#!/usr/local/bin/python
import sys
import os
import string

from spreadsheetsubjectproxy import *

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

NotCellError='NotCellError'

TRUE=1
FALSE=0

class TxtInterface:
    def __init__(self, subject=None, id=None):
        if subject==None:
            self.subject=SpreadSheetSubjectProxy()
        else:
            self.subject=subject
        self.id=id
        self.observerlist=[]
        self.invoker=Invoker()
        self.update()
        self.myturn=FALSE
        
    def run(self):
	
        while 1:
            cmd=raw_input(">>> ")

            if cmd=="":
                continue

            cmdargs=string.split(cmd)

	    if cmdargs[0]=="quit" or cmdargs[0]=='Quit' or cmdargs[0]=='q' or cmdargs=='Q':
		break;
	    elif cmdargs[0]=="plot":
                if not len(cmdargs)==5:
                    print "Four args needed to specify the cell range"
                else:
                    try:
                        self._user_PlotObserver(string.atoi(cmdargs[1]), string.atoi(cmdargs[2]),\
				   string.atoi(cmdargs[3]), string.atoi(cmdargs[4]))
                    except ValueError:
                        print "The position must be integer"

            elif cmdargs[0]=='gettoken':
                self.myturn=self.subject.getToken(self.id)
                if self.myturn==TRUE :
                    print "You've gotten the token, so you can edit the spreadsheet now"
                elif self.myturn==2:
                    print "You already registered to get a token"
                else:
                    print "You did not get the token, you cannot edit the spreadsheet. Wait until the server notifies you."

            elif cmdargs[0]=='returntoken':
                self.subject.returnToken(self.id)
                if self.myturn==TRUE:
                    print "You returned your token, you cannot edit the spreadsheet until you get a new token"
                    self.myturn=FALSE
                else:
                    print "You did not get your token"

            elif cmdargs[0]=="value":
                if not len(cmdargs)==2:
                    print "One args needed to specify a cell"
                else:
                    try:
                        cellrow, cellcol=self.cellPositionInterpretor(cmdargs[1])
                        print cmdargs[1], " current value is: ", `self.subject.getData(cellrow, cellcol)`
                        print cmdargs[1], " current formula is: ", `self.subject.getDataTree(cellrow, cellcol)`
                    except:
                        print cmdargs[1], 'is not for a defined cell'
	    elif cmdargs[0]=="set":
                if self.myturn==TRUE:
                    if not len(cmdargs)==3:
                        print "Three args needed to change a value of a cell"
                    else:
                        try:
                            cellrow, cellcol=self.cellPositionInterpretor(cmdargs[1])
                            cmd=SetCommand(self.subject,cellrow,cellcol,cmdargs[2])
                            self.invoker.invoke(cmd)                        
                        except:
                            print cmdargs[1], 'is not for a defined cell'
                else:
                    print "You did not get the token, you cannot edit the spreadsheet."

            elif cmdargs[0]=='undo':
                if self.myturn==TRUE:
                    self.invoker.undo()
                else:
                    print "You did not get the token, you cannot edit the spreadsheet."

            elif cmdargs[0]=='redo':
                if self.myturn==TRUE:
                    self.invoker.redo()
                else:
                    print "You did not get the token, you cannot edit the spreadsheet."
                    
	    elif cmdargs[0]=="spreadsheet":
                if not len(cmdargs)==5:
                    print "Four args needed to specify the cell range"
                else:
                    try:
                        self._user_SpreadsheetObserver(string.atoi(cmdargs[1]), \
				string.atoi(cmdargs[2]), string.atoi(cmdargs[3]), \
			        string.atoi(cmdargs[4]))
                    except ValueError:
                        print "The cell position must be integer"
            else:
                print 'The command cannot be recognized.'


        self.subject.detach(self.id)
                
    def quit(self):
        self.subject.detach(self.id)

    def receiveToken(self):
        self.myturn=TRUE
        print ""
        print "You've gotten the token, so you can edit the spreadsheet now"
        #sys.stdout.write(">>> \n")
    
    def update(self):
        for o in self.observerlist:
            try:
                o.update()
            except TclError:
                self.observerlist.remove(o)

    def _user_PlotObserver(self, startx, starty, endx, endy):
        observer=PlotObserver(SpreadSheetSubjectProxy(), (startx, starty), (endx, endy))
        #observer=PlotObserver(self.subject, (startx, starty), (endx, endy))
        self.observerlist.append(observer)
        #os.spawnvp(os.P_NOWAIT, './client.py', ['plot', (startx, starty), (endx, endy)])

    def _user_SpreadsheetObserver(self, startx, starty, endx, endy):
        tk=Tk()
        observer=SpreadsheetObserver(SpreadSheetSubjectProxy(), startx, starty, endx, endy, master=tk)
        #observer=SpreadsheetObserver(self.subject, startx, starty, endx, endy, master=tk)
        self.observerlist.append(observer)
        #tk=Tk()
        #os.spawnvp(os.P_NOWAIT, '/client.py', ['spreadsheet', startx, starty, endx, endy, tk])
        #os.spawnlp(os.P_NOWAITO, 'client.py')
        #print `os.system('python client.py')`

    def cellPositionInterpretor(self, cellstr):
        strlen=len(cellstr)
        cellstr=cellstr+'\0'
        if cellstr[0]=='$':
            ix=1
            while cellstr[ix] in string.whitespace:
                ix=ix+1
            row=''
            if cellstr[ix] in string.digits:
                while cellstr[ix] in string.digits:
                    row=row+cellstr[ix]
                    ix=ix+1
            else:
                raise NotCellError

            while cellstr[ix] in string.whitespace:
                ix=ix+1
            if cellstr[ix]=='$':
                ix=ix+1
            while cellstr[ix] in string.whitespace:
                ix=ix+1
            col=''
            if cellstr[ix] in string.digits:
                while cellstr[ix] in string.digits:
                    col=col+cellstr[ix]
                    ix=ix+1
            else:
                raise NotCellError

            if not strlen==ix:
                raise NotCellError

            return (string.atoi(row), string.atoi(col))
        
        else:
            raise NotCellError

if __name__ == '__main__':
	TxtInterface().run()











