#! /usr/bin/env python3

"""draw a cellular automaton"""

import time
import math
import sys

sys.path.append('../emergent-behavior')
from simple_ca import *
from draw_ca import *

## we use the tkinter widget set; this seems to come automatically
## with python3 on ubuntu 16.04, but on some systems one might need to
## install a package with a name like python3-tk
from tkinter import *

pause_state = True              # paused state
current_row_counter = None
current_row = None
ca_canvas = None
rule = None
global n_steps

def main():
    global pause_state
    global current_row_counter
    global current_row
    global ca_canvas
    global n_steps
    global rule

    # this state dictionary is for a coming improvement where I don't
    # use those global variables
    state = {'pause' : False,
             'row_no' : 1,
             }

    rule = pick_rule()

    n_steps = 200
    n_cells = 200
    canvas_width = 4*n_cells
    canvas_height = 4*n_steps

    root = Tk()
    ## put the three control buttons
    buttonFrame = Frame(root)
    buttonFrame.pack()
    restartButton = Button(buttonFrame, text='restart', command=restart)
    restartButton.pack(side=LEFT)
    pause_resumeButton = Button(buttonFrame, text='pause/resume', command=pause_resume)
    pause_resumeButton.pack(side=LEFT)
    stepButton = Button(buttonFrame, text='step', command=step)
    stepButton.pack(side=LEFT)
    ## a separator; in old tkinter versions you do this with a skinny frame
    separator = Frame(height=2, bd=1, relief=SUNKEN)
    separator.pack(fill=X, padx=5, pady=5)
    ## the canvas
    ca_canvas = Canvas(root, 
                       width=canvas_width,
                       height=canvas_height)
    ca_canvas.pack() # boiler-plate: we always call pack() on tk windows

    current_row_counter = 0
    current_row = set_first_row_random(n_cells)
    # row = set_first_row_specific_points(n_cells, [40])
    # row = set_first_row_specific_points(n_cells, [12, 40, 51, 52, 60, 110, 111,
    #                                               160, 161, 162, 163, 164, 165,
    #                                               166, 167, 168, 169, 170, 171, 177])
    # row = set_first_row_specific_points(n_cells, list(range(int(n_cells/2), n_cells)))
    # row = set_first_row_specific_points(n_cells, [12, 13, 50, 51, 70, 71, 99, 100])
    draw_row(ca_canvas, 0, current_row)
    mainloop()

def pick_rule():
    ## now set the rule
    # rule = '01101000'           # the basic rule
    # rule = '00011110'           # the famous rule 30
    rule = '01101110'           # the famous rule 110
    return rule

def draw_row(w, pos, row):    
    color_map = ['black', 'white', 'red', 'green', 'blue', 'yellow']
    for i, cell in enumerate(row):
        color = color_map[cell % len(color_map)]
        w.create_rectangle(4*i, 4*pos, 4*i+4, 4*pos+4, fill=color)
        ## update the canvas
        # if i % 10 == 0:
        #     w.update()
    w.update()

def update_canvas():
    """updates the canvas, then schedules another updating of it (as long
    as we are not yet done)"""
    global pause_state
    global current_row_counter
    if not pause_state:
        step()
    if current_row_counter < (n_steps-1):
        ca_canvas.after(10, update_canvas)
    else:                       # we've reached the end
        current_row_counter = 0
        pause_state = True
        print('done')

def restart():
    global pause_state
    global current_row_counter
    
    print('restarting')
    current_row_counter = 0
    pause_state = False
    update_canvas()

def pause_resume():
    global pause_state
    if pause_state:
        print('resuming')
        pause_state = False
        update_canvas()
    else:
        print('pausing')
        pause_state = True

def step():
    global current_row
    global current_row_counter
    current_row = take_step(rule, current_row)
    draw_row(ca_canvas, current_row_counter, current_row)
    current_row_counter += 1

main()
