#Photonic Crystal Generator Wizard
#Assumes that Fimmwave is serving on port 5101
from PCLayoutLib import *
import math
import cmath
from string import *

#********************************
# DEFAULT SETTINGS
#********************************
nb = 1.5
nh = 1.0
rad = 0.5
latsp = 2.0
NumColumns = 9
NumRows = 7
IsHex = 1       # 1 = Hexagonal Lattice, 0 = Square Lattice
Dir = "d:\\temp\\"
#********************************
#********************************

# The list below is the list of all settings in the menu
ParamsNameList = ["Bulk Index","Hole Index","Hole Radius","Lattice Period","Number of Columns","Number of Rows","Hexagonal Lattice","Directory"]
ParamsList = [nb,nh,rad,latsp,NumColumns,NumRows,IsHex,Dir]

filename = "PCLayoutSettings.txt"

def GetWorkingDirectory(pdAppClassName):
    f = pdAppClassName
    f.AddCmd("app.getwdir")
    wdir = f.Exec("app.wdir")
    l = len(wdir)
    wdir = wdir[0:l-2]
    return wdir
def ReadSettingsFromFile(ParamsList):
    # If there is a "PCLayoutSettings.txt" file in the Working Directory then load data
    IsFile = 1
    filepath = wdir + "\\" + filename
    try:   
        file = open(filepath,"r")
    except IOError:
        IsFile = 0
    if IsFile != 0:
        x = file.readlines()    # x will be a list of strings - one for each line.
        l = len(x)
        y = []
        for i in range (0,l):
            temp_str = x[i]
            num = find(temp_str,"   \\")
            str = temp_str[0:num]
            try:
                param = int(str)
            except ValueError:
                try:
                    param = float(str)
                except ValueError:
                    try:
                        param = str
                    except ValueError:        
                        break
            ParamsList[i] = param
        file.close
def WriteSettingsToFile(ParamsNameList,ParamsList):
    # This will be run at the end of the Fibre generation so that when the
    # user re-runs he is able to keep the previous settings.
    filepath = wdir + "\\" + filename    
    file = open(filepath,"w")
    l = len(ParamsNameList)
    NewList = []
    for i in range (0,l):
        if i != 7:
            temp1 = ParamsNameList[i]
            temp2 = ParamsList[i]
            temp3 = repr(temp2)
            str = temp3 + "   \\\\ " + temp1 + "\n"
            NewList.append(str)
        else:
            NewList.append(ParamsList[i])
            temp1 = ParamsNameList[i]
            NewList.append("   \\\\ " + temp1 + "\n")

    file.writelines(NewList)
    file.close
def GetValidNodeName(pdAppClassName):
    # Function for returning a valid name for a new Project Node.
    f = pdAppClassName
    Nodectr = 0
    Nodename = 'prj0'
    while (1):
        a = f.Exec("app.findnode({%})",[Nodename])
        if a==None:
            break
        Nodectr = Nodectr + 1
        Nodename = 'prj'+repr(Nodectr)
    return Nodename


def RoundNumber(Float):
    # Used by printsettings()
    # This is a quick script to round a number and return a string
    if type(Float) == float:
        test_str = repr(Float)
        l = len(test_str)
        if l > 6:
            RoundedNo = round(Float,4)      # we will round to 4 dec. places - this is just for the menu not the computation
            temp_string = repr(RoundedNo)
            string = temp_string[0:6]
            return string
        else:
            return test_str
    elif type(Float) == int:
        string = repr(Float)
        return string
    else:
        return Float
