from Simulation import *
from Tkinter import *
from visual import *

#from kSpace import *

class Interface:

    def __init__(self, nSpinsX, nSpinsY, stripeSpacingX, stripeSpacingY, Ja, Jbx, Jby, k, baseSigma, scalePhi, zArray, sigmaArray, phiArray, phaseArray, trackSpins, dt):
        self.tkr = Tk()

        self.simu = Simulation(self.tkr, nSpinsX, nSpinsY, stripeSpacingX, stripeSpacingY, Ja, Jbx, Jby, k, baseSigma, scalePhi, zArray, sigmaArray, phiArray, phaseArray, trackSpins, dt)

#        kSp = kSpace(self.tkr)

        self.nTotSpins = nSpinsX*nSpinsY

        self.k = k
        
        self.innerLoops = int(40*self.nTotSpins**-.5)+4
        self.outerLoops = int(10*self.nTotSpins**-.5)+1
        self.dtUpperLimit = int(200*self.nTotSpins**.33/(self.innerLoops*self.outerLoops))+200

        self.nUpperLimit = int(stripeSpacingX*stripeSpacingY*2-1)
        





        ##  TKR appearance and widget creation ##
        self.tkr.wm_geometry(newGeometry="460x680+700+15")   
        self.tkr.wm_title("Controls")

        self.tkr.topFrame = Frame(self.tkr,relief=SUNKEN, borderwidth=0)
        self.tkr.topFrame.grid(row=0, column=0, padx=0, pady=0)




        self.tkr.toggleFrame = Frame(self.tkr.topFrame, relief=FLAT, borderwidth=0)
        self.tkr.toggleFrame.grid(row=0, column=0, padx=4, pady=4)


        ####
        self.tkr.visualSphereFrame = Frame(self.tkr.toggleFrame, relief=FLAT, borderwidth=1)
        self.tkr.visualSphereFrame.grid(row=0, column=0, padx=4, pady=6)

        #
        self.tkr.sphereOptionsLabel = Label(self.tkr.visualSphereFrame, text="Sphere:").grid(row=0, column=0, sticky=N)

        self.tkr.sphereTracersLabel = Label(self.tkr.visualSphereFrame, text="Tracers").grid(row=1, column=0, sticky=E)
        self.tkr.sphereTracersWidget = Checkbutton(self.tkr.visualSphereFrame, text="", variable=self.simu.tvSphereTracers, command=self.toggleSphereTracers)
        self.tkr.sphereTracersWidget.grid(row=1, column=1)

        self.tkr.sphereVectorsLabel = Label(self.tkr.visualSphereFrame, text="Vectors").grid(row=2, column=0, sticky=E)
        self.tkr.sphereVectorsWidget = Checkbutton(self.tkr.visualSphereFrame, text="", variable=self.simu.tvSphereVectors, command=self.toggleSphereVectors)
        self.tkr.sphereVectorsWidget.grid(row=2, column=1)

        self.tkr.spherePointsLabel = Label(self.tkr.visualSphereFrame, text="Points").grid(row=3, column=0, sticky=E)
        self.tkr.spherePointsWidget = Checkbutton(self.tkr.visualSphereFrame, text="", variable=self.simu.tvSpherePoints, command=self.toggleSpherePoints)
        self.tkr.spherePointsWidget.grid(row=3, column=1)

        self.tkr.displayAxisLabel = Label(self.tkr.visualSphereFrame, text="Display Axis").grid(row=4, column=0, sticky=E)
        self.tkr.displayAxisWidget = Checkbutton(self.tkr.visualSphereFrame, text="", variable=self.simu.tvSphereAxis, command=self.toggleSphereAxis)
        self.tkr.displayAxisWidget.grid(row=4, column=1)

        self.tkr.followAxisLabel = Label(self.tkr.visualSphereFrame, text="Follow Axis").grid(row=5, column=0, sticky=E)
        self.tkr.followAxisWidget = Checkbutton(self.tkr.visualSphereFrame, text="", variable=self.simu.tvSphereAxisSync, command=self.toggleSphereAxisSync)
        self.tkr.followAxisWidget.grid(row=5, column=1)
        #



        ####
        self.tkr.visualLatticeFrame = Frame(self.tkr.toggleFrame, relief=FLAT, borderwidth=1)
        self.tkr.visualLatticeFrame.grid(row=0, column=1, padx=4, pady=6)

        #
        self.tkr.latticeOptionsLabel = Label(self.tkr.visualLatticeFrame, text="Lattice:").grid(row=0, column=0, sticky=N)

        self.tkr.latticeTracersLabel = Label(self.tkr.visualLatticeFrame, text="Tracers").grid(row=1, column=0, sticky=E)
        self.tkr.latticeTracersWidget = Checkbutton(self.tkr.visualLatticeFrame, text="", variable=self.simu.tvLatticeTracers, command=self.toggleLatticeTracers)
        self.tkr.latticeTracersWidget.grid(row=1, column=1)

        self.tkr.latticeVectorsLabel = Label(self.tkr.visualLatticeFrame, text="Vectors").grid(row=2, column=0, sticky=E)
        self.tkr.latticeVectorsWidget = Checkbutton(self.tkr.visualLatticeFrame, text="", variable=self.simu.tvLatticeVectors, command=self.toggleLatticeVectors)
        self.tkr.latticeVectorsWidget.grid(row=2, column=1)

        self.tkr.latticeBondsLabel = Label(self.tkr.visualLatticeFrame, text="Bonds").grid(row=3, column=0, sticky=E)
        self.tkr.latticeBondsWidget = Checkbutton(self.tkr.visualLatticeFrame, text="", variable=self.simu.tvLatticeBonds, command=self.toggleLatticeBonds)
        self.tkr.latticeBondsWidget.grid(row=3, column=1)

        self.tkr.spacerLabel = Label(self.tkr.visualLatticeFrame, text="").grid(row=4, column=0, sticky=E)

        self.tkr.hamLabel = Label(self.tkr.visualLatticeFrame, text="Hamiltonian").grid(row=5, column=0, sticky=E)
        self.tkr.hamWidget = Checkbutton(self.tkr.visualLatticeFrame, text="", variable=self.simu.tvUseHamiltonian, command=self.toggleUseHamiltonian)
        self.tkr.hamWidget.grid(row=5, column=1) 
        #



        ####
        self.tkr.dataAnalysisFrame = Frame(self.tkr.toggleFrame, relief=FLAT, borderwidth=1)
        self.tkr.dataAnalysisFrame.grid(row=0, column=2, padx=4, pady=6)

        #
        self.tkr.dataLabel = Label(self.tkr.dataAnalysisFrame, text="Data Analysis:").grid(row=0, column=0, sticky=N)
        
        self.tkr.fftLabel = Label(self.tkr.dataAnalysisFrame, text="Mode FFT").grid(row=1, column=0, sticky=E)
        self.tkr.fftWidget = Checkbutton(self.tkr.dataAnalysisFrame, text="", variable=self.simu.tvPlotFFT, command=self.toggleFFTPlot)
        self.tkr.fftWidget.grid(row=1, column=1)

        self.tkr.anglePlotLabel = Label(self.tkr.dataAnalysisFrame, text="Angle Plot").grid(row=2, column=0, sticky=E)
        self.tkr.anglePlotWidget = Checkbutton(self.tkr.dataAnalysisFrame, text="", variable=self.simu.tvPlotAngles, command=self.toggleAnglePlot)
        self.tkr.anglePlotWidget.grid(row=2, column=1)

        self.tkr.phasePointsLabel = Label(self.tkr.dataAnalysisFrame, text="Phase Points").grid(row=3, column=0, sticky=E)
        self.tkr.phasePointsWidget = Checkbutton(self.tkr.dataAnalysisFrame, text="", variable=self.simu.tvPhasePoints, command=self.togglePhasePoints)
        self.tkr.phasePointsWidget.grid(row=3, column=1)

        self.tkr.returnMapLabel = Label(self.tkr.dataAnalysisFrame, text="Return Map").grid(row=4, column=0, sticky=E)
        self.tkr.returnMapWidget = Checkbutton(self.tkr.dataAnalysisFrame, text="", variable=self.simu.tvReturnMap, command=self.toggleReturnMap)
        self.tkr.returnMapWidget.grid(row=4, column=1)

        self.tkr.tvTrackMaxMinLabel = Label(self.tkr.dataAnalysisFrame, text="Track Planarity").grid(row=5, column=0, sticky=E) 
        self.tkr.tvTrackMaxMinWidget = Checkbutton(self.tkr.dataAnalysisFrame, text="", variable=self.simu.tvTrackMaxMin, command=self.toggleTrackMaxMin)
        self.tkr.tvTrackMaxMinWidget.grid(row=5, column=1)
        #



        

        ####
        self.tkr.simuFrame = Frame(self.tkr.topFrame, relief=FLAT, borderwidth=0)
        self.tkr.simuFrame.grid(row=1, column=0, columnspan=2, padx=4, pady=4)
        #
        self.tkr.simuLabel = Label(self.tkr.simuFrame, text="Simulation:").grid(row=0, column=1, sticky=W)

        self.tkr.powerSpectraWidget = Button(self.tkr.simuFrame, text="Power Spectra", command=self.simu.powerSpectra).grid(row=1, column=1, padx=4, pady=4)
        self.tkr.deltaEWidget = Button(self.tkr.simuFrame, text="Delta Energy", command=self.simu.deltaE).grid(row=1, column=2, padx=4, pady=4)
        self.tkr.randomizeWidget = Button(self.tkr.simuFrame, text="Randomize", command=self.simu.randomize).grid(row=1, column=3, padx=4, pady=4)
        self.tkr.distortWidget = Button(self.tkr.simuFrame, text="Distort", command=self.simu.distort).grid(row=1, column=4, padx=4, pady=4)
        self.tkr.clearWidget = Button(self.tkr.simuFrame, text="Clear Graphs", command=self.simu.clear).grid(row=1, column=5, padx=4, pady=4) 
        self.tkr.resetWidget = Button(self.tkr.simuFrame, text="Reset", command=self.simu.reset).grid(row=1, column=6, padx=4, pady=4)


        ####
        self.tkr.scalesFrame = Frame(self.tkr.topFrame, relief=FLAT, borderwidth=1)
        self.tkr.scalesFrame.grid(row=2, column=0, columnspan=2, padx=10, pady=10)
        #
        self.tkr.scalesLabel = Label(self.tkr.scalesFrame, text="Scales:").grid(row=0, column=0, sticky=W)

