import sys
import socket
from Tkinter import *
import random
import tkFont
import os.path

def decToHexStr(x):
    h = hex(x)
    if x < 16:
        return '0' + h[2:]
    return h[2:]

class Application(Frame): 
    
    def __init__(self, socketConn=None, master=None): 
        """ constructor inputs:
                socketConn, a socket connection
                master, the root or parent window
        """
        Frame.__init__(self, master)
        self.sock = socketConn
        self.currentcolor=0
        self.grid()
        self.createWidgets() 
        self.color=[0,255,0,255,0,255]
        self.colors=[self.color[:],self.color[:],self.color[:],self.color[:],self.color[:],
                    self.color[:],self.color[:],self.color[:],self.color[:],self.color[:]]
        self.dotx=-1
        self.doty=-1   
        self.distance=-1         
        self.dotWindow=Toplevel()
        self.createDotWidgets(self.dotWindow)
        
    
    
    def sendData(self):
        if self.sock:
            message= "sendingdata " + str(self.rminScale.get()) + " "+ str(self.rmaxScale.get())\
                        + " "+ str(self.gminScale.get())+ " "+ str(self.gmaxScale.get())+\
                        " "+ str(self.bminScale.get())+ " "+ str(self.bmaxScale.get())
            print 'Sending "', message, '"'
            self.sock.send(message)
            data = self.sock.recv(1024)
            print "Received the data:", data
            
        else:
            print 'No socket connection was made at startup.'
            data = ''
        return data
            
        
        
    def myquit(self):
        if self.sock:
            # message = raw_input("Type a string to send: ")
            #message = self.stringToSend.get()
            message = "quit"
            print 'Sending "', message, '"'
            self.sock.send(message)
            data = self.sock.recv(1024)
            print "Received the data:", data
    
            
        else:
            print 'No socket connection was made at startup.'
            data = ''
        self.quit();

        
    def getData(self):
        """ this method sends off the string inside "entryLine" to
            the server (if a connection was made at start up)
            if there was no connection, it just prints that string
            the data returned from the connection (or nothing) is returned
        """
        if self.sock:
            message = "getdata"
            print 'Sending "', message, '"'
            self.sock.send(message)
            data = self.sock.recv(1024)
            print "Received the data:", data
            L= data.split();
            L=L[1:];
            L=[ int(x) for x in L ];
            self.rminScale.set(L[0])
            self.rmaxScale.set(L[1])
            self.gminScale.set(L[2])
            self.gmaxScale.set(L[3])
            self.bminScale.set(L[4])
            self.bmaxScale.set(L[5])
            self.setcolor(0);
            
        else:
            print 'No socket connection was made at startup.'
            data = ''
        return data
        
        
    def fromFile(self):
        if(os.path.isfile("colors.txt")):
            f=file("colors.txt", "r")
            while f:
                line=f.readline()
                L=line.split()
                if len(L)==0:
                    break
                self.currentcolor=int(L[0])
                L=L[2:]
                L=[ int(x) for x in L ];
                self.rminScale.set(L[0])
                self.rmaxScale.set(L[1])
                self.gminScale.set(L[2])
                self.gmaxScale.set(L[3])
                self.bminScale.set(L[4])
                self.bmaxScale.set(L[5])
                self.setcolor(0);
            f.close()
                
        
        
    def toFile(self):
        f=file("colors.txt", "w")
        for x in range(0,10):
            self.currentcolor=x
            print >>f, (str(x)+ " : "+ str(self.colors[self.currentcolor][0])+" "+ str(self.colors[self.currentcolor][1])
            + " "+ str(self.colors[self.currentcolor][2])+ " "+ str(self.colors[self.currentcolor][3]) + " "
            + str(self.colors[self.currentcolor][4]) + " " + str(self.colors[self.currentcolor][5]))
        f.close()
        

    

        
    def setcolor(self,val):
        
            redavg= (self.rminScale.get() + self.rmaxScale.get())/2
            greenavg=(self.gminScale.get() + self.gmaxScale.get())/2
            blueavg=(self.bminScale.get() + self.bmaxScale.get())/2
            
            
            ra = decToHexStr(redavg)
            ga = decToHexStr(greenavg)
            ba = decToHexStr(blueavg)
            
            self.colors[self.currentcolor][0]=self.rminScale.get()
            self.colors[self.currentcolor][1]=self.rmaxScale.get()
            self.colors[self.currentcolor][2]=self.gminScale.get()
            self.colors[self.currentcolor][3]=self.gmaxScale.get()
            self.colors[self.currentcolor][4]=self.bminScale.get()
            self.colors[self.currentcolor][5]=self.bmaxScale.get()
            
            
                  
            self.bminScale.configure(bg="#"+ ra+ga+ decToHexStr(self.bminScale.get()))
            self.bmaxScale.configure(bg="#"+ ra+ga+ decToHexStr(self.bmaxScale.get()))
        
            self.gminScale.configure(bg="#"+ ra+ decToHexStr(self.gminScale.get()) + ba)
            self.gmaxScale.configure(bg="#"+ ra+ decToHexStr(self.gmaxScale.get()) + ba)
            
            self.rminScale.configure(bg="#"+ decToHexStr(self.rminScale.get()) +ga+ba)
            self.rmaxScale.configure(bg="#"+ decToHexStr(self.rmaxScale.get()) +ga+ba)
            
            self.avgColor[self.currentcolor].configure(bg="#"+ ra+ga+ba)
    
    def setCurrColor(self, val):
        
        self.currentcolor=val;
        self.rminScale.set(self.colors[self.currentcolor][0])
        self.rmaxScale.set(self.colors[self.currentcolor][1])
        self.gminScale.set(self.colors[self.currentcolor][2])
        self.gmaxScale.set(self.colors[self.currentcolor][3])
        self.bminScale.set(self.colors[self.currentcolor][4])
        self.bmaxScale.set(self.colors[self.currentcolor][5])
        self.setcolor(0)
        self.CurrColor.configure(text= "CURRENT COLOR: "+ str(self.currentcolor), font= tkFont.Font(weight="bold", size=15))
        
        
    
        
    def createWidgets(self): 
        """ this method initializes all of the pieces of the GUI
        """
        self.quitButton = Button ( self, text="Quit", command=self.myquit ) 
        self.quitButton.grid(row=1, column=9, pady=10, padx=0) 
        
        self.quitButtonMini = Button ( self, text="MiniQuit", command=self.quit ) 
        self.quitButtonMini.grid(row=1, column=8, pady=10, padx=0)
        
        self.dataButton = Button ( self, text="GetColor", command=self.getData ) 
        self.dataButton.grid(row=1, column=0, pady=10, padx=0)
        
        self.ffileButton = Button ( self, text="GetFromFile", command=self.fromFile ) 
        self.ffileButton.grid(row=1, column=4, pady=10, padx=0)
        
        self.tfileButton = Button ( self, text="SendToFile", command=self.toFile ) 
        self.tfileButton.grid(row=1, column=6, pady=10, padx=0)
        
        self.sdataButton = Button ( self, text="SendColor", command=self.sendData ) 
        self.sdataButton.grid(row=1, column=2, pady=10, padx=0)
        
            
        
        self.bminScale = Scale ( self, from_=0, to=255, label="blue minimum", bg='#aaaaff', fg='white',
                                tickinterval=50, orient=HORIZONTAL, length=350, width=30, command=self.setcolor) 
                                
        self.bminScale.set(0)
        self.bminScale.grid(row=2, column=0, columnspan=5, padx=10, pady=15)
        
        
        self.bmaxScale = Scale ( self, from_=0, to=255, label="blue maximum", bg='#000099', fg='white',
                                 tickinterval=50, orient=HORIZONTAL, length=350, width=30, command=self.setcolor)
                                 
        self.bmaxScale.set(255)
        self.bmaxScale.grid(row=2, column=5, columnspan=5, padx=10, pady=15)
        
        
        self.gminScale = Scale ( self, from_=0, to=255, label="green minimum", bg='#aaffaa', fg='white',
                                 tickinterval=50, orient=HORIZONTAL, length=350, width=30, command=self.setcolor)
        self.gminScale.set(0)
        self.gminScale.grid(row=3, column=0, columnspan=5, padx=10, pady=15)
        
        
        self.gmaxScale = Scale ( self, from_=0, to=255, label="green maximum", bg='#009900', fg='white',
                                 tickinterval=50, orient=HORIZONTAL, length=350, width=30, command=self.setcolor )
        self.gmaxScale.set(255)
        self.gmaxScale.grid(row=3, column=5, columnspan=5, padx=10, pady=15)
        
        self.rminScale = Scale ( self, from_=0, to=255, label="red minimum", bg='#ffaaaa', fg='white',
                                 tickinterval=50, orient=HORIZONTAL, length=350, width=30, command=self.setcolor )
        self.rminScale.set(0)
        self.rminScale.grid(row=4, column=0, columnspan=5, padx=10, pady=15)
        
        
        self.rmaxScale = Scale ( self, from_=0, to=255, label="red maximum", bg='#990000', fg='white',
                                 tickinterval=50, orient=HORIZONTAL, length=350, width=30, command=self.setcolor )
        self.rmaxScale.set(255)
        self.rmaxScale.grid(row=4, column=5, columnspan=5, padx=10, pady=15)
        
        
        redavg= (self.rminScale.get() + self.rmaxScale.get())/2
        greenavg=(self.gminScale.get() + self.gmaxScale.get())/2
        blueavg=(self.bminScale.get() + self.bmaxScale.get())/2
        ra = decToHexStr(redavg)
        ga = decToHexStr(greenavg)
        ba = decToHexStr(blueavg)
        
        self.avgColor= [0]*10
        self.colorNum= [0]*10
        
        for x in range(0,10):
            self.avgColor[x] = Label ( self, bg="#" + ra+ba+ga, height=3, width=5,padx=10, pady=8) 
            self.avgColor[x].grid(row=5, column=x,padx=10, pady=10, columnspan=1 )
        
        self.CurrColor= Label(self, text= "CURRENT COLOR: "+ str(self.currentcolor), font= tkFont.Font(weight="bold", size=15))
        self.CurrColor.grid(row=7, column=4,pady=15, columnspan=2)
        
        
        for x23 in range(0,10):
                self.colorNum[x23] = Button (self, text="Color "+ str(x23), height=1, width=5,
                font= tkFont.Font(size=10)) 
                self.colorNum[x23].grid(row=6, column=x23,padx=10, pady=0, columnspan=1 )
                
        if True:
            self.colorNum[0].configure(command=lambda : self.setCurrColor(0))
            self.colorNum[1].configure(command=lambda : self.setCurrColor(1))
            self.colorNum[2].configure(command=lambda : self.setCurrColor(2))
            self.colorNum[3].configure(command=lambda : self.setCurrColor(3))
            self.colorNum[4].configure(command=lambda : self.setCurrColor(4))
            self.colorNum[5].configure(command=lambda : self.setCurrColor(5))
            self.colorNum[6].configure(command=lambda : self.setCurrColor(6))
            self.colorNum[7].configure(command=lambda : self.setCurrColor(7))
            self.colorNum[8].configure(command=lambda : self.setCurrColor(8))
            self.colorNum[9].configure(command=lambda : self.setCurrColor(9))



    def getDotData(self):
        if self.sock:
            message = "getdotdata"
            print 'Sending "', message, '"'
            self.sock.send(message)
            data = self.sock.recv(1024)
            print "Received the data:", data
            L= data.split();
            L=L[1:];
            L=[ int(x) for x in L ];
            self.rminScale2.set(L[0])
            self.rmaxScale2.set(L[1])
            self.gminScale2.set(L[2])
            self.gmaxScale2.set(L[3])
            self.bminScale2.set(L[4])
            self.bmaxScale2.set(L[5])
            self.setdotcolor(0);
        else:
            print 'No socket connection was made at startup.'
            data = ''
        return data
        
    def sendDotData(self):
        if self.sock:
            message= "sendingdotdata"+ " "+ str(self.rminScale2.get()) + " "+ str(self.rmaxScale2.get())\
                        + " "+ str(self.gminScale2.get())+ " "+ str(self.gmaxScale2.get())+\
                        " "+ str(self.bminScale2.get())+ " "+ str(self.bmaxScale2.get())
            print 'Sending "', message, '"'
            self.sock.send(message)
            data = self.sock.recv(1024)
            print "Received the data:", data
            
        else:
            print 'No socket connection was made at startup.'
            data = ''
        return data
        
        
    def dotFromFile(self):
        if(os.path.isfile("dot.txt")):
            f=file("dot.txt", "r")
            line=f.readline()
            L=line.split()
            if len(L)==0:
                f.close()
                return;
            L=L[1:]
            L=[ int(x) for x in L ];
            self.rminScale2.set(L[0])
            self.rmaxScale2.set(L[1])
            self.gminScale2.set(L[2])
            self.gmaxScale2.set(L[3])
            self.bminScale2.set(L[4])
            self.bmaxScale2.set(L[5])
            self.setdotcolor(0);
            f.close()



    def dotToFile(self):
        f=file("dot.txt", "w")
        print >>f, ("dot: "+ str(self.rminScale2.get())+" "+ str(self.rmaxScale2.get())
            + " "+ str(self.gminScale2.get())+ " "+ str(self.gmaxScale2.get()) + " "
            + str(self.bminScale2.get()) + " " + str(self.bmaxScale2.get()))
        f.close()


    def setdotcolor(self,val):

        redavg= (self.rminScale2.get() + self.rmaxScale2.get())/2
        greenavg=(self.gminScale2.get() + self.gmaxScale2.get())/2
        blueavg=(self.bminScale2.get() + self.bmaxScale2.get())/2


        ra = decToHexStr(redavg)
        ga = decToHexStr(greenavg)
        ba = decToHexStr(blueavg)

        self.bminScale2.configure(bg="#"+ ra+ga+ decToHexStr(self.bminScale.get()))
        self.bmaxScale2.configure(bg="#"+ ra+ga+ decToHexStr(self.bmaxScale.get()))

        self.gminScale2.configure(bg="#"+ ra+ decToHexStr(self.gminScale.get()) + ba)
        self.gmaxScale2.configure(bg="#"+ ra+ decToHexStr(self.gmaxScale.get()) + ba)

        self.rminScale2.configure(bg="#"+ decToHexStr(self.rminScale.get()) +ga+ba)
        self.rmaxScale2.configure(bg="#"+ decToHexStr(self.rmaxScale.get()) +ga+ba)

        self.DotColor.configure(bg="#"+ ra+ga+ba)
        
    def getdist(self):
        if(os.path.isfile("laser.txt")):
            f=file("laser.txt", "r")
            line=f.readline()
            M=line.split()
            if len(M)==0:
                f.close()
                return;
            M=M[1:]
            M=[ int(x) for x in M ];
            L=M[0];
            
            line=f.readline()
            M=line.split()
            if len(M)==0:
                f.close()
                return;
            M=M[1:]
            M=[ int(x) for x in M ];
            H=M[0];
            self.distance=getd(L,H,self.doty)
            f.close()
        else:
            self.distance=-1
        
        
    def getPos(self):
        if self.sock:
            message = "getpos"
            print 'Sending "', message, '"'
            self.sock.send(message)
            data = self.sock.recv(1024)
            print "Received the data:", data
            L= data.split();
            L=L[1:];
            L=[ int(x) for x in L ];
            self.dotx=L[0]
            self.doty=L[1]
            if self.doty<0:
                self.distance=-1
            else:
                self.getdist()
                
                
            self.dotPos.configure(text= "Position: ("+ str(self.dotx)+" , "+ str(self.doty) +")")
            self.dist.configure(text=" Distance: "+ str(self.distance))
            
        else:
            print 'No socket connection was made at startup.'
            data = ''
        return data
        


    def createDotWidgets(self, master):

        self.dotDataButton = Button ( master, text="GetColor", command=self.getDotData ) 
        self.dotDataButton.grid(row=1, column=0, pady=10, padx=0)

        self.dotFFileButton = Button ( master, text="GetDotFromFile", command=self.dotFromFile ) 
        self.dotFFileButton.grid(row=1, column=4, pady=10, padx=0)

        self.dotTFileButton = Button ( master, text="SendDotToFile", command=self.dotToFile ) 
        self.dotTFileButton.grid(row=1, column=6, pady=10, padx=0)

        self.sDotdataButton = Button ( master, text="SendColor", command=self.sendDotData ) 
        self.sDotdataButton.grid(row=1, column=2, pady=10, padx=0)

        self.getPosButton = Button(master, text="GetPosition", command=self.getPos)
        self.getPosButton.grid(row=1, column=8, padx=0, pady=10)



        self.bminScale2 = Scale ( master, from_=0, to=255, label="blue minimum", bg='#aaaaff', fg='white',
                                tickinterval=50, orient=HORIZONTAL, length=350, width=30, command=self.setdotcolor) 

        self.bminScale2.set(0)
        self.bminScale2.grid(row=2, column=0, columnspan=5, padx=10, pady=15)


        self.bmaxScale2 = Scale ( master, from_=0, to=255, label="blue maximum", bg='#000099', fg='white',
                                 tickinterval=50, orient=HORIZONTAL, length=350, width=30, command=self.setdotcolor)

        self.bmaxScale2.set(255)
        self.bmaxScale2.grid(row=2, column=5, columnspan=5, padx=10, pady=15)


        self.gminScale2 = Scale ( master, from_=0, to=255, label="green minimum", bg='#aaffaa', fg='white',
                                 tickinterval=50, orient=HORIZONTAL, length=350, width=30, command=self.setdotcolor)
        self.gminScale2.set(0)
        self.gminScale2.grid(row=3, column=0, columnspan=5, padx=10, pady=15)


        self.gmaxScale2 = Scale ( master, from_=0, to=255, label="green maximum", bg='#009900', fg='white',
                                 tickinterval=50, orient=HORIZONTAL, length=350, width=30, command=self.setdotcolor )
        self.gmaxScale2.set(255)
        self.gmaxScale2.grid(row=3, column=5, columnspan=5, padx=10, pady=15)

        self.rminScale2 = Scale ( master, from_=0, to=255, label="red minimum", bg='#ffaaaa', fg='white',
                                 tickinterval=50, orient=HORIZONTAL, length=350, width=30, command=self.setdotcolor )
        self.rminScale2.set(0)
        self.rminScale2.grid(row=4, column=0, columnspan=5, padx=10, pady=15)


        self.rmaxScale2 = Scale ( master, from_=0, to=255, label="red maximum", bg='#990000', fg='white',
                                 tickinterval=50, orient=HORIZONTAL, length=350, width=30, command=self.setdotcolor )
        self.rmaxScale2.set(255)
        self.rmaxScale2.grid(row=4, column=5, columnspan=5, padx=10, pady=15)


        redavg= (self.rminScale2.get() + self.rmaxScale2.get())/2
        greenavg=(self.gminScale2.get() + self.gmaxScale2.get())/2
        blueavg=(self.bminScale2.get() + self.bmaxScale2.get())/2
        ra = decToHexStr(redavg)
        ga = decToHexStr(greenavg)
        ba = decToHexStr(blueavg)

        self.DotColor = Label ( master, bg="#" + ra+ba+ga, height=3, text= "Dot Color", padx=10, pady=8) 
        self.DotColor.grid(row=5, column=1,padx=10, pady=10, columnspan=2 )
        
        self.dotPos = Label(master, height=3, text= "Dot Position: ("+ str(self.dotx)+" , "+ str(self.doty) +")",
        padx=10, pady=8) 
        self.dotPos.grid(row=5, column=4, padx=10, pady=10, columnspan=2)
        
        self.dist = Label(master, height=3, text=" Distance: "+ str(self.distance), padx=10, pady=8)
        self.dist.grid(row=5, column= 7, padx=10, pady=10, columnspan=2)
    

if __name__ == "__main__":
    serverHost = 'localhost'
    serverPort = 2000
    s = None

    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # create a TCP socket 
        s.connect((serverHost, serverPort)) # connect to server on the port 
        print 'Connection made at port', serverPort
    except:
        s = None
     
    app = Application(s) 
    app.master.title("Sample application") 
    app.mainloop()
