import os
import math
import sys
from string import Template

#########Script settings
connect_bidirectionally = True
use_pipmak_2_7 = True
handle_width = 30
handle_height = 60

#########Pipmak stuff

PIPMAK_EMPTY_NODE_STRING = """cubic {
	"1.png", --front
	"2.png", --right
	"3.png", --back
	"4.png", --left
	"5.png", --top
	"6.png" --bottom
}"""

SCRIPT_START_TOKEN = "\n--Begin automatically inserted handles\n"
SCRIPT_END_TOKEN = "\n--End automatically inserted handles\n"

PIPMAK_EMPTY_MAIN_STRING = """version (0.27)
title "test"
startnode (1)"""

#########Math neighborhood

def getRadius(x, y, z):
    return math.sqrt(x**2 + y**2 + z**2)

def radiansToDegrees(rad):
    return rad * 180 / math.pi

def getAzimuth(x, z):
    return radiansToDegrees(math.atan2(x, z))

def getElevation(x, y, z):
    radius = getRadius(x, y, z)
    return radiansToDegrees(math.acos(y / radius)) - 90

def getAzimuthFrom(originPoint, destinationPoint):
    return getAzimuth(destinationPoint[0]-originPoint[0],
                      destinationPoint[2]-originPoint[2])

def getElevationFrom(originPoint, destinationPoint):
    return getElevation(destinationPoint[0]-originPoint[0],
                      destinationPoint[1]-originPoint[1],
                      destinationPoint[2]-originPoint[2])

##########File parsing neighborhood

def floatify(list):
    newList = []
    for item in list:
        newList.append(float(item))
    return newList

def parsePointLocationFile(file):
    pointLocs = {}
    for line in file:
        lineStuff = line.rstrip('\n').split(':')
        pointLocs[lineStuff[0]]=floatify(lineStuff[1].split(',')) ## point locations are numbers
    return pointLocs

def parsePointConnectivityFile(file):
    connections = {}
    for line in file:
        lineStuff = line.rstrip('\n').split(':')
        key = lineStuff [0]
        connections[key]=lineStuff[1].split(',') ## node names are strings
        if (connect_bidirectionally):
            for val in connections[key]:
                if not connections.has_key(val):
                    connections[val] = []
                if not key in connections[val]:
                    connections[val].append(key) ## map bidirectionally
    return connections    

##########Bigger building blocks

def makeAHandleBetween(currNodePoint, targetNodePoint, targetNodeName):
    caz = getAzimuthFrom(currNodePoint, targetNodePoint)
    cel = getElevationFrom(currNodePoint, targetNodePoint)
    az = 0
    el = 0
    if (use_pipmak_2_7):
        az = caz - handle_width/2
        el = cel + handle_height/2
        if az < 0:
            az = az + 360
    if caz < 0 : caz = caz + 360
    if (use_pipmak_2_7):
        templateString = "\nhandle{\naz=${az}, el=${el},\ntarget=${target},\nw=${width}, h=${height},\ncursor=pipmak.hand_forward\n}\n"
        s = Template(templateString)
        return s.substitute(az=str(az), el=str(el), target=targetNodeName, width=handle_width, height=handle_height)
    else:
        templateString = "\nhandle{\ncaz=${caz}, cel=${cel},\ntarget=${target},\nw=${width}, h=${height},\ncursor=pipmak.hand_forward\n}\n"
        s = Template(templateString)
        return s.substitute(caz=str(caz), cel=str(cel), target=targetNodeName, width=handle_width, height=handle_height)

def makeAllHandlesFor(currNode, neighborList, nodeLocations):
    allHandles=""
    for neighbor in neighborList:
        allHandles = allHandles + makeAHandleBetween(nodeLocations[currNode], nodeLocations[neighbor], neighbor)
    return allHandles

##########I think it is time for the main loop

def main() :
    ## maybe the file locations should happen differently
    rootOfProject = os.getcwd() + os.sep
    fileNameForLocs = rootOfProject + "camExport"
    fileNameForCons = rootOfProject + "connectivity"
    nodeLocations = {}
    nodeConnections = {}
    if ((not os.path.exists(fileNameForLocs)) or (not os.path.exists(fileNameForCons))):
        print ("oh no!")
        return -1
    locFile = open(fileNameForLocs,"r")
    nodeLocations = parsePointLocationFile(locFile)
    locFile.close()
    conFile = open(fileNameForCons,"r")
    nodeConnections=parsePointConnectivityFile(conFile)
    conFile.close()

    ##OK, now we have all the data!

    if (not os.path.exists(rootOfProject + "main.lua")):
        mainFile = open(rootOfProject + "main.lua","w")
        mainFile.write(PIPMAK_EMPTY_MAIN_STRING)
        mainFile.close

    for node,neighbors in nodeConnections.iteritems():
        someHandles = makeAllHandlesFor(node, neighbors, nodeLocations)
        nodeFileName = rootOfProject + node + os.sep + "node.lua"
        if (not os.path.exists(nodeFileName)):
            nodeFile = open(nodeFileName, "w")
            nodeFile.write(PIPMAK_EMPTY_NODE_STRING)
            nodeFile.write(SCRIPT_START_TOKEN)
            nodeFile.write(someHandles)
            nodeFile.write(SCRIPT_END_TOKEN)
            nodeFile.close

    print "done"
    

if __name__ == "__main__":
    main()