def printsettings():
    global ParamsNameList,ParamsList,nb,nh,rad,latsp,NumColumns,NumRows,IsHex,Dir
    print ""
    print "Current Settings:"
    print ""
    
    # Here we synchronise the prev. data with the default
    nb = ParamsList[0]
    nh = ParamsList[1]
    rad = ParamsList[2]
    latsp = ParamsList[3]
    NumColumns = ParamsList[4]
    NumRows = ParamsList[5]
    IsHex = ParamsList[6]
    Dir = ParamsList[7]
    
    # Here we use the RoundNumber function to format the menu
    nb_str = RoundNumber(nb)
    nh_str = RoundNumber(nh)
    rad_str = RoundNumber(rad)
    latsp_str = RoundNumber(latsp)
    NumColumns_str = RoundNumber(NumColumns)
    NumRows_str = RoundNumber(NumRows)
    IsHex_str = RoundNumber(IsHex)

    l = len(ParamsList)
    for i in range (0,l):    
        print repr(i+1) + ": " + ParamsNameList[i] +" =  "+ RoundNumber(ParamsList[i])
    
def editsettings():
    global ParamsNameList,ParamsList,nb,nh,rad,latsp,NumColumns,NumRows,IsHex,Dir
    if ChangeOpt == 1:
        print "Please enter value for Bulk Index"
        nbStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(nbStr,1) # 1 = float
        print ParamsList[0]
    elif ChangeOpt == 2:
        print "Please enter value for Hole Index"
        nhStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(nhStr,1) # 1 = float   
    elif ChangeOpt == 3:
        print "Please enter value for Hole radius (um)"
        radStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(radStr,1) # 1 = float
    elif ChangeOpt == 4:
        print "Please enter value for Lattice Period (um)"
        latspStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(latspStr,1) # 1 = float
    elif ChangeOpt == 5:
        print "Please enter the number of Columns in the propagation direction"
        NumColumnsStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(NumColumnsStr,2) # 2 = int       
    elif ChangeOpt == 6:
        print "Please enter the number of Rows"
        NumRowsStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(NumRowsStr,2) # 2 = int
    elif ChangeOpt == 7:
        print "Would you like a hexagonal Lattice (y/n)"
        IsHexStr = raw_input(">>> ")
        if IsHexStr == "N" or IsHexStr == "n":
            ParamsList[ChangeOpt-1] = 0
        else:
            ParamsList[ChangeOpt-1] = 1
    elif ChangeOpt == 8:
        print "Please enter the directory to save the file"
        print "Please include double \"back slashes\" E.g. D:\\\\work"
        ParamsList[ChangeOpt-1] = raw_input(">>> ")
    print ""
    
def errorhandling(string,type):
    # Used by editsettings
    # Type: 1 = float, 2 = int
    while type == 1:
        try:
            val = atof(string)
            break
        except ValueError:
            print "Please enter a number"
            string = raw_input(">>> ")
    while type == 2:
        try:
            val = atoi(string)
            break
        except ValueError:
            print "Please enter an integer"
            string = raw_input(">>> ") 
    return val

print ""
print "********************************"
print "* PBXstalLayoutWizard          *"
print "* ---------------              *"
print "* by Tom Davies                *"
print "* (Modified from PBXStalWizard)*"
print "* (c) Photon Design 2005       *"
print "********************************"
print ""
print ""

f = pdApp()
f.ConnectToApp()

# First, get the working directory of Fimmwave
wdir = GetWorkingDirectory(f)
ParamsList[7] = wdir

while 1:
    ReadSettingsFromFile(ParamsList)
    while 1:
        printsettings()
        print ""
        print "Select number to change setting"
        print "Otherwise press return"
        change_str = raw_input(">>> ")
        if change_str == "" or change_str == "":
            p = PCLayout()
            p.nbulk = nb
            p.nhole = nh
            p.holeRad = rad
            p.latSpace = latsp
            p.nColumns = NumColumns
            p.nRows = NumRows
            p.IsHex =  IsHex
            print ""
            print "Working. Please wait...."
            print ""
            prjname = GetValidNodeName(f)
            p.GenerateLayout(Dir,f,prjname)
            WriteSettingsToFile(ParamsNameList,ParamsList)
            break
        else:
            ChangeOpt = errorhandling(change_str,2) # 2 = int        
            editsettings()
    break
del f
