from PCFibreLib import *
from string import *
import math
import cmath


#********************************
# DEFAULT SETTINGS - used if settings file does can not be found
#********************************

nb = 1.5
nh = 1.0
rad = 2.0
latsp = 4.5
ring = 3
cladRad = 20
Dist2Edge = 1.0
NumHexPoints = 0
IsRounding = 0
polyroundingResolution = 3
polyRoundingDiameter = 2.0
IshollowCore = 0
hollowCoreWidth = 16
hollowCoreWallThickness = 0.3
hollowCoreRoundingDiameter = 8.26
jctSize = 0.0
symmetry = 4
FillIn = 0
Wavelength = 1.55
name2 = ""

# The list below is the list of all settings in the menu
ParamsNameList = ["Bulk Index","Hole Index","Hole Radius","Lattice Period","Number of Rings","Cladding Radius","Distance to boundary","Hole polygon resolution","Corner Rounding","Rounding Resolution","Rounding Diameter","Hollow Core","Hollow Core Width","Hollow Core Wall Thickness","Hollow Core Rounding Diameter","Absorbing Jacket Size","Symmetry Plane","Fill In","Wavelength","Directory"]
ParamsList = [nb,nh,rad,latsp,ring,cladRad,Dist2Edge,NumHexPoints,IsRounding,polyroundingResolution,polyRoundingDiameter,IshollowCore,hollowCoreWidth,hollowCoreWallThickness,hollowCoreRoundingDiameter,jctSize,symmetry,FillIn,Wavelength,name2]

filename = "PCFibreSettings.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 "PCFibreSettings.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 != 19:
            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 GetValidWGName(pdAppClassName):
    # Function for returning a valid name for a new waveguide.
    f = pdAppClassName
    wgctr = 0
    wgname = 'wg0'
    while (1):
        a = f.Exec("app.findnode({%})",[wgname])
        if a==None:
            break
        wgctr = wgctr + 1
        wgname = 'wg'+repr(wgctr)
    return wgname