##        self.tkr.kxWidget = Scale(self.tkr.scalesFrame, orient=VERTICAL, from_=2.00*3.14159265359, to=0.0, resolution=0.001, label="kx", command=lambda str: self.setKx(str))
##        self.tkr.kxWidget.set(k.x)
##        self.tkr.kxWidget.grid(row=1, column=0)
##
##        self.tkr.kyWidget = Scale(self.tkr.scalesFrame, orient=VERTICAL, from_=2.00*3.14159265359, to=0.0, resolution=0.001, label="ky", command=lambda str: self.setKy(str))
##        self.tkr.kyWidget.set(k.y)
##        self.tkr.kyWidget.grid(row=1, column=1)

	self.tkr.baseSigmaWidget = Scale(self.tkr.scalesFrame, orient=VERTICAL, length=200, from_=1.000, to=0.0, resolution=0.001, label="sig", command=lambda str: self.setBaseSigma(str))
        self.tkr.baseSigmaWidget.set(baseSigma)
        self.tkr.baseSigmaWidget.grid(row=1, column=2)
        
	self.tkr.scalePhiWidget = Scale(self.tkr.scalesFrame, orient=VERTICAL, length=200, from_=4.000, to=0.000, resolution=0.01, label="phi", command=lambda str: self.setScalePhi(str))
        self.tkr.scalePhiWidget.set(scalePhi)
        self.tkr.scalePhiWidget.grid(row=1, column=3)
        
	self.tkr.setPhiHWidget = Scale(self.tkr.scalesFrame, orient=VERTICAL, length=200, from_=100.00, to=-10.00, resolution=0.1, label="phiH", command=lambda str: self.setPhiH(str))
        self.tkr.setPhiHWidget.set(phiArray[0][0])
        self.tkr.setPhiHWidget.grid(row=1, column=4)

	self.tkr.setPhiTWidget = Scale(self.tkr.scalesFrame, orient=VERTICAL, length=200, from_=100.00, to=-10.00, resolution=0.1, label="phiT", command=lambda str: self.setPhiT(str))
        self.tkr.setPhiTWidget.set(phiArray[2][0])
        self.tkr.setPhiTWidget.grid(row=1, column=5)

