# SPDX-FileCopyrightText: 2023 Phil Burgess for Adafruit Industries (with modifications by Aaron Pendley)
#
# SPDX-License-Identifier: MIT

"""
HAL 9000 demo project for Adafruit Prop Maker Feather RP2040 and "Massive
Arcade Button with LED - 100mm red." This simply monitors for button presses
and then randomly plays one WAV file from the CIRCUITPY filesystem.
No soldering required; using quick-connects, LED and button can be wired
to screw terminals on the Prop Maker Feather board.
NOTE: WAV FILES MUST BE 16-BIT. This will be fixed (allowing 8-bit WAVs if
desired) in CircuitPython 9.0.
"""

# pylint: disable=import-error
import os
import random
import time
import audiocore
import audiobusio
import board
import digitalio
import pwmio
import math
from adafruit_ticks import ticks_ms, ticks_diff


# HARDWARE SETUP -----------------------------------------------------------

led = pwmio.PWMOut(board.EXTERNAL_NEOPIXELS)
led.duty_cycle = 0
led_pulse_period = 8000
led_timer = 0

# Button is wired to GND and "Btn" on screw terminal header:
button = digitalio.DigitalInOut(board.EXTERNAL_BUTTON)
button.direction = digitalio.Direction.INPUT
button.pull = digitalio.Pull.UP

# Enable power to audio amp, etc.
external_power = digitalio.DigitalInOut(board.EXTERNAL_POWER)
external_power.direction = digitalio.Direction.OUTPUT
external_power.value = True

# I2S audio out
audio = audiobusio.I2SOut(board.I2S_BIT_CLOCK, board.I2S_WORD_SELECT, board.I2S_DATA)

# Find all Wave files in CIRCUITPY storage:
wavefiles = [
    file
    for file in os.listdir("/sounds/")
    if (file.endswith(".wav") and not file.startswith("._"))
]
print("\nAudio files found:", wavefiles)

current_sound_index = 0

# FUNCTIONS ----------------------------------------------------------------

def shuffle_sounds():
    global wavefiles
    global current_sound_index

    wavefiles = sorted(wavefiles, key=lambda x: random.random())
    current_sound_index = 0

    print("Shuffled sounds:", wavefiles)    

def play_next_sound():
    global wavefiles
    global current_sound_index

    filename = wavefiles[current_sound_index]

    print("Playing sound", current_sound_index, "-", filename)    

    # Go to the next random sound and reshuffle list if we're at the end
    current_sound_index += 1
    if current_sound_index >= len(wavefiles):
        shuffle_sounds()

    """Plays a WAV file in its entirety (function blocks until done)."""
    with open(f"/sounds/{filename}", "rb") as file:
        audio.play(audiocore.WaveFile(file))

        # Randomly flicker the LED a bit while audio plays
        while audio.playing:
            led.duty_cycle = random.randint(5000, 30000)
            time.sleep(0.1)


# MAIN LOOP ----------------------------------------------------------------

shuffle_sounds()
last_ticks = ticks_ms()

while True:
    # Update time tracking
    now = ticks_ms()
    dt = ticks_diff(now, last_ticks)
    last_ticks = now

    if button.value is False:
        play_next_sound()

        # Set the LED timer to fade out from 25% brightness
        led_timer = led_pulse_period - (led_pulse_period / 4)

        # Update last_ticks since play_next_sound() blocks our timing updates until it's done
        last_ticks = ticks_ms()        
    else:
        # Update pulse animation
        led_timer = (led_timer + dt) % led_pulse_period
        sinValue = math.sin((led_timer * math.pi * 2 / led_pulse_period) + 2) + 1
        gammaCorrected = pow(1 - (sinValue / 2), 1.8)
        led.duty_cycle = int(gammaCorrected * 65535)