import usb_hid
import supervisor
import storage
import usb_midi

DEFAULT_REPORT_ID = 1
HANDSHAKE_REPORT_ID = 2
VENDOR_ID = 0x0359
PRODUCT_ID = 0x6497           # T9 MIXR

RESOLUTION = 100               # Voicemeeter sliders go from 12.0 to -60.0 in 0.1 increments

REPORT_DESCRIPTOR = bytes([
    0x05, 0x01,               # Usage Page (Generic Desktop Controls)
    0x09, 0x08,               # Usage (Multi-Axis Controller)
    #0x09, 0x04, # Joystick usage (for windows to pick up as usb controller)
    0xA1, 0x01,               # Collection (Application)
    # BUTTONS
    0x05, 0x09,               # Usage Page (Button)
    0x19, 0x01,               # Usage Minimum (Button 1)
    0x29, 0x30,               # Usage Maximum (Button 48)
    0x15, 0x00,               # Logical Minimum (0)
    0x25, 0x01,               # Logical Maximum (1)
    0x75, 0x01,               # Report Size (1 bit)
    0x95, 0x30,               # Report Count (48)
    0x81, 0x02,               # Input (Data, Variable, Absolute)
    # SLIDERS
    0x15, 0x00,               # Logical Minimum (0)
    0x26, 0xFF, 0xFF,         # Logical Maximum (RESOLUTION (720))
    0x75, 0x10,               # Report Size (16-bit)
    #0x85, DEFAULT_REPORT_ID,  # Report ID (DEFAULT_REPORT_ID)
    0x95, 0x05,               # Report Count (5)
    0x09, 0x30,               # Usage (X)
    0x09, 0x31,               # Usage (Y)
    0x09, 0x32,               # Usage (Z)
    0x09, 0x33,               # Usage (Rx)
    0x09, 0x34,               # Usage (Ry)
    0x81, 0x00,               # Input (Data, Array, Absolute)
    0xC0,                     # End Collection
    #0x05, 0x06,               # Usage Page (Generic Device Controls)
    #0x09, 0x01,               # Usage (Background/Nonuser controls)
    #0xA1, 0x01,               # Collection (Application)
    #0x75, 0x20,               # Report Size (32-bit)
    #0x95, 0x01,               # Report Count (1)
    #0x85, HANDSHAKE_REPORT_ID,# Report ID (HANDSHAKE_REPORT_ID)
    #0x81, 0x01,               # Input (Constant, Array, Absolute)
    #0xC0,                     # End Collection
])

def initUsb():
    if supervisor.runtime.usb_connected:
        raise RuntimeError("USB cannot be initialized post-boot")
    supervisor.set_usb_identification(manufacturer="TechAbsol", product="USB Mixer", vid=VENDOR_ID, pid=PRODUCT_ID)

    usb_midi.disable()
    usb_hid.set_interface_name("CircuitPython Mixer")
    sliders = usb_hid.Device(
        report_descriptor = REPORT_DESCRIPTOR,
        usage_page=0x01,
        usage=0x08,
        report_ids=(0,),
        in_report_lengths=(16,),
        out_report_lengths=(0,),
    )

    #storage.disable_usb_drive()
    #storage.remount("/", False)
    usb_hid.enable((sliders,))
    
class UsbMixer():
    def __init__(self):
        if not supervisor.runtime.usb_connected:
            raise RuntimeError("USB is not connected")
        self._device = next((dev for dev in usb_hid.devices if dev.usage_page == 0x01 and dev.usage == 0x08))
        if self._device is None:
            raise RuntimeError("USB mixer doesn't appear to be initialized")

    def _valToBytes(self, value):
        return bytes([value & 0xFF, (value >> 8) & 0xFF])
    
    def _keysToBytes(self, keys):
        return bytes([keys[0], keys[1], keys[2], keys[3], keys[4], keys[5]])

    def send_values(self, slider1, slider2, slider3, slider4, slider5, keys):
        report = self._keysToBytes(keys) + self._valToBytes(slider1) + self._valToBytes(slider2) + self._valToBytes(slider3) + self._valToBytes(slider4) + self._valToBytes(slider5)
        self._device.send_report(report)
