"""
build rainbow
attach hardware to controller
launch the rainbow attack
"""
import math
import time
import badge
import ugfx
#import deepsleep

#import time
#from random import randint, random
#import sys


def go_home():
    print("go_home")
    import machine
    machine.deepsleep(1)


def hardware_init():
    print("hardware_init inprogress")
    badge.init()
    ugfx.init()
    ugfx.input_init()
    badge.leds_init()
    badge.leds_enable()
    print("hardware_init done")


class LedsController:
    def __init__(self, set_color_bytes, err_handler):
        print("LedsController.__init__")
        self.leds_init()
        self.set_color_bytes = set_color_bytes
        self.err_handler = err_handler

    def leds_init(self):
        self.leds = []
        for _ in range(6):
            self.leds.append([0, 0, 0, 0])


    def show_leds(self):
        try:
            # sum() doesnt work
            leds_data = bytes(self.leds[0] + 
                self.leds[1] + 
                self.leds[2] + 
                self.leds[3] + 
                self.leds[4] + 
                self.leds[5]) 
            
            self.set_color_bytes(leds_data)

        except Exception as e:
            self.err_handler(e)




def press_exit_handler(e):
    print("press_exit_handler: " + str(e))
    if e:
        go_home()
    else:
        show_error(e)

def attach_exit_handlers():
    print("attach_exit_handlers inprogress")
    ugfx.input_attach(ugfx.BTN_B, press_exit_handler)
    print("attach_exit_handlers done")

def show_error(err):
    print("show_error: " + str(err))
    ugfx.set_lut(ugfx.LUT_NORMAL)
    ugfx.clear(ugfx.WHITE)
    ugfx.string(10, 10, str(err), "Roboto_Regular12", 0)
    ugfx.flush()

def show_splash():
    print("show_splash")
    ugfx.set_lut(ugfx.LUT_NORMAL)
    ugfx.clear(ugfx.WHITE)
    ugfx.string(10, 10, str("FIXME: place unicors and rainbows here"), "Roboto_Regular12", 0)
    ugfx.flush()

def get_rainbow_piece(size, index):
    k = math.pi * 2 / size
    r = math.sin(index * k)
    r = r * r * 255.99999
    r = math.floor(r)
    g = math.sin(index * k + math.pi * 2/3)
    g = g * g * 255.99999
    g = math.floor(g)
    b = math.sin(index * k + math.pi * 4/3)
    b = b * b * 255.99999
    b = math.floor(b)
    return [int(r), int(g), int(b), int(0)]


def main():
    print("shaUnicornAttack launched")
    hardware_init()
    show_splash()
    attach_exit_handlers()
    lc = LedsController(badge.leds_send_data, show_error)
    
    rainbow_len = 300
    leds_gap = 15
    rainbow_state = 0

    while True:

        for i in range(6):
            led_state = (rainbow_state + i*leds_gap) % rainbow_len
            lc.leds[i] = get_rainbow_piece(rainbow_len, led_state)
        
        lc.show_leds()
        rainbow_state = (rainbow_state + 1) % rainbow_len

        time.sleep_ms(10)

try:
    main()
except Exception as e:
    show_error(e)