#Author-George.
#Modified by Jonathon Shults 9/5/2022 10PM
#Description-draw tools.

import adsk.core, adsk.fusion, traceback, math, time, tempfile, adsk.cam, os, sys, json, random
#import tkinter as tk
#from tkinter import filedialog
import os
app = adsk.core.Application.get()
ui  = app.userInterface

def createHolder() -> str:  
    ui = app.userInterface

    if (not ui.activeWorkspace.id == "FusionSolidEnvironment"):
        modelWS = ui.workspaces.itemById("FusionSolidEnvironment")
        modelWS.activate()    
            
    doc = app.activeDocument
    
    products = doc.products
    design = adsk.fusion.Design.cast(products.itemByProductType("DesignProductType"))
    rootComp = design.rootComponent
    input = rootComp.name
    # Get a string from the user.
    ui.messageBox('INSTRUCTIONS: \n\n1. Choose a file name\n2. Select the Body you are converting\n\n MUST NOT BE CAPTURING DESIGN HISTORY for this to work\n\n Press OK to continue')
    (input, isCancelled) = ui.inputBox('File Name', 'File Name', input)
            
    # Exit the program if the dialog was cancelled.
    if isCancelled:
        adsk.terminate()
        return


    if not design:
        ui.messageBox('It is not supported in current workspace, please change to MODEL workspace and try again.')
        return
    
    sel = app.userInterface.selectEntity('Select the holder', 'SolidBodies')
    if sel:
        holder = adsk.fusion.BRepBody.cast(sel.entity)
        sections = []
        points = []
        for ed in holder.edges:
            points.append(round(ed.startVertex.geometry.z, 3))
        points.sort()
        ## only allow TWO duplicate points
        currentPoint = 0
        addPoint = True
        newPoints = []
        for point in points:
            if point == currentPoint:
                if addPoint:
                    newPoints.append(point + 0.001)
                    newPoints.append(point - 0.001)
                    currentPoint = point
                    addPoint = False
            else:
                addPoint = True
                newPoints.append(point)
                currentPoint = point
        newPoints.sort()
        normal = adsk.core.Vector3D.create(0,0,1)
        for p in newPoints:
            ## create the plane
            point = adsk.core.Point3D.create(0,0,p)
            plane = adsk.core.Plane.create(point, normal)
            planes = rootComp.constructionPlanes
            pInput = planes.createInput()
            
            pInput.setByPlane(plane)
            
            newPlane = planes.add(pInput)
            ## put a sketch on it
            sketches = rootComp.sketches
            sketch = sketches.add(newPlane)
            #sketch = sketches.add(rootComp.yZConstructionPlane)
            sketch.projectCutEdges(holder)
            box = sketch.boundingBox
            sizeX = abs(box.minPoint.x - box.maxPoint.x) * 10
            sizeY = abs(box.minPoint.y - box.maxPoint.y) * 10
            maxSize = 0
            sketch.deleteMe()
            newPlane.deleteMe()
            if sizeX > sizeY:
                maxSize = sizeX
            else:
                maxSize = sizeY
            sections.append((maxSize, p * 10))
          
        first = True
        lastPos = (0, 0)
        guid = "00000000-0000-0000-0000-" + str(random.randint(100000000000,999999999999))
        jsonOut = {
            "data": [
                {
                    "description": input,
                    "guid": guid,
                    "last_modified": 1570310972973,
                    "product-id": "",
                    "product-link": "",
                    "reference_guid": guid,
                    "segments": [],
                    "type": "holder",
                    "unit": "millimeters",
                    "vendor": ""
                }

        ],
        "version": 1
        }
        
        for s in sections:
            if not first:
                seg = {
                    "height": round(abs(s[1] - lastPos[1]),3),
                    "lower-diameter": round(lastPos[0],3),
                    "upper-diameter": round(s[0],3)
                }
                if abs(s[1] - lastPos[1]) > 0.1:
                    jsonOut["data"][0]["segments"].append(seg)
                lastPos = (s[0], s[1])
            else:
                first = False
                lastPos = (s[0], s[1])

    # Find the user home folder
    home_directory = os.path.expanduser( '~' )
    # 
    filename = os.path.join( home_directory,'Downloads', (input + ".json") )
    
    filename = uniq_file_maker(filename)
    if filename:
        with open(filename, 'w+') as f:
            json.dump(jsonOut, f)
    return filename


##------------------------- Unique File Name ------------------------------------

def uniq_file_maker(file: str) -> str:
    """Create a unique file path"""
    # get file name and extension
    filename, filext = os.path.splitext(os.path.basename(file))
    # get file directory path
    directory = os.path.dirname(file)
    # get file without extension only
    filexx = str(directory + os.sep + filename)
    # check if file exists
    if os.path.exists(file):
        # create incrementing variable
        i = 1
        # determine incremented filename
        while os.path.exists(f"{filexx} ({str(i)}){filext}"):
            # update the incrementing variable
            i += 1
        # update file name with incremented variable
        file = directory + os.sep + filename + ' (' + str(i) + ')' + filext
    return file



##-------------------------Priamary Run Funciton ------------------------

def run(context):
    try:
        filename = createHolder()
        if filename:
            if ui:
                ui.messageBox('Saved File To: ' + filename)
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

