import machine
import neopixel
import time

# Pin configurations
PIN = 5
LED_COUNT = 16
POTENTIOMETER_PIN = 2
BUTTON_PIN = 13
POT_MAX_VALUE = 4095

# Initialization
np = neopixel.NeoPixel(machine.Pin(PIN), LED_COUNT)
pot = machine.ADC(machine.Pin(POTENTIOMETER_PIN))
button = machine.Pin(BUTTON_PIN, machine.Pin.IN, machine.Pin.PULL_UP)

# Define the colors for up to 8 players
SEGMENT_COLORS = [
    (0, 255, 0), (0, 0, 255), (255, 165, 0), (255, 0, 0),
    (255, 255, 0), (75, 0, 130), (255, 20, 147), (0, 255, 255)
]

# Mode settings
SET_PLAYER_COUNT = 0
SET_TIMER_DURATION = 1
TIMER_RUNNING = 2

# Initial settings
mode = SET_PLAYER_COUNT
player_count = 6
timer_duration = 10  # Default to 10 seconds
leds_on = LED_COUNT  # Initialize the variable to keep track of the number of LEDs that are currently on
current_player = 0  # Initialize the current player index

# Timer states
RUNNING = 1
PAUSED = 0
state = PAUSED

def get_player_count():
    pot_value = pot.read()
    return max(2, round((pot_value / POT_MAX_VALUE) * (len(SEGMENT_COLORS) - 1)) + 1)

def display_segments(player_count):
    np.fill((0, 0, 0))  # Clear the LEDs first
    segment_length = LED_COUNT // player_count
    extra_leds = LED_COUNT % player_count
    led_index = 0
    for i in range(player_count):
        color = SEGMENT_COLORS[i % len(SEGMENT_COLORS)]
        for _ in range(segment_length + (1 if i < extra_leds else 0)):
            np[led_index] = color
            led_index += 1
    np.write()

def get_timer_duration():
    pot_value = pot.read()
    return max(10, round((pot_value / POT_MAX_VALUE) * 60))  # 10 to 60 seconds

def update_leds_for_duration(duration):
    """Updates LEDs based on the timer duration selected using the potentiometer."""
    led_count = round((duration - 10) / 50 * (LED_COUNT - 1) + 1)
    np.fill((0, 0, 0))  # Clear all LEDs
    for i in range(led_count):
        np[i] = (255, 255, 255)  # Set LEDs to white based on the timer duration
    np.write()

def check_timer_duration_change():
    """Checks and updates the timer duration setting from the potentiometer."""
    global timer_duration
    current_duration = get_timer_duration()
    if current_duration != timer_duration:
        timer_duration = current_duration
        update_leds_for_duration(timer_duration)

def start_timer():
    global state, last_update_time, leds_on
    state = RUNNING
    leds_on = LED_COUNT  # Reset LEDs to full on start
    last_update_time = time.ticks_ms()
    np.fill((0, 255, 0))  # Set all LEDs to green
    np.write()
    print("Timer started")

def pause_timer():
    global state
    if state == RUNNING:
        state = PAUSED
        print("Timer paused")

def resume_timer():
    global state, last_update_time
    if state == PAUSED:
        state = RUNNING
        last_update_time = time.ticks_ms()  # Reset the last update time to avoid jump in countdown
        print("Timer resumed")
def update_timer_setting_display():
    """Updates the LED display to show the current timer setting."""
    duration = get_timer_duration()
    led_count = round((duration - 10) / 50 * (LED_COUNT - 1) + 1)
    np.fill((0, 0, 0))  # Clear all LEDs
    for i in range(led_count):
        np[i] = (255, 255, 255)  # Set LEDs to white based on the timer duration
    np.write()

def display_segments(player_count):
    np.fill((0, 0, 0))  # Clear the LEDs first
    segment_length = LED_COUNT // player_count
    extra_leds = LED_COUNT % player_count
    led_index = 0
    for i in range(player_count):
        color = SEGMENT_COLORS[i % len(SEGMENT_COLORS)]  # Use modulo for safety
        for _ in range(segment_length + (1 if i < extra_leds else 0)):
            np[led_index] = color
            led_index += 1
    np.write()




def button_press():
    """Handles button press events for mode transitions and function activation."""
    global mode, state, timer_duration
    if not button.value():  # Check if the button is pressed
        time.sleep(0.05)  # Debounce delay
        if not button.value():  # Confirm button press
            while not button.value():  # Wait until the button is released
                time.sleep(0.01)
            if mode == SET_TIMER_DURATION:
                # Transition between states if in timer setting mode
                if state == PAUSED:
                    start_timer()  # Start the timer if paused
                elif state == RUNNING:
                    pause_timer()  # Pause the timer if running
                elif state == PAUSED:
                    resume_timer()  # Resume the timer if paused
            elif mode == SET_PLAYER_COUNT:
                mode = SET_TIMER_DURATION  # Move to timer duration setting mode
                timer_duration = get_timer_duration()
                update_leds_for_duration(timer_duration)  # Show timer setting visually
def update_timer():
    global last_update_time, leds_on, state, current_player, player_count
    if state != RUNNING:
        return  # Only update if the timer is running

    current_time = time.ticks_ms()
    interval = (timer_duration * 1000) // LED_COUNT  # Total duration divided by the number of LEDs

    if time.ticks_diff(current_time, last_update_time) >= interval:
        last_update_time = current_time
        leds_on -= 1  # Decrease the number of LEDs to be lit
        np.fill((0, 0, 0))  # Clear all LEDs first

        # Light up the remaining LEDs in the current player's color
        for i in range(leds_on):
            np[i] = SEGMENT_COLORS[current_player % len(SEGMENT_COLORS)]

        np.write()

        if leds_on == 0:
            state = PAUSED  # Pause the timer after the last LED is turned off
            current_player = (current_player + 1) % player_count  # Move to the next player
            leds_on = LED_COUNT  # Reset the LEDs for the next round
            display_segments(player_count)  # Display the current player's color
            print("Timer finished, switch to player", current_player + 1)


def main_loop():
    global mode, state, timer_duration
    while True:
        button_press()
        if mode == SET_PLAYER_COUNT:
            current_player_count = get_player_count()
            if current_player_count != player_count:
                player_count = current_player_count
                display_segments(player_count)
        elif mode == SET_TIMER_DURATION:
            current_duration = get_timer_duration()
            if current_duration != timer_duration:
                timer_duration = current_duration
                update_timer_setting_display()  # Update display to reflect current timer duration
        if state == RUNNING:
            update_timer()
        time.sleep(0.01)  # Sleep to prevent excessive CPU usage





# Display initial player count
player_count = get_player_count()
display_segments(player_count)

while True:
    button_press()
    if mode == SET_PLAYER_COUNT:
        current_player_count = get_player_count()
        if current_player_count != player_count:
            player_count = current_player_count
            display_segments(player_count)
    elif mode == SET_TIMER_DURATION:
        current_duration = get_timer_duration()
        if current_duration != timer_duration:
            timer_duration = current_duration
            update_timer_setting_display()  # Update display to reflect current timer duration
    if state == RUNNING:
        update_timer()
    time.sleep(0.01)  # Sleep to prevent excessive CPU usage
# At the bottom of your script file
if __name__ == "__main__":
    main_loop()  # Or use your current while loop if preferred