# MakeArt Project
#Imports:
import board, neopixel, digitalio, time, random
from adafruit_led_animation.animation.colorcycle import ColorCycle
from adafruit_led_animation.animation.solid import Solid
from adafruit_led_animation.animation.comet import Comet
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
from adafruit_bluefruit_connect.packet import Packet
from adafruit_bluefruit_connect.color_packet import ColorPacket
from adafruit_bluefruit_connect.button_packet import ButtonPacket
from adafruit_led_animation.color import (
    AMBER,
    BLACK,
    BLUE,
    JADE,
    ORANGE,
    PURPLE,
    RED,
    WHITE,
    YELLOW,
)
from audiopwmio import PWMAudioOut as AudioOut
from audiocore import WaveFile

#LED Position, Addl. Color, and Animation Setup:
strip_pin = board.A1
strip_number_of_lights = 30
set_brightness = 0.5
strip = neopixel.NeoPixel(strip_pin, strip_number_of_lights, brightness = set_brightness, auto_write = True)
DARK_GREEN = (15, 85, 0)
DARK_BLUE = (1, 0, 96)
DARK_PURPLE = (37, 0, 61)
VIOLET = (127, 0, 255)

morning = [RED, YELLOW, ORANGE, AMBER]
night = [VIOLET, BLUE, JADE, DARK_PURPLE]

colorcycle_strip_morning = ColorCycle(strip, 1, colors=morning)
colorcycle_strip_night = ColorCycle(strip, 1, colors=night)
colorcycle_strip_comet = Comet(strip, speed=.001, color=WHITE, tail_length=10, bounce=True)
solid = Solid(strip, color=BLACK)


#Setup Audio:
path = "Project/"

speaker = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
speaker.direction = digitalio.Direction.OUTPUT
speaker.value = True
audio = AudioOut(board.SPEAKER)

#Setup Bluetooth
ble = BLERadio()
uart_server = UARTService()
advertisement = ProvideServicesAdvertisement(uart_server)

advertisement.complete_name = "Virtudes" # Change this name to whatever you want to call your CPB - Make sure it's 11 char. or less
ble_radio = BLERadio()
ble_radio.name = advertisement.complete_name
print(f"ble.name is {ble_radio.name}")

#Setup LED Functions:
def morning_LED():
    colorcycle_strip_morning.animate()
def night_LED():
    colorcycle_strip_night.animate()
def morning_spiral():
    count = 0
    while count <= len(morning)-2:
        for i in range(strip_number_of_lights):
            strip[i] = morning[count]
            strip.write()
            time.sleep(0.1)
        for x in range(strip_number_of_lights-1, -1, -1):
            strip[x] = morning[count+1]
            strip.write()
            time.sleep(0.1)
        count += 2
def night_spiral():
    count = 0
    while count <= len(night)-2:
        for i in range(strip_number_of_lights):
            strip[i] = night[count]
            strip.write()
            time.sleep(0.1)
        for x in range(strip_number_of_lights-1, -1, -1):
            strip[x] = night[count+1]
            strip.write()
            time.sleep(0.1)
        count += 2
def whiteout():
    colorcycle_strip_comet.animate()
def blackout():
    solid.animate()

#Setup Sound Function:
def play_sound(filename):
    tone_volume = 200
    with open(path + filename, "rb") as wave_file:
        wave = WaveFile(wave_file)
        audio.play(wave)
        while audio.playing:
            pass
        time.sleep(2)


run_cycle = False
def runSelectedCycle():
    if cycle_number == 1:
        print("Morning mode with sound")
        morning_LED()
        play_sound("chirps.wav")
    elif cycle_number == 2:
        print("Night Mode with Sound")
        night_LED()
        play_sound("night.wav")
    elif cycle_number == 3:
        print("Morning Mode (No Sound)")
        time.sleep(2)
        morning_LED()
    elif cycle_number == 4:
        print("Night Mode (No Sound)")
        night_LED()
        time.sleep(2)
    elif cycle_number == 5:
        print("Day Spiral Mode")
        morning_spiral()
    elif cycle_number == 6:
        print("Night Spiral Mode")
        night_spiral()
    elif cycle_number == 7:
        print("Whiteout")
        whiteout()
    elif cycle_number == 8:
        print("LEDs Off")
        blackout()

while True:
    ble.start_advertising(advertisement)
    while not ble.connected:
        pass

    ble.stop_advertising()

    while ble.connected:
        try:
            packet = Packet.from_stream(uart_server)
        except ValueError:
            continue

        if isinstance(packet, ColorPacket):
            print("*** color sent")
            print("pickedColor = ", ColorPacket)
            run_cycle = False
            animation_number = 0
            strip.fill(packet.color)
            strip.write()
            pickedColor = packet.color
            fade_color = (pickedColor[0]//2, pickedColor[1]//2, pickedColor[2]//2)
            light_position = -1


        if isinstance(packet, ButtonPacket):
            if packet.pressed:
                if packet.button == ButtonPacket.BUTTON_1: # app button 1 pressed
                    cycle_number = 1
                    run_cycle = True

                elif packet.button == ButtonPacket.BUTTON_2: # app button 2 pressed
                    cycle_number = 2
                    run_cycle = True

                elif packet.button == ButtonPacket.BUTTON_3: # app button 3 pressed
                    cycle_number = 3
                    run_cycle = True

                elif packet.button == ButtonPacket.BUTTON_4: # app button 4 pressed
                    cycle_number = 4
                    run_cycle = True

                elif packet.button == ButtonPacket.RIGHT: # app button Right arrow pressed
                    cycle_number = 5
                    run_cycle = True

                elif packet.button == ButtonPacket.LEFT: # app button Left arrow pressed
                    cycle_number = 6
                    run_cycle = True

                elif packet.button == ButtonPacket.DOWN: # app button Down arrow pressed
                    cycle_number = 7
                    run_cycle = True

                elif packet.button == ButtonPacket.UP: # app button Up arrow pressed
                    cycle_number = 8
                    run_cycle = True


        if run_cycle == True:
            runSelectedCycle()





