import board
import neopixel
import time
import digitalio
import pwmio
from adafruit_led_animation.color import RED, GREEN, BLUE

# Setup NeoPixel Strip on A1
NUM_PIXELS = 13  # Adjusted to match the number of playable keys
pixels = neopixel.NeoPixel(board.A1, NUM_PIXELS, brightness=0.5, auto_write=True)

# Setup Buttons
button_A = digitalio.DigitalInOut(board.BUTTON_A)
button_A.switch_to_input(pull=digitalio.Pull.DOWN)

button_B = digitalio.DigitalInOut(board.BUTTON_B)
button_B.switch_to_input(pull=digitalio.Pull.DOWN)

# Enable the speaker (important for CPB)
speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
speaker_enable.direction = digitalio.Direction.OUTPUT
speaker_enable.value = True  # Turn speaker ON

# Setup Speaker
speaker = pwmio.PWMOut(board.SPEAKER, variable_frequency=True)
speaker.duty_cycle = 0  # Turn off speaker initially

# Define Note Frequency Mapping
note_frequencies = {
    "C1": 262, "D1": 294, "E1": 330, "F1": 349, "G1": 392, "A2": 440, "B2": 494,
    "C2": 523, "D2": 587, "E2": 659, "F2": 698, "G2": 784, "A3": 880
}

# Reverse-Mapped Light Positions
note_to_pixel = {
    "A3": 0, "G2": 1, "F2": 2, "E2": 3, "D2": 4, "C2": 5, "B2": 6,
    "A2": 7, "G1": 8, "F1": 9, "E1": 10, "D1": 11, "C1": 12
}

# Define Notes for "When the Saints Go Marching In"
notes = [
    "G1", "B2", "C2", "D2", "G1", "B2", "C2", "D2", "G1", "B2", "C2", "D2", "B2", "G1", "B2", "A2", "B2", "A2", "G1",
    "G1", "B2", "D2", "D2", "C2", "B2", "C2", "D2", "B2", "A2", "A2", "G1"
]
note_durations = [
    0.25, 0.25, 0.25, 1.0, 0.25, 0.25, 0.25, 1.0, 0.25, 0.25, 0.25, 0.5, 0.5, 0.5, 0.5, 1.0, 0.25, 0.25, 1.0, 0.5, 0.25,
    0.25, 0.5, 0.5, 0.25, 0.5, 0.5, 0.5, 0.5, 0.5, 1.0
]  # Seconds per note


# Function to Play Notes with LED Feedback
def play_note_with_light(note_name, duration):
    if note_name not in note_frequencies:
        return  # Skip if note is not found

    freq = note_frequencies[note_name]
    pixel_index = note_to_pixel.get(note_name, -1)

    pixels.fill((0, 0, 0))  # Turn off all LEDs before lighting a new note
    if pixel_index != -1:
        pixels[pixel_index] = BLUE  # Light up the corresponding note

    speaker.frequency = freq
    speaker.duty_cycle = 32768  # Play sound
    time.sleep(duration)

    speaker.duty_cycle = 0  # Stop sound
    pixels.fill((0, 0, 0))  # Turn off LEDs
    time.sleep(0.1)


# Main Loop
current_index = 0
playing = False

while True:
    if button_A.value and not playing:
        playing = True

    if button_B.value:
        playing = False

    if button_A.value and button_B.value:
        current_index = 0  # Restart song
        playing = True

    if playing and current_index < len(notes):
        play_note_with_light(notes[current_index], note_durations[current_index])
        current_index += 1
    elif current_index >= len(notes):
        playing = False

