import rgb
import time
import buttons
import defines
import random


#important i guess
play_area_x = 24
play_area_y = 8
offset_x = 8
offset_y = 0


#variables
disp_buf = [0] * (play_area_x * play_area_y)
game_buf = [0] * (play_area_x * play_area_y)
screen_brightness = 50
c_red = 0xFF000000 + screen_brightness
c_green = 0x00FF0000 + screen_brightness
c_blue = 0x0000FF00 + screen_brightness
c_yellow = 0xFFD00000 + screen_brightness
button_press = 0


def btn1(button_is_down):
    if button_is_down:
        global button_press
        button_press = 1
        pass


def btn2(button_is_down):
    if button_is_down:
        global button_press
        button_press = 2
        pass


def btn3(button_is_down):
    if button_is_down:
        global button_press
        button_press = 3
        pass


def btn4(button_is_down):
    if button_is_down:
        global button_press
        button_press = 4
        pass


def place_buttons():
    rgb.pixel((0xFF,0,0), (3,1))
    rgb.pixel((0xFF,0,0), (4,1))
    rgb.pixel((0xFF,0,0), (3,2))
    rgb.pixel((0xFF,0,0), (4,2))
    rgb.pixel((0,0xFF,0), (5,3))
    rgb.pixel((0,0xFF,0), (6,3))
    rgb.pixel((0,0xFF,0), (5,4))
    rgb.pixel((0,0xFF,0), (6,4))
    rgb.pixel((0xFF,0xD0,0), (1,3))
    rgb.pixel((0xFF,0xD0,0), (2,3))
    rgb.pixel((0xFF,0xD0,0), (1,4))
    rgb.pixel((0xFF,0xD0,0), (2,4))
    rgb.pixel((0,0,0xFF), (3,5))
    rgb.pixel((0,0,0xFF), (4,5))
    rgb.pixel((0,0,0xFF), (3,6))
    rgb.pixel((0,0,0xFF), (4,6))


def init_screen():
    for i in range(play_area_x * play_area_y):
        game_buf[i] = 0
        val = random.getrandbits(2)
        if val == 0:
            disp_buf[i] = c_red
        elif val == 1:
            disp_buf[i] = c_green
        elif val == 2:
            disp_buf[i] = c_blue
        else:
            disp_buf[i] = c_yellow
    game_buf[0] = 1
    rgb.clear()
    place_buttons()
    rgb.image(disp_buf, (offset_x, offset_y), (play_area_x, play_area_y))
    return disp_buf[0]


def set_new_color(color):
    for i in range(play_area_y):
        for j in range(play_area_x):
            if game_buf[(i * play_area_x) + j] == 1:
                disp_buf[(i * play_area_x) + j] = color
    rgb.clear()
    place_buttons()
    rgb.image(disp_buf, (offset_x, offset_y), (play_area_x, play_area_y))


def update_buf_star(x, y, color):
    # sanity check if start position is valid
    if x < 0 or x >= play_area_x:
        return -1
    if y < 0 or y >= play_area_y:
        return -1
    if game_buf[(y * play_area_x) + x] == 0:
        return -1
    # create variables
    ret = int(0)
    pos_up = int(y - 1)
    pos_down = int(y + 1)
    pos_left = int(x - 1)
    pos_right = int(x + 1)
    # up position
    if pos_up >= 0 and pos_up < play_area_y:
        if game_buf[(pos_up * play_area_x) + x] == 0:
            if disp_buf[(pos_up * play_area_x) + x] == color:
                game_buf[(pos_up * play_area_x) + x] = 1
                ret |= 1
    # down position
    if pos_down >= 0 and pos_down < play_area_y:
        if game_buf[(pos_down * play_area_x) + x] == 0:
            if disp_buf[(pos_down * play_area_x) + x] == color:
                game_buf[(pos_down * play_area_x) + x] = 1
                ret |= 2
    # left position
    if pos_left >= 0 and pos_left < play_area_x:
        if game_buf[(y * play_area_x) + pos_left] == 0:
            if disp_buf[(y * play_area_x) + pos_left] == color:
                game_buf[(y * play_area_x) + pos_left] = 1
                ret |= 4
    # right position
    if pos_right >= 0 and pos_right < play_area_x:
        if game_buf[(y * play_area_x) + pos_right] == 0:
            if disp_buf[(y * play_area_x) + pos_right] == color:
                game_buf[(y * play_area_x) + pos_right] = 1
                ret |= 8
    # all good
    return ret


def set_active_pixels(color):
    cntr = 10
    while cntr > 0:
        for i in range(play_area_y):
            for j in range(play_area_x):
                ret = update_buf_star(j, i, color)
                if ret != -1:
                    i = 0
                    j = 0
        cntr -= 1


def game_done():
    for i in range(play_area_x * play_area_y):
        if game_buf[i] == 0:
            return False
    return True
            

# register button callbacks
buttons.register(defines.BTN_UP, btn1)
buttons.register(defines.BTN_RIGHT, btn2)
buttons.register(defines.BTN_DOWN, btn3)
buttons.register(defines.BTN_LEFT, btn4)

# set the initial screen colors
c_start = init_screen()
set_active_pixels(c_start)
set_new_color(c_start)
button_counter = 0

# Main loop
while True:
    time.sleep(0.1)
    if button_press != 0:
        button_counter += 1
        new_color = 0
        if button_press == 1:
            new_color = c_red
        elif button_press == 2:
            new_color = c_green
        elif button_press == 3:
            new_color = c_blue
        elif button_press == 4:
            new_color = c_yellow
        button_press = 0
        # do things
        if new_color != 0:
            set_active_pixels(new_color)
            time.sleep(0.01)
            set_new_color(new_color)
        # game done?
        if game_done():
            # wait
            time.sleep(1)
            # show score
            rgb.clear()
            rgb.scrolltext("Score: " + str(button_counter))
            time.sleep(5)
            # run again
            c_start = init_screen()
            set_active_pixels(c_start)
            set_new_color(c_start)
            button_counter = 0