#!/usr/local/bin/python
import sys, os
import threading
from socket import *

from spreadsheetsubjectproxy import *
from txtinterface import *

#sys.path.insert(0, os.pardir)
#from plotobserver import *
#from spreadsheetobserver import *
#from clientinfo import *
#from spreadsheet import *
#from data import *

class ListenerThread(threading.Thread):
    def __init__(self,sock,userinterface):
         #self.myinfo=myinfo
         self.s=sock
         self.userinterface=userinterface
         threading.Thread.__init__(self)

    def run(self):
         #self.s=socket(AF_INET, SOCK_STREAM)
         
         #make the socket re-usable for bind(), otherwise, the kernel may 
         #still hang on to the port and bind() will fail. Without 
         #SO_REUSEADDR, just have to wait 
         #self.s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1024)
         #self.s.bind((self.myinfo.getHost(), self.myinfo.getPort()))
         #self.s.listen(1)
         self.conn, self.addr=self.s.accept()
         while 1:
             data=self.conn.recv(1024)
             #print data
             stdoutmutex.acquire()
             if data=='update':
                 self.userinterface.update()
             elif data=='gettoken':
                 self.userinterface.receiveToken()
             else:
                 pass
             #break
             stdoutmutex.release()

class UserInterfaceThread(threading.Thread):
    def __init__(self, subject):
        self.subject=subject
        threading.Thread.__init__(self)
        
    def run(self):
        self.interface=TxtInterface(self.subject)
        self.interface.run()

    def update(self):
        self.interface.update()

stdoutmutex=threading.Lock()

from Tkinter import *

class Client(threading.Thread):
    def __init__(self):
        self.myinfo=(gethostname(),500022)
        self.subject=SpreadSheetSubjectProxy()
        self.observer=None

        self.s=socket(AF_INET, SOCK_STREAM)
        #make the socket re-usable for bind(), otherwise, the kernel may
        #still hang on to the port and bind() will fail. Without 
        #SO_REUSEADDR, just have to wait 
        self.s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1024)
        host, port=self.myinfo
        while 1:
            try:
                self.s.bind((host, port))
                self.myinfo=(host, port)
                break
            except:
                port=port+1
            
        self.s.listen(2)

        self.subject.attach(self.myinfo)

    def run(self):
##        userinput=UserInterfaceThread(self.subject)
##        userinput.start()
        self.userinput=TxtInterface(self.subject, self.myinfo)
        self.listener=ListenerThread(self.s, self.userinput)

        # set the listener thread to be daemonic. The entire Python program
        # exits when no active non-daemon threads are left. 

        self.listener.setDaemon(1)
        
        self.listener.start()
        self.userinput.run()
        #self.quit()
        self.s.close()
        #os._exit(1)
        
    def quit(self):
        self.subject.detach(self.myinfo)
        
if __name__=='__main__':
    Client().run()

