import board, time, digitalio, neopixel, touchio, adafruit_lis3dh, busio, math

# Import various colors for the LED strip
from adafruit_led_animation.color import RED, YELLOW, ORANGE, GREEN, TEAL, CYAN, BLUE, PURPLE, MAGENTA, GOLD, PINK, AQUA, JADE, AMBER, OLD_LACE, WHITE, BLACK
from adafruit_debouncer import Button  # Import Button class for debouncing touch inputs

# Initialize the NeoPixel strip
num_leds = 29  # Total number of LEDs in the strip
strip = neopixel.NeoPixel(board.A2, num_leds, brightness=0.5)  # Pin A2 for the strip and 50% initial brightness
strip.brightness = 0  # Set initial brightness to 0 (LEDs off)

# List of colors to cycle through when interacting with the LEDs
colors = [RED, ORANGE, YELLOW, GREEN, TEAL, CYAN, BLUE, PURPLE, MAGENTA, PINK]

# Setup touch inputs using touchio library and debounce them using Button
touchpad_A4_input = touchio.TouchIn(board.A4)
touchpad_A4 = Button(touchpad_A4_input, value_when_pressed=True)
touchpad_A5_input = touchio.TouchIn(board.A5)
touchpad_A5 = Button(touchpad_A5_input, value_when_pressed=True)
touchpad_A6_input = touchio.TouchIn(board.A6)
touchpad_A6 = Button(touchpad_A6_input, value_when_pressed=True)
touchpad_A7_input = touchio.TouchIn(board.TX)
touchpad_A7 = Button(touchpad_A7_input, value_when_pressed=True)

color = 0  # Start with the first color in the list

# Setup accelerometer using I2C communication
i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
int1 = digitalio.DigitalInOut(board.ACCELEROMETER_INTERRUPT)
accelerometer = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19, int1=int1)  # LIS3DH accelerometer setup
accelerometer.range = adafruit_lis3dh.RANGE_8_G  # Set accelerometer sensitivity

brightness = 0  # Initialize brightness level
active = False  # LED strip activity state
boot = False  # Boot state to control startup sequence
fill = False
toggleon = True  # Toggle state for controlling LEDs

lastinteracted = time.time() - 1000  # Tracks the last time of interaction with the system

def shutdown():
    for i in range(0, 4, 1):  # Blink LEDs between black and red
        strip.fill(BLACK)
        time.sleep(0.5)
        strip.fill(RED)
        time.sleep(0.5)

    for i in reversed(range(0, 50, 1)):  # Gradually decrease brightness
        strip.brightness = i / 100
        time.sleep(0.05)

def accel_to_led(x,y):
    if abs(x) > 2 or abs(y) > 2:
        lastinteracted = time.time()
        degrees = math.degrees(math.atan2(y,x))
        if degrees < 0:
            degrees = 180 + (180 + degrees)
        else:
            pass

        led = int((360-degrees) * 1 / 360 * 29) - 1

        if led != None:
            if led < 26:
                ledadj = led+3
            if led == 26:
                ledadj = 0
            if led == 27:
                ledadj = 1
            if led == 28:
                ledadj = 2

            strip[ledadj] = WHITE

        else:
            pass

    else:
        pass

def updatepads():
    touchpad_A4.update()
    touchpad_A5.update()
    touchpad_A6.update()
    touchpad_A7.update()

def startup():
    strip.fill(colors[color])  # Fill the strip with the current color
    for i in range(0, 50, 1):  # Gradually increase brightness
        strip.brightness = i / 100
        time.sleep(0.05)  # Short delay for smooth transition

def checkfull():
    ledswhite = 0
    for i in range(0,29,1):
        if strip[i] == WHITE:
            ledswhite += 1
        if ledswhite == 29:
            strip.fill(BLACK)
            time.sleep(0.25)
            strip.fill(WHITE)
            time.sleep(0.25)
            strip.fill(BLACK)
            time.sleep(0.25)
            strip.fill(WHITE)
            time.sleep(0.25)
            strip.fill(BLACK)
            ledswhite = 0


while True:
    # Read accelerometer values for x, y, z axes
    x, y, z = accelerometer.acceleration
    # Update the state of the touchpads (debounced)
    updatepads()

    # Detect if the accelerometer experiences a shake motion (shake threshold = 10)
    if accelerometer.shake(shake_threshold=10):
        print("shaken")
        boot = True  # Start the boot process if shaken
        lastinteracted = time.time()  # Update interaction time

    # Boot sequence to gradually increase LED brightness
    if boot and strip.brightness == 0:
        startup()
        active = True  # Set the strip to active mode
    else:
        pass  # Do nothing if not in boot mode

    if active:
        # Change color if touchpad A4 is pressed
        if touchpad_A4.pressed:
            lastinteracted = time.time()  # Update interaction time
            color = (color + 1) % len(colors)  # Cycle to the next color
            strip.fill(colors[color])  # Fill strip with the new color

        # Change to the previous color if touchpad A5 is pressed
        if touchpad_A5.pressed:
            lastinteracted = time.time()  # Update interaction time
            color = (color - 1) % len(colors)  # Cycle to the previous color
            strip.fill(colors[color])  # Fill strip with the new color

        # Increase brightness if touchpad A6 is pressed
        if touchpad_A6.pressed:
            lastinteracted = time.time()
            strip.fill(BLACK)
            time.sleep(0.25)
            strip.fill(WHITE)
            time.sleep(0.25)
            strip.fill(BLACK)
            time.sleep(0.25)
            strip.fill(WHITE)
            time.sleep(0.25)
            strip.fill(BLACK)
            fill = True


        # Decrease brightness if touchpad A7 is pressed
        if touchpad_A7.pressed:
            lastinteracted = time.time()
            strip.fill(colors[color])
            fill = False

        if fill:
            accel_to_led(x,y)
        else:
            strip.fill(colors[color])
            accel_to_led(x, y)

        checkfull()

    # Automatically deactivate the LED strip if no interaction for 15 seconds
    if time.time() - lastinteracted > 15 and active:
        shutdown()
        active = False  # Deactivate strip
        boot = False  # Reset boot flag
        strip.brightness = 0  # Turn off LEDs

    pass
