#!/usr/bin/python

from Gui import *
from PokerHand import *

class Table(Gui):
    """A Table displays a green canvas and a control area.
    By default, all tables share a common deck."""

    def __init__(self, deck=Deck()):
        Gui.__init__(self)
        self.cardset = None            # the images used to display cards
        self.deck = deck               # the deck
        self.views = {}                # mapping from Hands to HandViews
        self.transforms = []
        self.setup()

    def setup(self):
        self.ca_width = 100
        self.ca_height = 100
        
        # left frame
        self.row()
        self.canvas = self.ca(width=self.ca_width, height=self.ca_height,
                              bg='dark green', transforms=[])

        # right frame
        self.col([1,1,1])
        self.bu('Quit', command=self.quit)
        self.bu('Deal', command=self.deal_hands)
        self.bu('Print', command=self.canvas.dump)

    def set_cardset(self, cardset, numhands=6, numcards=9):
        """associate a cardset with this table, which has the
        effect of changing the size of the canvas and setting
        up the coordinate Transform"""
        self.cardset = cardset
        width = self.cardset.width
        height = self.cardset.height
        self.canvas.add_transform(TableTransform(width, height))
        self.canvas.configure(width=width*numcards, height=height*numhands)

    def deal_hands(self, nhands=6, ncards=7):
        """deal the cards and display them on the canvas,
        storing the Hands and HandViews in self.views"""

        # if there are old HandViews, get rid of them
        if len(self.views) != 0:
            self.clear()

        # make a new deck and shuffle
        deck = Deck()
        deck.shuffle()

        # deal the cards and display each Hand
        for i in range(nhands):
            hand = PokerHand()
            deck.move_cards(hand, ncards)

            # classify the hand.
            # this version only checks for flushes
            if hand.has_flush():
                hand.label = 'flush'
                
            view = HandView(hand, self)
            view.draw(0, i)
            self.views[hand] = view

    def clear(self):
        """delete the graphical representation of the HandViews,
        then delete the HandViews"""
        for view in self.views.values():
            view.delete()
        self.views = {}


class TableTransform(Transform):
    """transform coordinates so that the x-axis is in units of card widths
    and the y-axis is in units of card heights.  The origin is in the
    upper left corner, and the y-axis points down."""

    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def trans(self, p):
        x = p[0] * self.width
        y = p[1] * self.height
        return [x, y]


class Cardset(dict):
    """a cardset is a dictionary that maps a tuple (suit,rank) onto
    an Image that depicts the card.  In addition, the dictionary
    contains a key 'back' that maps to an Image that depicts the
    back of the card"""

    def __init__(self, dir=None, ext='gif'):
        """create a cardset, reading cards from the given directory"""
        dict.__init__(self)
        if dir:
            self.read_cards(dir, ext)

    def read_cards(self, dir, ext='gif'):
        suits = 'cdhs'
        for rank in range(1,14):
            for suit in range(4):
                filename = '%s/%.2d%s.%s' % (dir, rank, suits[suit], ext)
                image = PhotoImage(file=filename)
                self[suit,rank] = image

        filename = '%s/back01.gif' % (dir)
        try:
            image = PhotoImage(file=filename)
            self['back'] = image
        except:
            pass

        # cardset keeps track of the width and height of the cards
        self.width = image.width()
        self.height = image.height()

    def lookup(self, card):
        """lookup the given card and return the Image that depicts it"""
        return self[card.suit, card.rank]

class HandView:
    """a HandView object represents a Hand being displayed on a Table"""
    
    def __init__(self, hand, table):
        self.hand = hand
        self.table = table

    def draw(self, x=0, y=0):
        """draw the hand at the given location on the table.
        the Tk tag for this item is a string based on the object id"""

        self.tag = 'HandView%d' % id(self)
        cardset = self.table.cardset
        width = cardset.width
        height = cardset.height
        for card in self.hand.cards:
            self.draw_card(card, x, y)
            x += 1

        # display the hand's label next to the hand
        self.table.canvas.text([x, y], self.hand.label,
                               fill='white', anchor=NW, tag=self.tag)

    def draw_card(self, card, x, y):
        """draw a single card at the given position"""
        image = self.table.cardset.lookup(card)
        self.table.canvas.image([x, y], image, anchor=NW, tag=self.tag)

    def move(self, dx=0, dy=0):
        """move the entire handset right by dx and down by dy"""
        self.table.move_item(self.tag, dx, dy)

    def delete(self):
        """remove the graphical representation of this HandView"""
        self.table.canvas.delete(self.tag)

    
def main(name, cardstyle='tuxedo', *args):
    table = Table()
    cardset = Cardset('cardsets/cardset-' + cardstyle)
    table.set_cardset(cardset)    
    table.mainloop()
    
if __name__ == '__main__':
    main(*sys.argv)