def getwguidelist(wglist):
    # This is used to obtain the list of valid wgs
    # Currently not used 'cos there is no "edit current wg" option
    # Currently the waveguide must be at the root of the project tree,
    # or subnode of a project file that lies at the root.
    wglist = wglist
    # for some reason f.Exec("app.subnodes[{i}].nodename") does not work
    # Command sent to Fimmwave is "app.subnodes[_exit].nodename"
    string1 = "app.subnodes["
    string3 = ".nodename"
    string4 = ".objtype"
    Tree = []
    for i in range (1,6):
        string2 = repr(i)
        TreePosn = string1 + string2 + "]"
        wgname = f.Exec(TreePosn + string3)
        if wgname != None:
            c = rfind(wgname,"\n") #FIMMWAVE appends a \012 to the sequence
            objtype = f.Exec(TreePosn + string4)
            if objtype[0:3] == "FMM":    # Project
                n = f.Exec(TreePosn+".numsubnodes")
                for j in range (1,n+1):
                    objtypea = f.Exec("app.subnodes[{%}].subnodes[{%}].objtype", [i,j])
                    if c!=-1 and objtypea[0:3]=="MWG":
                        TreePosn = "app.subnodes["+repr(i)+"].subnodes["+repr(j)+"]"
                        wgname2 = f.Exec(TreePosn+".nodename")
                        c2 = rfind(wgname2,"\n")
                        wgname = wgname[0:c]+"\\"+wgname2[0:c2]
                        wglist.append(wgname)
                        Tree.append(TreePosn)
            elif objtype[0:3] == "MWG":    # MWG Waveguide
                if c!=-1:
                    wgname = wgname[0:c]
                    wglist.append(wgname)
                    Tree.append(TreePosn)
    listlength = len(wglist)
    return wglist,listlength,Tree

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,ring,cladRad,Dist2Edge,NumHexPoints,IsRounding,polyroundingResolution,polyRoundingDiameter,IshollowCore,hollowCoreWidth,hollowCoreWallThickness,hollowCoreRoundingDiameter,jctSize,symmetry,FillIn,Wavelength,name2
    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]
    ring = ParamsList[4]
    cladRad = ParamsList[5]
    Dist2Edge = ParamsList[6]
    NumHexPoints = ParamsList[7]
    IsRounding = ParamsList[8]
    polyroundingResolution = ParamsList[9]
    polyRoundingDiameter = ParamsList[10]
    IshollowCore = ParamsList[11]
    hollowCoreWidth = ParamsList[12]
    hollowCoreWallThickness = ParamsList[13]
    hollowCoreRoundingDiameter = ParamsList[14]
    jctSize = ParamsList[15]
    symmetry = ParamsList[16]
    FillIn = ParamsList[17]
    Wavelength = ParamsList[18]
    name2 = ParamsList[19]
    
    # 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)
    cladRad_str = RoundNumber(cladRad)
    Dist2Edge_str = RoundNumber(Dist2Edge)
    hollowCoreWidth_str = RoundNumber(hollowCoreWidth)
    hollowCoreWallThickness_str = RoundNumber(hollowCoreWallThickness)
    hollowCoreRoundingDiameter_str = RoundNumber(hollowCoreRoundingDiameter)
    polyroundingResolution_str = RoundNumber(polyroundingResolution)
    polyRoundingDiameter_str = RoundNumber(polyRoundingDiameter)
    Wavelength_str = RoundNumber(Wavelength)
    jctSize_str = RoundNumber(jctSize)

    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,ring,cladRad,Dist2Edge,IshollowCore,hollowCoreWidth,hollowCoreWallThickness,hollowCoreRoundingDiameter,IsRounding,NumHexPoints,polyroundingResolution,polyRoundingDiameter,jctSize,symmetry,Wavelength,FillIn,name2
    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 rings"
        ringStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(ringStr,2) # 2 = int       
    elif ChangeOpt == 6:
        print "Please enter the Cladding Radius (um)"
        cladRadStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(cladRadStr,1) # 1 = float
    elif ChangeOpt == 7:
        print "Please enter distance from the outermost atom to the boundary (um)"
        Dist2EdgeStr = raw_input(">>> ")    
        ParamsList[ChangeOpt-1] = errorhandling(Dist2EdgeStr,1) # 1 = float
    elif ChangeOpt == 8:
        print "Please enter the number of vertices to describe the holes"
        NumHexPointsStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(NumHexPointsStr,2) # 2 = int
    elif ChangeOpt == 9:
        print "Would you like corner rounding (y/n)"
        IshollowCoreStr = raw_input(">>> ")
        if IshollowCoreStr == "N" or IshollowCoreStr == "n":
            ParamsList[ChangeOpt-1] = 0
        else:
            ParamsList[ChangeOpt-1] = 1
    elif ChangeOpt == 10:
        print "Please enter rounding resolution"
        polyroundingResolutionStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(polyroundingResolutionStr,2) # 2 = int
    elif ChangeOpt == 11:
        print "Please enter rounding diameter"
        polyRoundingDiameterStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(polyRoundingDiameterStr,1) # 1 = float        
    elif ChangeOpt == 12:
        print "Would you like a Hollow Core (y/n)"
        IshollowCoreStr = raw_input(">>> ")
        if IshollowCoreStr == "Y" or IshollowCoreStr == "y":
            ParamsList[ChangeOpt-1] = 1
        else:
            ParamsList[ChangeOpt-1] = 0
    elif ChangeOpt == 13:
        print "Please enter the width of the Hollow Core"
        hollowCoreWidthStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(hollowCoreWidthStr,1) # 1 = float
    elif ChangeOpt == 14:
        print "Please enter the wall thickness of the Hollow Core"
        hollowCoreWallThicknessStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(hollowCoreWallThicknessStr,1) # 1 = float
    elif ChangeOpt == 15:
        print "Please enter the rounding diameter of the Hollow Core"
        hollowCoreRoundingDiameterStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(hollowCoreRoundingDiameterStr,1) # 1 = float
    elif ChangeOpt == 16:
        print "Please enter the size of the Absorbing jacket"
        jctSizeStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(jctSizeStr,1) # 1 = float
    elif ChangeOpt == 17:
        print "Symmetry Plane? (1 = vertical, 2 = horizontal, 3 = both, 4 = NONE)"
        symmetryOptionStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(symmetryOptionStr,2) # 2 = int
    elif ChangeOpt == 18:
        print "Would you like holes filled in (y/n)"
        FillInStr = raw_input(">>> ")
        if FillInStr == "Y" or FillInStr == "y":
            ParamsList[ChangeOpt-1] = 1
        else:
            ParamsList[ChangeOpt-1] = 0
    elif ChangeOpt == 19:
        print "Please enter the working wavelength"
        WavelengthStr = raw_input(">>> ")
        ParamsList[ChangeOpt-1] = errorhandling(WavelengthStr,1) # 1 = float
    elif ChangeOpt == 20:
        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 "********************************"
print "* PCFibreWizard                *"
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[19] = 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 == "":
            if IshollowCore == 1 and hollowCoreWidth == 0:
                print "Please enter a diameter for the hollow core (um)"
                hollowCoreWidth_str = raw_input(">>> ")
                hollowCoreWidth = errorhandling(hollowCoreWidth_str,1) # 1 = float
            while cladRad != 0 and cladRad < (ring*latsp + rad):
                print "Please enter a larger value for the Cladding Radius (um)"
                cladRadStr = raw_input(">>> ")
                cladRad = errorhandling(cladRadStr,1) # 1 = float    
            p = PCFibre()
            p.nbulk = nb
            p.nhole = nh
            p.holeRad = rad
            p.latSpace = latsp
            p.nRings = ring
            p.Dist2Edge = Dist2Edge
            p.cladRad = cladRad
            p.NumHexPoints = NumHexPoints
            p.IshollowCore = IshollowCore
            p.hollowCoreWallThickness = hollowCoreWallThickness
            p.hollowCoreWidth = hollowCoreWidth
            p.hollowCoreRoundingDiameter = hollowCoreRoundingDiameter
            p.IsRounding = IsRounding
            p.polyRoundingDiameter = polyRoundingDiameter
            p.polyroundingResolution = polyroundingResolution
            p.symmetry = symmetry
            p.jctSize = jctSize
            p.Wavelength = Wavelength
            p.FillIn = FillIn
            print ""
            print "Working. Please wait...."
            print ""
            wgname = GetValidWGName(f)
            name1 = wgname
            p.GenerateFibre(name1,name2,f,wgname)
            WriteSettingsToFile(ParamsNameList,ParamsList)
            break
        else:
            ChangeOpt = errorhandling(change_str,2) # 2 = int
            editsettings()
    break
del f







