
"""The controller module contains the class for the slide button.

   About the solution strategy: when a SlideButton is pressed,
   the button's  handle  function asks the PuzzleModel to move the
   number on the button's face into the empty space.  Once this is 
   accomplished, the button's face should be repainted as the empty space.

   But, there is one last job:  the button that represented the former
   empty space must be repainted, too, to show that a number has moved
   into that button's space on the grid!   How should we code this?
   
   The solution given below remembers the button that was the empty space
   and repaints it.
"""

from Tkinter import *

import PuzzleModel # the slide puzzle

total_moves = 0    # how many moves the player has used

empty_space = ""   # remembers which button is the empty space (0-button)

class Controller(Button) :
    """Controller constructs the handler functions for a slide button.
       Attributes:
          mybutton - the button connected to this controller
          myrow - the button's row position in the grid
          mycolumn - its button's column position in the grid
    """

    def __init__(self, but, row, column) :
        """init  constructs the button, by calling  Button.

           parameters:  self - the new object we are constructing
                        but - the button connected to this controller
                        row - the button's row position in the grid
                        column - the button's column position in the grid
        """
        global empty_space
        # remember the attributes:
        self.myrow = row
        self.mycolumn = column
        self.mybutton = but
        # paint the number on the button:
        self.paint()
        my_number = PuzzleModel.getValueAt(self.myrow, self.mycolumn)
        if my_number == 0 :   # is this button the empty space ?
            empty_space = self

    def handle(self) :
        """This is the event handler for the button: It tries to 
           move the number on the button into the empty space and
           then it repaints the entire slide puzzle.
           It also increments the  total_moves  variable.
        """
        global empty_space, total_moves
        # try to move the number:
        move_OK = PuzzleModel.moveAt(self.myrow, self.mycolumn)
        if move_OK :
            empty_space.paint()  # repaint former empty space with its number
            self.paint()  # repaint ourself to be the new empty space
            empty_space = self # remember the location of the new empty space
        total_moves = total_moves + 1
        print "total moves =", total_moves

    def paint(self) :
        """paint  paints the current puzzle number onto the button's face"""
        my_number = PuzzleModel.getValueAt(self.myrow, self.mycolumn)
        self.mybutton.configure(text = str(my_number))
        if my_number == 0 :   # is it the empty space ?
            self.mybutton.configure(bg = "blue")   # hide the blue 0 within a blue bg
        else :
            self.mybutton.configure(bg = "white")

