from Tkinter import *
from visual import *
from random import *

import time,sys,thread

from NumericUnitCell import *
from VisualSphere import *


     
class Simulation:
    nSpinsX = 1
    nSpinsY = 2

    tracerLength = 31

    uc = NumericUnitCell(nSpinsX,nSpinsY)
    vSphere = VisualSphere(nSpinsX,nSpinsY, tracerLength)

    dt = .001
    animDuty = 31                       # Number of cycles per animation frame

    Ja = -1.0
    Jbx = 0.0001
    Jby = -1.0
        
    temp = 0.01*abs(Ja)

    paused = 1
    pause = 1

    r = .2128
    k = 3.1416*vector(1.0 + r,1.0 - r,0.0)
    baseSigma = .5

        
    def __init__(self,parent):
        self.uc.setCouplings(self.Ja, self.Jbx, self.Jby)
        self.uc.setState(self.k, self.baseSigma)
        
        thread.start_new_thread(self.animSpins,(self.animDuty,))
        self.pause = 0


    def animSpins(self,animDuty):
        print '-----------------------------'
        print "Animation Started"
        
##        self.uc.permuteState(self.dt)
##        scene.forward = self.uc.getCommonAxis()

##        visAxis = []
##        for x in arange(-2.0,2.01,1.0):
##            visAxis.append(x*norm(self.uc.getCommonAxis()))
##        axisLine = curve(pos=visAxis, color=(.8,.8,.8))
        
        self.vSphere.addPoints(self.uc.getState())
        self.vSphere.addVectors(self.uc.getState())
        self.vSphere.addTracers(self.uc.getState())

        while 1:
            for k in range(animDuty):
                self.paused = self.pause
                if self.paused != 1:
                    
                    self.uc.permuteState(self.dt)
                    self.uc.perturbState(self.dt,self.temp,self.Ja)

            self.vSphere.updatePoints(self.uc.getState())
            self.vSphere.updateTracers(self.uc.getState())
            self.vSphere.updateVectors(self.uc.getState())
              

    def setKx(self,kx):
        self.pause = 1
        while self.paused == 0:
            pass

        if (self.k.y == 0.0 and float(kx) == 0.0):
            pass
        else:
            self.k.x = float(kx)/(self.nSpinsX)
            self.uc.setState(self.k, self.baseSigma)
            self.vSphere.setAxis(self.uc.getCommonAxis())
        self.pause = 0

      
    def setKy(self,ky):
        self.pause = 1
        while self.paused == 0:
            pass
        
        if (self.k.y == 0.0 and float(ky) == 0.0):
            pass
        else:
            self.k.y = float(ky)/(self.nSpinsY)
            self.uc.setState(self.k, self.baseSigma)
            self.vSphere.setAxis(self.uc.getCommonAxis())
        self.pause = 0


    def setGamma(self, gamma):
##        if float(gamma) != 0.0:
##            self. = float(gammaratio_string)
##            
##            self.spins = self.initialize_spins(self.spins, self.k)
            
        pass
    

    def setJbx(self, Jbx):
        self.pause = 1
        while self.paused == 0:
            pass

        self.Jbx = float(Jbx)
        self.uc.setCouplings(self.Ja, self.Jbx, self.Jby)
        self.vSphere.setAxis(self.uc.getCommonAxis())

        self.pause = 0


    def setJby(self, Jby):
        self.pause = 1
        while self.paused == 0:
            pass

        self.Jby = float(Jby)
        self.uc.setCouplings(self.Ja, self.Jbx, self.Jby)
        self.vSphere.setAxis(self.uc.getCommonAxis())

        self.pause = 0



    def setTemp(self, temp):
        self.pause = 1
        while self.paused == 0:
            pass

        self.temp = float(temp)*self.Ja
        self.pause = 0


    def setDt(self, dt):
        self.pause = 1
        while self.paused == 0:
            pass

        self.dt = float(dt)/10000.0
        self.pause = 0


    def randomize(self):
        self.pause = 1
        while self.paused == 0:
            pass

        self.uc.randomizeState()
        self.uc.permuteState(self.dt)
        self.vSphere.setAxis(self.uc.getCommonAxis())
        self.pause = 0


        

