"""
A board is a 2D list containing Booleans. A "shape" is a nested
tuple, where the real world shape is represented as Trues. For example, an "L"
shape could be represented as 

   shape = ((False, False, True),(True, True, True))
"""

from draw_packing import *
import time
import random

class Board:
    """
    squares is a 2D list containing Booleans.
    """
    def __init__(self, rows, cols, squares):
        """
        Board constructor
        """

    def update(self, shape, game):
        """
        Top-level def for placing a single shape on board. Finds best
        position and rotation for shape, update
        board squares.
        Calls: find_best_place rotate90 
        Returns tuple:  (fits board) boolean and board
        """

    def find_best_place(self, shape):
        """
        Takes a single shape, finds best position on self. Tries original and 
        three possible 90 degree rotations. Mutates shape.
        Returns tuple:  (fits, max_score_row, max_score_col, num_rotations)
        fits: bool
        max_score_row, max_score_col: upper left coordinates of best position
        for shape on board num_rotations: 0-3 rotations required for best fit.
        Calls: find_one_place, Shape.rotate90
        """

    def find_one_place(self, shape):
        """
        Takes a single shape in one position and finds the best fit on the
        board. If two fits are the same, then it defaults to the lowest,
        rightmost position on the board. 
        Returns a tuple:  (fits, best_row, best_col score)
        fits: bool
        best_row, best_col: upper left coordinates of best position for shape
        on self
        score: fill, or other heuristic. Higher is better.
        Calls: fit
        """ 

    def fit(self, upleft_Row, upleft_Col, shape):
        """
        upleft_Row, upleft_Col are upper left coordinates of position we wish to
        fit shape on self.
        Returns tuple: (it_fits, fill) where it_fits is true if the shape fits
        in the specified location on the board;  fill is the amount of
        "fill" the shape has with other filled space on the board (that is, 
        where a zero in the shape lines up with a one on the board). 
        """

class Shape:
    """
    A "shape" is a nested tuple, where the real world shape is
    represented as Trues. For example, an "L" shape could be
    represented as

    shape = ((False, False, True),(True, True, True))
    """
    def __init__(self, letter, squares, color):
        """
        Shape constructor
        """

    def rotate90(self):
        """
        Rotates self 90 degrees clockwise (yes, direction matters).
        Returns: None
        """
        self.squares = tuple(apply(zip, self.squares[::-1]))
        self.rotations = (self.rotations + 1) % 4

    def show_and_rotate(self, num_rotations, game):
        """
        Draws shape  and shows it rotating to correct orientation
        with a brief pause at each orientation.
        Calls: Game.draw_shape, rotate90
        Returns: None
        """

def get_shape(letter):
    """
    Returns the shape corresponding to the letter parameter: I, J, L, O, S, T, 
    or Z.
    """

def start(rows, cols):
    """
    Makes a blank Board of size rows by cols, makes a corresponding Game on
    which to draw the game happening, seeds the random number generator,
    schedules run, and starts the event loop.
    Calls: run (via Game.after)
    Returns: None
    """

def run(board, shapes, game):
    """
    Repeatedly generates a new shape and then fits that shape on the current
    board.  On each pass, the new shape should be shown in the upper left
    corner of the board, then rotated to the appropriate orientation (the
    rotation should be animated to show each step,) and finally placed in
    the appropriate location on the board.
    calls: get_shape, Game.draw_game_board, Board.update.
    """

if __name__ == '__main__':
    start(22,10) # You can make a board of whatever size you wish.  Here's an
                 # idea to get you started.  (The standard Tetris board size is
                 # 22 by 10.
