import buttons
import leds
import display
import utime
import color

_rand = utime.localtime()[5]


def rand():
    global _rand
    _rand = (1103515245 * _rand + 12345) & 0xFFFFFF
    return _rand



BUTTON_SEL = 1 << 0
BUTTON_UP = 1 << 1
BUTTON_DOWN = 1 << 2
BUTTON_SEL_LONG = 1 << 3
BUTTON_UP_LONG = 1 << 4
BUTTON_DOWN_LONG = 1 << 5
pressed_prev = 0
button_sel_time = 0
button_up_time = 0
button_down_time = 0
def checkButtons():
    global pressed_prev, button_sel_time, button_up_time, button_down_time
    t = utime.time()
    pressed = buttons.read(buttons.BOTTOM_LEFT | buttons.TOP_RIGHT | buttons.BOTTOM_RIGHT)
    cur_buttons = 0
    if pressed & buttons.BOTTOM_LEFT and not pressed_prev & buttons.BOTTOM_LEFT:
        button_sel_time = t
    elif not pressed & buttons.BOTTOM_LEFT and pressed_prev & buttons.BOTTOM_LEFT:
        if button_sel_time < t:
            cur_buttons |= BUTTON_SEL_LONG
        else:
            cur_buttons |= BUTTON_SEL
    if pressed & buttons.TOP_RIGHT and not pressed_prev & buttons.TOP_RIGHT:
        button_sel_time = t
    elif not pressed & buttons.TOP_RIGHT and pressed_prev & buttons.TOP_RIGHT:
        if button_sel_time < t:
            cur_buttons |= BUTTON_UP_LONG
        else:
            cur_buttons |= BUTTON_UP
    if pressed & buttons.BOTTOM_RIGHT and not pressed_prev & buttons.BOTTOM_RIGHT:
        button_sel_time = t
    elif not pressed & buttons.BOTTOM_RIGHT and pressed_prev & buttons.BOTTOM_RIGHT:
        if button_sel_time < t:
            cur_buttons |= BUTTON_DOWN_LONG
        else:
            cur_buttons |= BUTTON_DOWN
    pressed_prev = pressed
    return cur_buttons


col = color.WHITE
time = 0
f_x = 20
f_y = 35
f_vy = 0
jump_vy = -0.9
g = 0.08
size = 6
tubes = []
tubesize = 12
t_halfheight = 10
score = 0


def check_intersect(x1, y1, x2, y2):
    if f_x > x2 - time or f_x + size < x1 - time: return False
    if f_y > y2 or f_y + size < y1: return False
    return True

def draw_score():
    ohm = [color.BLUE] * 15
    for i in range(8):
        if score & (1 << i):
            ohm[i] = color.RED
    leds.set_all(ohm)

def intersect_tubes():
    global score, time
    for e,t in enumerate(tubes):
        if f_x > (t[0] + tubesize - time): 
            score = max(score, e + 1)
        if check_intersect(t[0], 0, t[0] + tubesize, t[1] - t_halfheight) or check_intersect(t[0], t[1] + t_halfheight, t[0] + tubesize, 160):
            return True
    draw_score()
    return False



def gen_tubes():
    global tubes
    tubes = []
    for i in range(64):
        posx = 100 + 50*i + (rand() % 30) - 15
        height = 40 + (rand() % 60) - 30
        tubes += [(posx, height)]

def draw_tubes(d):
    global time
    for t in tubes:
        if t[0] + tubesize < time: continue
        if t[0] > time + 160: break
        s_x = max(t[0] - time, 0)
        s_X = min(t[0] - time + tubesize, 159)
        d.rect(s_x, 0, s_X, t[1] - t_halfheight, col=color.GREEN)
        d.rect(s_x, t[1] + t_halfheight, s_X, 80, col=color.GREEN)

def game_over(d):
    text = ["git gud", "fascist", "u dead", "x_x", "fix me", "you lose", 
            "panic", "the cops!", "fuzz me", "kill me", "free me", "u suck", 
            "u snitch", "stop", "STOP", "u ok?", "lol", "nazist", 
            "come on", "try more", "shit", "oops", "omg", "go rage",
            "time2quit", "install\ngentoo", "poop", " :(){:|:&};:", "wtf boom",
            "oh my\ngod", "please\nstop", "script\nkiddie", "u done\ngoofin",
            "i'm so\nsorry", "play\nmore", "you\nd e a d", "run\narchlinux",
            "fuck\ngoogle", "fuck\ncomputers", "run\nbarrelfish", "go get\na joint",
            "go get\na beer", "let's go\nprimitive", "punch\nyourself",
            "not funny", "you are\nboring", "rm -rf /", "sudo\nkill -9 1",
            "shut me\ndown"]
    tt = text[rand() % len(text)]
    if '\n' in tt:
        ttt = tt.split('\n')
        d.print(ttt[0], posx= 80 - len(ttt[0])*7, posy=20)
        d.print(ttt[1], posx= 80 - len(ttt[1])*7, posy=40)
    else:
        d.print(tt, posx= 80 - len(tt)*7, posy=30)
    d.update()


def update(bs, d):
    global col, time, f_y, f_vy
    d.rect(0, 0, 160, 80, col=color.BLACK) # clean screen (to do: faster)
# 
    if bs & BUTTON_UP or bs & BUTTON_DOWN:
        f_vy = min(jump_vy, f_vy + jump_vy)
        # col = color.BLUE
#
    if f_y < 0 or f_y + size >= 79: 
        return False
    if intersect_tubes():
        return False
#
    f_y += f_vy
    f_vy += g
#
    r_y = f_y
#
    d.rect(f_x, int(r_y), f_x+size, int(r_y) + size, col=col)
    draw_tubes(d)
    time += 1
    return True

def render(d):
    d.update()


def loop(d):
    gen_tubes()
    global f_y, f_vy, score, time, tubes
    f_y = 35
    f_vy = 0
    score = 0
    time = 0
    while True:
        bs = checkButtons()
        if not update(bs, d):
            game_over(d)
            utime.sleep(3)
            return
        render(d)

def main():
    try:
        with display.open() as d:
            while True:
                loop(d)
    except KeyboardInterrupt:
        pass

main()
