from uib_inf100_graphics.event_app import run_app


## Modell 

def app_started(app):
    app.rows = 25
    app.cols = 40
    app.margin = 50 # margin rundt rutenettet
    app.board = []
    for row in range(app.rows):
        new_row = []
        for col in range(app.cols):
            new_row.append(False)
        app.board.append(new_row)
    app.play = False


def generate_board(app):
    return [[False] * app.cols for row in range(app.rows)]
    

def live_neighbors(app, row, col):
    # tell hvor mange naboer som har True verdi
    count = 0
    
    for neighbor_row in range(row-1, row+2):
        for neighbor_col in range(col-1, col+2):
            if (neighbor_row == row) and (neighbor_col == col):
                continue
            if not cell_in_grid(app, neighbor_row, neighbor_col):
                continue
            
            if app.board[neighbor_row][neighbor_col]:
                count += 1
    
    return count
                
    
def update(app):
    # utfør reglene for modellen
    new_board = [[app.board[row][col] for col in range(app.cols)] for row in range(app.rows)] # kopi
    
    for row in range(app.rows):
        for col in range(app.cols):
            living_neighbors = live_neighbors(app, row, col)
            
            if app.board[row][col]: # hvis du lever
                # 1
                if living_neighbors < 2:
                    new_board[row][col] = False
                # 2
                elif 2 <= living_neighbors <= 3:
                    new_board[row][col] = True
                # 3
                else:
                    new_board[row][col] = False
            
            else:
                # 4
                if living_neighbors == 3:
                    new_board[row][col] = True
    
    app.board = new_board


# kontroller

def timer_fired(app):
    if app.play:
        update(app)


def board_cell_pressed(app, row, col):
    # håndter et trykk på en celle på brettet
    # (gjøre cellen aktiv hvis død, og død hvis aktiv)
    
    app.board[row][col] = not app.board[row][col] # oppdater bool verdi


def mouse_pressed(app, event):
    (row, col) = get_cell(app, event.x, event.y)
    # velg denne ruten med mindre den allerede er valgt
    if not (row < 0 and col < 0):
        board_cell_pressed(app, row, col)

def key_pressed(app, event):
    key = event.key
    if key == 'p':
        app.play = not app.play
    if key == 'r':
        app.play = False
        app.board = generate_board(app)
        

# visning

def point_in_grid(app, x, y):
    # returner True hvis piksel-koordinatet (x, y) er på innsiden av
    # rutenettet slik det blir tegnet i visningen.
    return ((app.margin <= x <= app.width-app.margin) and
            (app.margin <= y <= app.height-app.margin))
    
    
def cell_in_grid(app, row, col):
    # returner True hvis (row,col)-koordinatet er på innsiden av
    # rutenettet slik det er i modellen.
    return ((0 <= row < app.rows) and
            (0 <= col < app.cols))


def get_cell(app, x, y):
    # "visning-til-modell"
    # returnerer (row, col) for ruten hvor piksel-koordnatet (x, y) hører
    # hjemme, eller (-1, -1) hvis koodinatet er utenfor rutenettet
    if (not point_in_grid(app, x, y)):
        return (-1, -1)
    grid_width  = app.width - 2*app.margin
    grid_height = app.height - 2*app.margin
    cell_width  = grid_width / app.cols
    cell_height = grid_height / app.rows

    # Merk: vi trenger å konvertere til int her; det er ikke 
    # tilstrekkelig å benytte //, siden x, y, eller app.margin kan
    # være flyttall, og da vil også // returnere flyttall
    row = int((y - app.margin) / cell_height)
    col = int((x - app.margin) / cell_width)

    return (row, col)

def get_cell_bounds(app, row, col):
    # "modell-til-visning"
    # returnerer (x0, y0, x1, y1), piksel-koordinater for hjørnene til
    # den gitte ruten
    grid_width  = app.width - 2*app.margin
    grid_height = app.height - 2*app.margin
    column_width = grid_width / app.cols
    row_height = grid_height / app.rows
    x0 = app.margin + col * column_width
    x1 = app.margin + (col+1) * column_width
    y0 = app.margin + row * row_height
    y1 = app.margin + (row+1) * row_height
    return (x0, y0, x1, y1)

def redraw_all(app, canvas):
    # tegn alle rutene
    for row in range(app.rows):
        for col in range(app.cols):
            (x0, y0, x1, y1) = get_cell_bounds(app, row, col)
            
            fill = "black" if (app.board[row][col]) else "white"
            canvas.create_rectangle(x0, y0, x1, y1, fill=fill)
    canvas.create_text(app.width/2, app.height/2, text="Klikk på rutene!",
                       font="Arial 20 bold", fill="darkBlue")
    

        

run_app(width=1200, height=800)