######-------------------------------------------------------######
###                             TKR                             ###
        
##  Instance creation ##
tkr = Tk()
simu = Simulation(tkr)

##  TKR appearance and widget creation ##

########
tkr.wm_geometry(newGeometry="360x513+900+320")   
tkr.wm_title("Controls")

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


######
toggle_frame = Frame(top_frame, relief=FLAT, borderwidth=0)
toggle_frame.grid(row=0, column=0, padx=4, pady=4)

######
##modes_frame = Frame(toggle_frame, relief=FLAT, borderwidth=1)
##modes_frame.grid(row=0, column=0, padx=4, pady=4)
##
###
##modes_label = Label(modes_frame, text="Mode Options:").grid(row=0, column=0, sticky=W)
##
##sigma_rep_label = Label(modes_frame, text="Sigmas").grid(row=1, column=0, sticky=E)
##sigma_rep_widget = Checkbutton(modes_frame, text="", variable=simu.tv_sigma_rep, command=simu.t_sigma_rep).grid(row=1, column=1)
##
##box_rep_label = Label(modes_frame, text="Boxes").grid(row=2, column=0, sticky=E)
##box_rep_widget = Checkbutton(modes_frame, text="", variable=simu.tv_box_rep, command=simu.t_box_rep).grid(row=2, column=1)
##
##sphere_rep_label = Label(modes_frame, text="Sphere").grid(row=3, column=0, sticky=E)
##sphere_rep_widget = Checkbutton(modes_frame, text="", variable=simu.tv_sphere_rep, command=simu.t_sphere_rep).grid(row=3, column=1)
##
##circles_label = Label(modes_frame, text="Circles").grid(row=1, column=2, sticky=E)
##circles_widget = Checkbutton(modes_frame, text="", variable=simu.tv_circles, command=simu.t_circles).grid(row=1, column=3)
##
##flatten_label = Label(modes_frame, text="Flatten").grid(row=2, column=2, sticky=E)
##flatten_widget = Checkbutton(modes_frame, text="", variable=simu.tv_flatten, command=simu.t_flatten).grid(row=2, column=3)
##
##points_label = Label(modes_frame, text="Points").grid(row=3, column=2, sticky=E)
##points_widget = Checkbutton(modes_frame, text="", variable=simu.tv_points, command=simu.t_points).grid(row=3, column=3)
##
###


######
##visuals_frame = Frame(toggle_frame, relief=FLAT, borderwidth=1)
##visuals_frame.grid(row=0, column=0, padx=4, pady=4)
##
###
##visuals_label = Label(visuals_frame, text="Visual Options:").grid(row=0, column=0, sticky=W)
##
##sublattices_label = Label(visuals_frame, text="Sublattices").grid(row=1, column=0, sticky=E)
##sublattices_widget = Checkbutton(visuals_frame, text="", variable=simu.tv_sublattices, command=simu.t_sublattices).grid(row=1, column=1)
##
##torque_label = Label(visuals_frame, text="Torques").grid(row=2, column=0, sticky=E)
##torque_widget = Checkbutton(visuals_frame, text="", variable=simu.tv_torques, command=simu.t_torques).grid(row=2, column=1)
##
##color_label = Label(visuals_frame, text="Colors").grid(row=3, column=0, sticky=E)
##color_widget = Checkbutton(visuals_frame, text="", variable=simu.tv_colors, command=simu.t_colors)
##color_widget.grid(row=3, column=1)
##color_widget.toggle()
##
##fm_filter_label = Label(visuals_frame, text="FM Filter").grid(row=4, column=0, sticky=E)
##fm_filter_widget = Checkbutton(visuals_frame, text="", variable=simu.tv_fm_filter, command=simu.t_fm_filter).grid(row=4, column=1)
###
##
##
##
####
simu_frame = Frame(toggle_frame, relief=FLAT, borderwidth=0)
simu_frame.grid(row=1, column=0, columnspan=2, padx=4, pady=4)