##        self.tkr.JbyRatioWidget = Scale(self.tkr.scalesFrame, orient=VERTICAL, from_=10.0, to=-1.0, resolution=0.001, label="Jby", command=lambda str: self.setJby(str))
##        self.tkr.JbyRatioWidget.set(self.simu.Jby)
##        self.tkr.JbyRatioWidget.grid(row=1, column=3)

        ####
        self.tkr.scales2Frame = Frame(self.tkr.topFrame, relief=FLAT, borderwidth=1)
        self.tkr.scales2Frame.grid(row=3, column=0, columnspan=2, padx=10, pady=10)
        #
##        self.tkr.meanFieldDownWidget = Scale(self.tkr.scales2Frame, orient=VERTICAL, from_=4.00, to=-4.00, resolution=0.001, label="EBd", command=lambda str: self.setEBd(str))
##        self.tkr.meanFieldDownWidget.set(self.simu.EBd)
##        self.tkr.meanFieldDownWidget.grid(row=0, column=0)

        self.tkr.JbxRatioWidget = Scale(self.tkr.scales2Frame, orient=VERTICAL, length=200, from_=4.0, to=-4.0, resolution=0.001, label="Jbx", command=lambda str: self.setJbx(str))
        self.tkr.JbxRatioWidget.set(Jbx)
        self.tkr.JbxRatioWidget.grid(row=0, column=0)
        
        self.tkr.EBWidget = Scale(self.tkr.scales2Frame, orient=VERTICAL, length=200, from_=4.00, to=-4.00, resolution=0.001, label="EBu", command=lambda str: self.setEBu(str))
        self.tkr.EBWidget.set(self.simu.EBu)     
        self.tkr.EBWidget.grid(row=0, column=1)

        self.tkr.tempWidget = Scale(self.tkr.scales2Frame, orient=VERTICAL, length=200, from_=1.0, to=0, resolution=0.001, label="kT", command=lambda str: self.setTemp(str))
        self.tkr.tempWidget.set(self.simu.temp/self.simu.Ja)
        self.tkr.tempWidget.grid(row=0, column=2)

        self.tkr.DtWidget = Scale(self.tkr.scales2Frame, orient=VERTICAL, length=200, from_=self.dtUpperLimit, to=0, label="dt", command=lambda str: self.setDt(str))
        self.tkr.DtWidget.set(self.simu.dt*1000.0)
        self.tkr.DtWidget.grid(row=0, column=3)

        self.tkr.nWidget = Scale(self.tkr.scales2Frame, orient=VERTICAL, length=200, from_=self.nUpperLimit, to=-1, resolution=1, label="State", command=lambda str: self.setState(str))
        self.tkr.nWidget.set(self.simu.n)
        self.tkr.nWidget.grid(row=0, column=4)
        #
 
        thread.start_new_thread(self.tkr.mainloop(),())


    def setEBu(self, EBu):
        self.simu.EBu = float(EBu)

    def setEBd(self, EBd):
        self.simu.EBd = float(EBd)
 
    def setTemp(self, temp):
        self.simu.temp = float(temp)*abs(self.simu.Ja)

    def setDt(self, dt):
        self.simu.dt = float(dt)/1000.0

    def setState(self, n):
        self.simu.n = int(n)
           
    def setKx(self, kx):
        self.k.x = float(kx)
        self.simu.k = self.k
  
    def setKy(self, ky):
        self.k.y = float(ky)
        self.simu.k = self.k

    def setJbx(self, Jbx):
        self.simu.Jbx = float(Jbx)
        self.simu.nLattice.setCouplings(self.simu.Ja, self.simu.Jbx, self.simu.Jby)

