# Tic Tac Toe board class
"""Extends the Board class with specific features
required for Tic Tac Toe"""

# import modules and classes
from graphics import *
from tttcube import TTTCube
from board import Board

class TTTBoard(Board):
    """TTT Board class implements the functionality of a
    Tic Tac Toe board. It inherits from the Board class and
    extends it by creating a grid of TTTLetters."""

    # inherits _grid made up of _rows and _cols and other graphical attributes
    # new attribute:  _cubes (list of TTTCubes)
    __slots__ = ['_cubes']
    

    def __init__(self, win):
        """Initializes a Tic-tac-toe board with an empty grid"""
        # call Board init with appropriate TTT grid size
        super().__init__(win, rows=3, cols=3)

        # initialize new attribute to build 2-D list
        # of TTTCubes
        self._cubes = []
        for row in range(self._rows):
            cube_row = []
            for col in range(self._cols):
                # add TTTCube to row
                cube_row.append(TTTCube())

            # add column to grid
            self._cubes.append(cube_row)

        # display the cubes on the board
        self.place_cubes_on_board()

    def get_ttt_cube_at_point(self, point):
        """Returns the TTTCube at point on window (a screen coord tuple)"""
        if self.in_grid(point):
            # get_position returns grid coords as a (row,col) pair
            (row, col) = self.get_position(point)
            return self._cubes[row][col]
        return None

    def place_cubes_on_board(self):
        '''Updates the board to display the letters on TTTCubes'''
        for row in range(self._rows):
            for col in range(self._cols):
                cube = self._cubes[row][col]
                # if letter is unchanged, this has no effect
                self.set_grid_cell(row, col, cube.get_letter())
        
    def reset(self):
        """Clears the TTT board by clearing letters and colors on grid"""

        # first update cube letters, then make the grid's graphics
        # reflect the state of the reset cubes
        for x in range(self._rows):
            for y in range(self._cols):
                self._cubes[x][y].set_letter("")
        self.place_cubes_on_board()
                
    def _check_rows(self, letter):
        """Check rows for a win (3 in a row)."""
        for row in range(self._rows):
            count = 0
            for col in range(self._cols):
                cube = self._cubes[row][col]

                # check how many times letter appears
                if cube.get_letter() == letter:
                    count +=1

            # if this is a winning row
            if count == self._cols:
                return True

        # no winning row found
        return False

    def _check_cols(self, letter):
        """Check columns for a win (3 in a row)."""
        for col in range(self._cols):
            count = 0
            for row in range(self._rows):
                cube = self._cubes[row][col]

                # check how many times letter appears
                if cube.get_letter() == letter:
                    count +=1

            # if this is a winning col
            if count == self._rows:
                return True

        # if no winning cols
        return False

    def _check_diagonals(self, letter):
        """Check diagonals for a win (3 in a row)."""
        # counts for primary and secondary diagonal
        count_primary = 0
        count_second = 0

        for col in range(self._cols):
            for row in range(self._rows):
                cube = self._cubes[col][row]

                # update count for primary diagonal
                if (row == col and cube.get_letter() == letter):
                    count_primary += 1

                # update count for secondary diagonal
                if (row + col == self._rows - 1 and cube.get_letter() == letter):
                    count_second += 1

        # return true if either return in win
        return count_primary == self.get_rows() or count_second == self.get_rows()


    def check_for_win(self, letter):
        """Check board for a win."""
        row_win = self._check_rows(letter)
        col_win = self._check_cols(letter)
        diag_win = self._check_diagonals(letter)

        return row_win or col_win or diag_win

if __name__ == "__main__":
    win = GraphWin("Tic-Tac-Toe", 400, 400)
    board = TTTBoard(win)
    print(board)

    board.draw_board()

    keep_going = True
    while keep_going:
        point = win.getMouse()
        print("Clicked point {}".format(point))
        if board.in_grid(point):
            position = board.get_position(point)
            print("\t{} -> {}".format(point, position))
        elif board.in_exit(point):
            keep_going = False