#
simu_label = Label(simu_frame, text="Simulation:").grid(row=0, column=0, sticky=W)
##
##stripes_label = Label(simu_frame, text="Stripes").grid(row=1, column=0, sticky=E)
##stripes_widget = Checkbutton(simu_frame, text="", variable=simu.tv_stripes, command=simu.t_stripes).grid(row=1, column=1)
##
randomize_widget = Button(simu_frame, text="Randomize", command=simu.randomize).grid(row=1, column=2, padx=4, pady=2)
##
##reset_widget = Button(simu_frame, text="Reset", command=simu.reset).grid(row=1, column=3, padx=4, pady=2)
###
##
##
##
####
scales_frame = Frame(top_frame, relief=FLAT, borderwidth=1)
scales_frame.grid(row=1, column=0, columnspan=2, padx=10, pady=10)

#
scales_label = Label(scales_frame, text="Scales:").grid(row=0, column=0, sticky=W)

kxWidget = Scale(scales_frame, orient=VERTICAL, from_=2.0*3.1416, to=0.0, resolution=0.31416/2.0, label="kxLx", command=lambda str: simu.setKx(str))
kxWidget.set(simu.k.x)
kxWidget.grid(row=1, column=0)

kyWidget = Scale(scales_frame, orient=VERTICAL, from_=2.0*3.1416, to=0.0, resolution=0.31416/2.0, label="kyLy", command=lambda str: simu.setKy(str))
kyWidget.set(simu.k.y)
kyWidget.grid(row=1, column=1)

JbxRatioWidget = Scale(scales_frame, orient=VERTICAL, from_=3.0, to=-3.0, resolution=0.04, label="Jbx", command=lambda str: simu.setJbx(str))
JbxRatioWidget.set(simu.Jbx)
JbxRatioWidget.grid(row=1, column=2)

JbyRatioWidget = Scale(scales_frame, orient=VERTICAL, from_=3.0, to=-3.0, resolution=0.04, label="Jby", command=lambda str: simu.setJby(str))
JbyRatioWidget.set(simu.Jby)
JbyRatioWidget.grid(row=1, column=3)
#


####
scales2_frame = Frame(top_frame, relief=FLAT, borderwidth=1)
scales2_frame.grid(row=2, column=0, columnspan=2, padx=10, pady=10)

#
##mean_field_down_widget = Scale(scales2_frame, orient=VERTICAL, from_=1.00, to=-1.00, resolution=0.01, label="MF D", command=lambda str: simu.set_mean_field_down(str))
##mean_field_down_widget.set(simu.mean_field_down)
##mean_field_down_widget.grid(row=0, column=0)
##
##mean_field_up_widget = Scale(scales2_frame, orient=VERTICAL, from_=1.00, to=-1.00, resolution=0.01, label="MF U", command=lambda str: simu.set_mean_field_up(str))
##mean_field_up_widget.set(simu.mean_field_up)
##mean_field_up_widget.grid(row=0, column=1)
##
tempWidget = Scale(scales2_frame, orient=VERTICAL, from_=10.0, to=0, resolution=0.05, label="kT", command=lambda str: simu.setTemp(str))
tempWidget.set(simu.temp/simu.Ja)
tempWidget.grid(row=0, column=2)

DtWidget = Scale(scales2_frame, orient=VERTICAL, from_=200, to=0, label="dt", command=lambda str: simu.setDt(str))
DtWidget.set(simu.dt*10000.0)
DtWidget.grid(row=0, column=3)
#

##  Enter the main TKR loop, starting the interface and program ##
tkr.mainloop()











##gammaRatioWidget = Scale(scales_frame, orient=VERTICAL, from_=1.000, to=-1.000, resolution=0.001, label="GR", command=lambda str: simu.setGamma(str))
####gammaRatioWidget.set(simu.spin_mag_ratio)
##gammaRatioWidget.grid(row=1, column=2)