##        print self.simu.nLattice.couplingXArray
##        print self.simu.nLattice.couplingYArray


    def setJby(self, Jby):
        self.simu.Jby = float(Jby)
        self.simu.nLattice.setCouplings(self.simu.Ja, self.simu.Jbx, self.simu.Jby)

    def setBaseSigma(self, baseSigma):
        self.simu.baseSigma = float(baseSigma)

    def setScalePhi(self, scalePhi):
        self.simu.scalePhi = float(scalePhi)

    def setPhiH(self,PhiH):
        phiH = float(PhiH)
        phiT = -self.simu.phiArray[1][0]
        
        if abs(sin(phiT*(pi/180.0))/(2.0*cos(phiH*(pi/180.0)))) >= 1.00:
            phiA = 90.0
        else:
            phiA = (180.0/pi)*arcsin(sin(phiT*(pi/180.0))/(2.0*cos(phiH*(pi/180.0))))
                     
        self.simu.phiArray[0][0] = phiA - phiH 
        self.simu.phiArray[2][0] = phiA + phiH
        
        if self.simu.dt <= 0.050:   self.simu.reset()
        
    def setPhiT(self,PhiT):
        phiT = float(PhiT)
        phiH = (self.simu.phiArray[2][0] - self.simu.phiArray[0][0])/2.0
        
        if abs(sin(phiT*(pi/180.0))/(2.0*cos(phiH*(pi/180.0)))) >= 1.00:
            phiA = 90.0
        else:
            phiA = (180.0/pi)*arcsin(sin(phiT*(pi/180.0))/(2.0*cos(phiH*(pi/180.0))))

        self.simu.phiArray[1][0] = -phiT
        self.simu.phiArray[0][0] = phiA - phiH 
        self.simu.phiArray[2][0] = phiA + phiH
        
        if self.simu.dt <= 0.050:   self.simu.reset()


    

    def toggleSphereTracers(self):
        self.simu.vSphere.toggleTracers()
    def toggleSpherePoints(self):
        self.simu.vSphere.togglePoints()
    def toggleSphereVectors(self):
        self.simu.vSphere.toggleVectors()
    def toggleSphereAxis(self):
        self.simu.vSphere.toggleAxis()
    def toggleSphereAxisSync(self):
        pass
        
    def toggleLatticeTracers(self):
        self.simu.vLattice.toggleTracers()
    def toggleLatticeVectors(self):
        self.simu.vLattice.toggleVectors()
    def toggleLatticeBonds(self):
        self.simu.vLattice.toggleBonds()
        
    def toggleUseHamiltonian(self):
        pass


    def togglePhasePoints(self):
        pass
    def toggleAnglePlot(self):
        self.simu.t = 0.000
    def toggleFFTPlot(self):
        self.simu.FFTPlot.toggleWindow()
    def togglePowerSpectra(self):
        pass
    def toggleReturnMap(self):
        pass
    def toggleTrackMaxMin(self):
        pass


##    def setTracerLength(self, tracerLength):
##        self.hold()
##        self.tracerLength = float(tracerLength)
##        self.unhold()





