from Tkinter import *
from colorservices import *
from classpoint import Point

#------------"transfering movement functions from Square to Pointer"

class Pointer(Point): # use a better name??
    def __init__(self, coord=(0, 0), canvas=None, size=20, spacer=2):
        Point.__init__(self, coord, )
        self.size = size
        self.spacer = spacer

    def moveNextCol(self):
        self.x += self.size + self.spacer
        return (self.x, self.y)

    def moveNextRow(self):
        self.y += self.size + self.spacer
        return (self.x, self.y)
    

class HarmonyPalettes(object):
    '''generate colors and  draw each on a canvas'''
    def __init__(self, canv, rgb="#05ff05", size=20, spacer=2):
        canv.config(height=375, width=500)
        baseRGB = rgb
        baseHSV = getHSV(baseRGB)
        harmonies = [("Base Color - Tints & Shades", (0,)),
                    ("Complementary - RGB color space", (180,)),
                    ("Split complementary - RGB", (150, 210)),
                    ("Triad - RGB", (120, 240))]
        self.size = size
        self.largeSquareSize = self.size * 2 + spacer
        self.xoffset = self.largeSquareSize + spacer
        start = (10, 20)
        self.origin = Pointer(start, size=self.size, spacer=2)
        self.sqr = Square(canv, nwCorner=self.origin.getCoord(), lenSide=self.size,
                     tagList=["", "harm"])
        self.largeSqr = Square(canv, nwCorner=self.origin.getCoord(), 
                               lenSide=self.size*2 + spacer,
                               tagList=["", "harm"])
        print  "self.__class__", self.__class__

        for name, angles in harmonies:
            canv.create_text(self.origin.x, self.origin.y + 4, text=name, anchor=NW)
            self.origin.moveNextRow()

            for angle in angles:
                self.largeSqr.copyXY(self.origin)
                self.sqr.moveAbs((self.xoffset + self.largeSqr.x, self.origin.y))
                newHSV = self.rotateHue(baseHSV, angle)
                newRGB = getRGB(newHSV)
                self.largeSqr.draw(fillColor=newRGB)
                tints = self.getTints(newHSV, 10, 5)
                shades = self.getShades(newHSV, 10, 5)
                for tint in tints:
                    self.sqr.draw(fillColor=tint)
                self.origin.moveNextRow()
                self.sqr.moveAbs((self.xoffset + self.origin.x, self.origin.y))
                for shade in shades:
                    self.sqr.draw(fillColor=shade)
                self.origin.moveNextRow()
                self.sqr.copyXY(self.origin)

    def rotateHue(self, baseHSV, angle):
        hue, sat, val = baseHSV
        sum = hue + angle
        if sum > 360:
            sum -= 360
        return ((sum, sat, val))

    def getTints(self, baseHSV, steps=10, stepValue=10):
        '''return array of colors that vary the saturation\
        the original color plus three tints to either side'''
        tints = []
        h, s, v = baseHSV

        for sat in range (100, 0, -5):
            tints.append(getRGB((h, sat, v)))
        return tints

    def getShades(self, baseHSV, steps=10, stepValue=10):
        '''return array of colors that vary the saturation\
        the original color plus three tints to either side'''
        shades = []
        h, s, val = baseHSV
        for val in range (100, 0, -5):
            shades.append(getRGB((h, s, val)))
        return shades

class DrawPalette(object): #for gimp and favorites
    "draws squares by rows on a canvas until *colors* list is exhausted"
    def __init__(self, canv, colors, name='', tags = [], columns=16, 
                 size=20, spacer=2, start=(5, 5)):
        self.square = Square(canv, tagList = tags, nwCorner = start, 
                        lenSide=size)
#        print id(self.square), tags
        origin = Square(canv, nwCorner = start, lenSide=size)
        origin.config(tagList = tags)
