#!/usr/bin/python

from Gui import *
from Card import *
from time import sleep
from copy import copy
import Tkinter

# A Table displays a green canvas and a control area.
# By default, all tables share a common deck.
class Table(Gui):
    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()

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

    # set up the GUI elements for
    def setup(self):
        self.ca_width = 500
        self.ca_height = 400
        
        # left frame
        self.fr(LEFT)
        self.canvas = self.ca(width=self.ca_width, height=self.ca_height,
                              bg='dark green')
        self.endfr()

        # right frame
        self.fr(LEFT, fill=BOTH, expand=1)
        self.bu(TOP, text='Quit', command=self.quit)
        self.bu(TOP, text='Deal', command=self.deal)
        self.bu(TOP, text='Print', command=self.print_canvas)
        self.endfr()

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

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

        # make a copy of the deck, which shares the old
        # set of cards
        deck = Deck(self.deck)
        deck.shuffle()

        # deal the cards and display each Hand
        for i in range(nhands):
            hand = PokerHand()
            deck.deal(hand, ncards)
            if hand.has_flush():
                hand.label = 'flush'
            view = HandView(hand, self)
            view.draw(0, i)
            self.views[hand] = view

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


# 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.
class TableTransform(Transform):
    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]


# 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
class Cardset(dict):

    # create a cardset, reading cards from the given directory
    def __init__(self, dir=None, ext='gif'):
        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()

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

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

    # draw the hand at the given location on the table
    def draw(self, x=0, y=0):
        # 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.create_text([x, y], self.hand.label,
                               fill='white', anchor=NW, tag=self.tag)

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

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

    # remove the graphical representation of this HandView
    def delete(self):
        self.table.delete_item(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)


