"""
Knight Rider

Written by: PetePriority
(basically just a modified non-blocking version of ledfx.kitt)

"""

import leds
import ledfx
import utime
import math
import buttons

class KnightRider:
    def __init__(self,
        enabled=False,
        delay=80,
        power=10,
        minimum=0.3,
        rgb=[255,0,0],
        spectrum=[],
        halo=False
    ):
        self.delay = delay
        self.power = power
        self.minimum = minimum
        self.rgb = rgb
        self.spectrum = spectrum
        self.halo = halo

        self.kitt_table = [((-math.cos(math.pi * (x / 10.0))) + 1) / 2.0 for x in range(21)]
        self.kitt_table = [math.pow(x, power) * (1 - minimum) + minimum for x in self.kitt_table]

        self.cycle = 0

        self.enabled = enabled

        leds.clear()
        leds.set_rocket(0, 0)
        leds.set_rocket(1, 0)
        leds.set_rocket(2, 0)

    def toggle_enabled(self):
        self.enabled = not self.enabled
        leds.clear()

    def toggle_halo(self):
        if self.halo:
            self.halo = False
            leds.clear()
        else:
            self.halo = ledfx.halo

    def cycle_speeds(self):
        self.delay = (self.delay + 20) % 120

    def work(self):
        if not self.enabled:
            return
        j = self.cycle
        if self.cycle > 10:
            j = 20 - self.cycle

        if self.spectrum == []:
            used_leds = 11
            # set the color values to the LEDs by multiplying the given color
            # value with the corresponding brightness value in the kitt table
            output = [[int(x * y) for y in self.rgb] for x in self.kitt_table[j : (j + used_leds)]]
        else:
            used_leds = len(spectrum)

            # multiply the color values in the corresponding spectrum tuple
            # with the brightness value in the kitt table
            output = [
                [int(y * self.kitt_table[j + x]) for y in spectrum[x]]
                for x in range(used_leds)
            ]

        if self.halo:
            self.halo(output)

        leds.set_all(output)
        utime.sleep_ms(self.delay)

        self.cycle = (self.cycle + 1) % 20