#        print id(origin)
        
        rgb = (color for color in colors)
        if name:
            self.draw_text(canv, name, origin)
        self.draw_squares(canv, rgb, origin, columns)

    def draw_text(self, canv, name, origin):
        x, y = origin.x, origin.y
        canv.create_text(x, y + 3, text=name, anchor=W)
        origin.moveNextRow()

    def draw_squares(self, canv, rgb, origin, columns):
#        print "in draw_squares::self.square.tagList", self.square.tags
        def move():
            origin.moveNextRow()
            self.square.copyXY(origin)
        while True:
            for col in range(columns):
                try:
                    self.square.draw(fillColor=rgb.next())
                except StopIteration: #out of colors
                    move()
                    return
            move()
            
class Square(Pointer):
    def __init__(self, canvas, nwCorner=(0, 0), lenSide=5, fillColor="",
                 tagList=[], activeoutline="white"):
        Pointer.__init__(self, coord = nwCorner, size = lenSide, )
        self.canvas = canvas
        self.lenSide = lenSide
        self.fillColor = fillColor
        self.activeoutline = activeoutline
#        print "in Square::tagList", tagList
        self.tags = Tagifier(tagList)

    def duplicate(self):
        return Square((self.x, self.y), self.canvas, self.size, self.spacer)
                
    def config(self, **kwargs):
        if "nwCorner" in kwargs:
            self.set(kwargs["nwCorner"])
#            print "kwARG", type(kwargs["nwCorner"])
        if "tagList" in kwargs: self.tags.processNew(kwargs["tagList"])
        for k in kwargs.keys():
            self.__dict__[k] = kwargs[k]
            
    def corners(self):
        d = self.lenSide
        return (self.x, self.y, self.x + d, self.y + d)
    
    def moveTo(self, nwCorner):
        self.set(coord=nwCorner)
     
    def draw(self, **kwargs):
        #=======================================================================
        # kwargs is intended for colorFill and moving x, y
        #    but any value attribute can be changed - for now
        #=======================================================================
        if kwargs:
            self.config(**kwargs)
            tags=self.tags.next()
        self.canvas.create_rectangle(self.corners(), fill=self.fillColor,
                        tags=self.tags.next(), activeoutline=self.activeoutline, outline="#bababa")
#        print "in Square, draw(), tags", tags
        self.moveNextCol()
        
class Tagifier(object):
    """returns a  list of tags, the special bit  is appending the first tag 
    with an index number"""
    start = 0
    def __init__(self, tagList=[]):
#        print "taglist", tagList
        self.processNew(tagList)
        
    def processNew(self, tagList):
        self.tagList = tagList
        self.ndxdTag = []
        if self.tagList:
#            print self.tagList, "in process new ln 170"
            self.ndxdTag = self.tagList.pop(0)
        self.staticTags = list(self.tagList)

    def __iter__(self):
        return self
        
    def next(self):
        front = []
        if self.ndxdTag:
            front = [self.ndxdTag.strip() + str(Tagifier.start).rjust(4, '0')]
            Tagifier.start += 1
            front.extend(self.staticTags)
            t = front
        else:
            t = self.staticTags
        return t
    
    def setIndex(self, index=0):
        Tagifier.start = index
        

if __name__ == '__main__':
    root = Tk()
    
    def select(event):
        sqr = canvas.find_closest(event.x, event.y)
        tagstr = canvas.itemcget(sqr, "tags")
        print "tags::", tagstr
        if "current" in tagstr:
            print "yes"
        else:
            print "no"

    colors = ["#123456","#abcdef", "#a1b2c3", "#189050", "#baddad", "#cadcam",
               "#cabeee", "#201110", "#aabbcc"]
    canvas = Canvas(width=600, height=200, bg='white')
    canvas.pack(expand=YES, fill=BOTH)
    root.bind("<KeyPress-c>", select)

    HarmonyPalettes(canvas)
    DrawPalette(canvas, colors, tags = ["", "beans"])
    
     
    root.mainloop()
