import sys
import string
import fpformat

from abstractobserver import *
from Tkinter import *

import sys, os
sys.path.insert(0,os.pardir)
from data import *

#The following class is the modified version from the class spreadsheetLines
#whic was obtained from Professor Hans Vangheluwe 
class SpreadsheetObserver(AbstractObserver, Frame):
    def __init__(self, subject, startx=0, starty=0, endx=19, endy=19, master=None):
    #def __init__(self, subject, master=None, height=10,width=10):
        # initializer superclasses
        AbstractObserver.__init__(self, subject)

        # Initialize packer ?????
        #Pack.config(self)
        #self.pack()
        
        # to be used by all Spreadsheet methods
	self.startx=startx
	self.starty=starty
	self.endx=endx
	self.endy=endy
	self.height=endx-startx+1
	self.width=endy-starty+1
        #self.height=height
        #self.width=width

        startcell=(startx, starty)
        endcell=(endx, endy)
        master.title('start cell: '+ `startcell`+' end cell:'+`endcell`)
	Frame.__init__(self, master)

        #Frame.__init__(self, master, height=self.height/2, width=self.width)
        self.pack()        

        self.texthandlers={}

        self.createWidgets()        

    def createWidgets(self):
        print 'Widgets is created'
        
	MAXDRAWWIDTH=750    # the max width of canvas is 20 cm
	MAXDRAWHEIGHT=750   # the max height of canvas is 20 cm
        MARGIN=40
	CELLWIDTH=77
	CELLHEIGHT=19
	
        # Canvas 10cm x 10cm, packed on top, left
        # Scrollable region 20cm x 20cm
	drawwidth=self.width*77+MARGIN*2 
        scrollwidth=drawwidth
	drawheight=self.height*19+MARGIN*2
        scrollheight=drawheight
	if drawwidth>MAXDRAWWIDTH:
		drawwidth=MAXDRAWWIDTH
	if drawheight>MAXDRAWHEIGHT:
		drawheight=MAXDRAWHEIGHT
	
        self.drawarea = Canvas(self, 
                               width=drawwidth, height=drawheight,
                               background="white",
                               scrollregion=(0, 0, scrollwidth, scrollheight))

        # An array of Rectangles in the canvas
        # Values of cells are kept in self.data (list of lists),
        for row in range(self.height+1):
            self.drawarea.create_line(MARGIN, MARGIN+row*CELLHEIGHT, 
                                      MARGIN+self.width*CELLWIDTH, MARGIN+row*CELLHEIGHT, 
                                      fill="grey")
        for column in range(self.width+1):
            self.drawarea.create_line(MARGIN+column*CELLWIDTH, MARGIN,
                                      MARGIN+column*CELLWIDTH, MARGIN+self.height*CELLHEIGHT,
                                      fill="grey")

        #create label to show the row number
        lblxoffset=MARGIN/2
        lblyoffset=MARGIN+CELLHEIGHT/2
        row=self.startx
        i=0
        while (row<=self.endx):
            self.drawarea.create_text(lblxoffset, lblyoffset+i*CELLHEIGHT, text=`row`, anchor="c")
            i=i+1
            row=row+1

        #create lable to show the col number
        lblxoffset=MARGIN+CELLWIDTH/2
        lblyoffset=MARGIN/2
        column=self.starty
        j=0
        while(column<=self.endy):
            self.drawarea.create_text(lblxoffset+j*CELLWIDTH,lblyoffset, text=`column`, anchor="c")
            j=j+1
            column=column+1

        # The following puts self.height * self.width
        # text objects on the canvas. This slows down things 
        # considerably. A meaningful alternative is to only
        # display the content of those cells which have a value 
        # in the corresponding self.data[row][column]
        # This leads to the discovery that a "sparse" 
        # representation of the cell values might be far more 
        # efficient. Implement this in a later version.
        txtxoffset=MARGIN+CELLWIDTH/2
        txtyoffset=MARGIN+CELLHEIGHT/2
        for row in range(self.height):
            for column in range(self.width):
                #if self.data[row][column] != 0:
                value=self.subject.getData(row+self.startx, column+self.starty)
               ##  if data!=None:
##                     value=data.getValue()
##                 else:
##                     value=None
                #value=self.subject.getData(row, column)
                id=self.drawarea.create_text(txtxoffset+column*CELLWIDTH, txtyoffset+row*CELLHEIGHT,
                                             text='',
                                             anchor="c")
                self.texthandlers[(row+self.startx, column+self.starty)]=id
		#self.texthandlers[(row, column)]=id
                if value!=None:
                    self.drawarea.itemconfig(id, text=`value`)

        # scrollbars for drawarea
        self.drawarea.scrollX = Scrollbar(self, orient=HORIZONTAL)
        self.drawarea.scrollY = Scrollbar(self, orient=VERTICAL)

        # link canvas, scrollbars, and events
        self.drawarea['xscrollcommand'] = self.drawarea.scrollX.set
        self.drawarea['yscrollcommand'] = self.drawarea.scrollY.set
        self.drawarea.scrollX['command'] = self.drawarea.xview
        self.drawarea.scrollY['command'] = self.drawarea.yview

        # pack it all
        self.drawarea.scrollX.pack(side=BOTTOM, fill=X)
        self.drawarea.scrollY.pack(side=RIGHT, fill=Y)
        self.drawarea.pack(side=LEFT)

	#self.subject.attach(self)

    def update(self):
        for a in self.subject.getState():
            ax=a.getXPosition()	
            ay=a.getYPosition()
            newval=a.getValue()
            if ( ax>=self.startx and ax<=self.endx and ay>=self.starty and ay<=self.endy):
                if not newval==None:
                    self.drawarea.itemconfig(self.texthandlers[(ax,ay)],text=fpformat.fix(a.getValue(), 6))
                else:
                    self.drawarea.itemconfig(self.texthandlers[(ax,ay)],text='')
            else:
		pass
            

if __name__=='main__':
    SpreadSheetObserver().mainloop()

















