# Make Art Physical Computing Project
import board, time, neopixel, random, digitalio,adafruit_vl53l1x,math
from rainbowio import colorwheel

from audiopwmio import PWMAudioOut as AudioOut
from audiocore import WaveFile


path="sounds/"

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


#make list of lantern colors
YELLOW = (255, 253, 15)
BLACK = (0, 0, 0)
WHITE=(255,255,255)
AMBER=(255, 100, 0)
GOLD=(255, 222, 30)
ORANGE=(255,127,0)

colors=[YELLOW,WHITE,AMBER,GOLD,ORANGE,BLACK]

#set up sensor
i2c = board.I2C()
distance_sensor = adafruit_vl53l1x.VL53L1X(i2c)
distance_sensor.distance_mode = 1
distance_sensor.timing_budget = 100

distance_sensor.start_ranging()

#set up strip
strip_pin=board.A1
strip_num_of_lights= 20
strip= neopixel.NeoPixel(strip_pin, strip_num_of_lights, brightness=1,auto_write=True)
WHITE=(255,255,255)
BLACK=(0,0,0)

#set up button
button_A=digitalio.DigitalInOut(board.BUTTON_A)
button_A.switch_to_input(pull=digitalio.Pull.DOWN)


#values needed for while true loop
last_random=-1

MAX_DISTANCE = 100
MIN_DISTANCE = 10
cm_per_light = (MAX_DISTANCE-MIN_DISTANCE)/strip_num_of_lights

#define function to randomly animate lights
def animate_lights():
    global random_number
    global random_color
    global last_random
    global COLOR
    random_number= random.randint(0,9)
    random_number_strip=random.randint(0,19)
    random_color=random.randint(0,5)
    COLOR= colors[random_color]
    while last_random == random_number:
        random_number= random.randint(0,9)
    strip[random_number_strip]=COLOR
    time.sleep(0.25)
    strip[random_number_strip]= BLACK
    last_random= random_number

#define function to play wav files
def play_sound(filename):
    with open(path+filename,"rb") as wave_file:
            wave= WaveFile(wave_file)
            audio.play(wave)
            while audio.playing:
                animate_lights()

#start with lights off and animation off
animating=False
strip.fill(BLACK)

while True:
    if distance_sensor.data_ready:
        distance = distance_sensor.distance
        if distance == None:
            distance = 0
        if distance == 0:
            continue
        distance = min(distance, MAX_DISTANCE)
        distance = max(distance, MIN_DISTANCE)

        leds_off = math.ceil((distance-MIN_DISTANCE)/cm_per_light)
        leds_on = strip_num_of_lights-leds_off

        for i in range(strip_num_of_lights):
            if i < leds_on:
                animating= True
                animate_lights()
                if button_A.value:
                    play_sound("I_see_the_light.wav")
                if i > leds_on:
                    strip[i]=BLACK
            else:
                strip[i] = BLACK
        strip.write()
        distance_sensor.clear_interrupt()
        time.sleep(0.05)

