# The Knob
# Made by: Jens Ståhl
# Board: RP2040-Zero
# v1.0: 2025-01-12 (Initial release)

#SW: GP29
#DT: GP28
#CLK: GP27

import board
import time
import neopixel
import usb_hid
import digitalio
import rotaryio
from adafruit_debouncer import Button
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_hid.consumer_control import ConsumerControl
from adafruit_hid.consumer_control_code import ConsumerControlCode

pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)

kbd = Keyboard(usb_hid.devices)
cc = ConsumerControl(usb_hid.devices)

pin = digitalio.DigitalInOut(board.GP29)
pin.direction = digitalio.Direction.INPUT
pin.pull = digitalio.Pull.UP
switch = Button(pin)

encoder = rotaryio.IncrementalEncoder(board.GP27, board.GP28)
last_position = 0

leftRotary, rightRotary, buttonStatus = False, False, False

now = time.monotonic()
lastButton = time.monotonic()
lastTurn = time.monotonic()

RED = (255, 0, 0)
YELLOW = (255, 150, 0)
GREEN = (0, 255, 0)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)
ORANGE = (220, 88, 42)
BLANK = (0, 0, 0)

def setLED(color):
    global now
    pixel[0] = color
    if color != BLANK:
        now = time.monotonic()

while True:
    position = encoder.position
    if position > last_position:
        lastTurn = time.monotonic()
        if buttonStatus and not rightRotary:
            cc.send(ConsumerControlCode.SCAN_NEXT_TRACK)
            setLED(YELLOW)
            leftRotary, rightRotary = False, True
        elif not buttonStatus and ((lastButton + 1) < time.monotonic()):
            cc.send(ConsumerControlCode.VOLUME_INCREMENT)
            setLED(GREEN)
    if position < last_position:
        lastTurn = time.monotonic()
        if buttonStatus and not leftRotary:
            cc.send(ConsumerControlCode.SCAN_PREVIOUS_TRACK)
            setLED(YELLOW)
            leftRotary, rightRotary = True, False
        elif not buttonStatus and ((lastButton + 1) < time.monotonic()):
            cc.send(ConsumerControlCode.VOLUME_DECREMENT)
            setLED(BLUE)

    last_position = position

    switch.update()
    if switch.long_press and ((lastTurn + 1) < time.monotonic()):
        cc.send(ConsumerControlCode.MUTE)
        setLED(RED)
    if switch.short_count == 1 and ((lastTurn + 1) < time.monotonic()):
        cc.send(ConsumerControlCode.PLAY_PAUSE)
        setLED(CYAN)
    if switch.short_count == 2 and ((lastTurn + 1) < time.monotonic()):
        kbd.send(Keycode.ALT, Keycode.A) #Mute Zoom
        kbd.send(Keycode.CONTROL, Keycode.SHIFT, Keycode.M) #Mute Teams
        setLED(RED)

    if switch.pressed:
        buttonStatus = True
    if switch.released:
        lastButton = time.monotonic()
        leftRotary, rightRotary, buttonStatus = False, False, False

    if (time.monotonic() - now > 0.3) and not (pixel[0] == BLANK):
        setLED(BLANK)
