# L-34 MCS 260 Wed 6 Apr 2016 : life.py
"""
GUI for Conway's game of life
"""

from tkinter import Tk, Scale, Canvas, Button, Label
from tkinter import IntVar, W, E, N, S, ALL
import game

class GameOfLife(object):
    """
    GUI to the game of life
    """
    def __init__(self, wdw, r, c, m, delay):
        """
        The GUI consists of a canvas, scale, start and stop button.
        The scale controls the speed of the animation, initialized
        by the variable delay on input.
        On canvas there are r rows and c columns of squares of size m.
        """
        wdw.title('the game of life')
        self.rows = r      # number of rows on canvas
        self.cols = c      # number of columns on canvas
        self.size = m      # size of the squares on canvas
        self.dly = IntVar()
        self.grow = False  # state of the animation
        self.grid = []
        self.scl = Scale(wdw, orient='horizontal', \
            from_=0, to=300, tickinterval=50, resolution=1, \
            length=self.cols, variable=self.dly)
        self.scl.grid(row=0, column=0, columnspan=2, sticky=W+E+N+S)
        self.scl.set(delay)
        self.cnv = Canvas(wdw, width=m*self.cols+2*m, \
            height=m*self. rows+2*m, bg='white')
        self.lbl = Label(wdw, text="scale controls the delay time")
        self.lbl.grid(row=1, column=0, columnspan=2)
        self.cnv.grid(row=2, column=0, columnspan=2)
        self.bt0 = Button(wdw, text='start', command=self.start)
        self.bt0.grid(row=3, column=0, sticky=W+E)
        self.bt1 = Button(wdw, text='stop', command=self.stop)
        self.bt1.grid(row=3, column=1, sticky=W+E)

    def draw_cells(self):
        """
        Draws the cells on canvas.
        """
        msz = self.size
        self.cnv.delete(ALL)
        for i in range(self.rows):
            for j in range(self.cols):
                if self.grid[i][j]:
                    (xpt, ypt) = (msz*(j + 1), msz*(i + 1))
                    self.cnv.create_rectangle(xpt, ypt, \
                        xpt+msz, ypt+msz, fill="green")

    def animate(self):
        """
        Performs the animation.
        """
        while self.grow:
            self.grid = game.update(self.grid)
            self.cnv.after(self.dly.get())
            self.draw_cells()
            self.cnv.update()

    def start(self):
        """
        At the start of the animation, a random configuration
        of cells is generated and the animate method is called.
        """
        self.grid = game.random_grid(self.rows, self.cols)
        self.grow = True
        self.draw_cells()
        self.animate()

    def stop(self):
        """
        Stops the animation.
        """
        self.grow = False

def main():
    """
    Sets the dimensions of the canvas,
    number of rows, columns, and size of squares,
    before launching the main event loop of the GUI.
    """
    top = Tk()
    # rraw = raw_input('Give number of rows (e.g. 40) : ')
    # craw = raw_input('Give number of columns (e.g. 80) : ')
    # mraw = raw_input('Give size of squares (e.g. 10) : ')
    # (row, col, msz) = (int(rraw), int(craw), int(mraw))
    (row, col, msz) = (40, 80, 10)
    dly = 60  # delay for next frame
    GameOfLife(top, row, col, msz, dly)
    top.mainloop()

if __name__ == "__main__":
    main()
