import ssd1306
import utime
from rando import randrange
from machine import Pin, PWM, I2C
from micropython import const


# Configure OLED screen
i2c = I2C(id=1, sda=Pin(6), scl=Pin(7), freq=400000)
print(i2c.scan())
display = ssd1306.SSD1306_I2C(128, 64, i2c)


# Define Color LEDs
ledYellow = Pin(18, Pin.OUT)
ledGreen = Pin(19, Pin.OUT)
ledRed = Pin(20, Pin.OUT)
ledBlue = Pin(21, Pin.OUT)

# Define Color Buttons
btnYellow = Pin(13, Pin.IN, Pin.PULL_UP)
btnGreen = Pin(12, Pin.IN, Pin.PULL_UP)
btnRed = Pin(11, Pin.IN, Pin.PULL_UP)
btnBlue = Pin(10, Pin.IN, Pin.PULL_UP)

# Define Buzzer
buzzer = machine.PWM(machine.Pin(9))

# Define Tones
lights = {0:ledYellow, 1:ledGreen, 2:ledRed, 3:ledBlue}
tones = {0:440 , 1:494, 2:523, 3:587}


# Choose Difficulty
difficulty = 4


def get_sequence(difficulty):
    sequence = []
    for i in range(difficulty):
        sequence.append(randrange(4))
    print(sequence)
    return sequence


def tone(pin,frequency,duration):
    pin.freq(frequency)
    pin.duty_u16(30000)
    utime.sleep_ms(duration)
    pin.duty_u16(0) 


def compare_sequence(sequence1, sequence2):
    if sequence1 != sequence2:
        display_message('WRONG!', 'Try Again!')
    else:
        display_message('CORRECT!', 'Great Job!')
    
    
def display_message(*args):
    display.fill(0)
    for index, arg in enumerate(args):
        print(index, arg)
        display.text(arg, 0, int(index)*20, 1) 
    display.show()



while True:  
    # Flash color sequence for user
    sequence = get_sequence(difficulty)
    display_message(' ')
    for i in sequence:
        lights[i].on()
        tone(buzzer,tones[i],250)
        utime.sleep(1)
        lights[i].off()
        utime.sleep(0.25)
    
    # Define the list for the user sequence 
    user_sequence = []
    red_Button_pressed = 1 # Initialize flag for when the red button is pressed
    yellow_Button_pressed = 1 # Initialize flag for when the red button is pressed
    green_Button_pressed = 1 # Initialize flag for when the red button is pressed
    blue_Button_pressed = 1 # Initialize flag for when the red button is pressed
    
    # Collect user input while flashing LEDs
    while len(user_sequence) != len(sequence):
        if btnYellow.value() == 0 and yellow_Button_pressed == 1:
            user_sequence.append(0) # Add 0 to user list once Yellow button is pressed
            yellow_Button_pressed = 0
            lights[0].on()
            tone(buzzer,tones[0],250)
            print(user_sequence)
        elif btnYellow.value() == 1: 
            yellow_Button_pressed = 1
            lights[0].off()
        if btnGreen.value() == 0 and green_Button_pressed == 1:
            user_sequence.append(1) # Add 1 to user list once Green button is pressed
            green_Button_pressed = 0
            lights[1].on()
            tone(buzzer,tones[1],250)      
            print(user_sequence)
        elif btnGreen.value() == 1:
            green_Button_pressed = 1
            lights[1].off()
        if btnRed.value() == 0 and red_Button_pressed == 1:
            user_sequence.append(2) # Add 2 to user list once Red button is pressed
            red_Button_pressed = 0
            lights[2].on()
            tone(buzzer,tones[2],250)
            print(user_sequence)
        elif btnRed.value() == 1:
            red_Button_pressed = 1
            lights[2].off()
        if btnBlue.value() == 0 and blue_Button_pressed == 1:
            user_sequence.append(3) # Add 3 to user list once Blue button is pressed
            blue_Button_pressed = 0
            lights[3].on()
            tone(buzzer,tones[3],250)
            print(user_sequence)
        elif btnBlue.value() == 1:
            blue_Button_pressed = 1
            lights[3].off()
     
    # Turn off all lights once entire user sequence is completed 
    for i in range(4):
        lights[i].off()
    compare_sequence(user_sequence, sequence)
    utime.sleep(2)