// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2025 James Turner <james@flightgear.org>

#pragma once

#include <cstdint>
#include <string>

namespace HID {
// clang-format off
enum class UsagePage
{
    Undefined = 0x00,
    GenericDesktop = 0x01,
    Simulation = 0x02,
    VR = 0x03,
    Sport =0x04,
    Game =0x05,
    GenericDevice = 0x06,
    Keyboard = 0x07,
    LEDs = 0x08,
    Button = 0x09,
    Ordinal = 0x0A,
    Telephony = 0x0B,
    Consumer = 0x0C,
    Digitizer = 0x0D,
    // reserved 0x0E
    PID = 0x0F,
    Unicode = 0x10,
    AlphanumericDisplay = 0x14,
    MedicalInstruments = 0x40,
    BarCodeScanner = 0x8C,
    MagneticStripeReadingDevice = 0x8E,
    CameraControl = 0x90,
    Arcade = 0x91,
    VendorDefinedStart = 0xFF00
};

enum SimulationUsage
{
    SC_FlightSimulationDevice = 0x01,
    SC_AutomobileSimulationDevice = 0x02,
    SC_TankSimulationDevice = 0x03,
    SC_SpaceShipSimulationDevice = 0x04,
    SC_SubmarineSimulationDevice = 0x05,
    SC_SailingSimulationDevice = 0x06,
    SC_MotorcycleSimulationDevice = 0x07,
    SC_SportsSimulationDevice = 0x08,
    SC_AirplaneSimulationDevice = 0x09,
    SC_HelicopterSimulationDevice = 0x0A,
    SC_MagicCarpetSimulationDevice = 0x0B,
    SC_BycicleSimulationDevice = 0x0C,
    SC_FlightControlStick = 0x20,
    SC_FlightStick = 0x21,
    SC_CyclicControl = 0x22,
    SC_CyclicTrim = 0x23,
    SC_FlightYoke = 0x24,
    SC_TrackControl = 0x25,
    SC_Aileron = 0xB0,
    SC_AileronTrim = 0xB1,
    SC_AntiTorqueControl = 0xB2,
    SC_AutopilotEnable = 0xB3,
    SC_ChaffRelease = 0xB4,
    SC_CollectiveControl = 0xB5,
    SC_DiveBrake = 0xB6,
    SC_ElectronicCountermeasures = 0xB7,
    SC_Elevator = 0xB8,
    SC_ElevatorTrim = 0xB9,
    SC_Rudder = 0xBA,
    SC_Throttle = 0xBB,
    SC_FlightCommunications = 0xBC,
    SC_FlareRelease = 0xBD,
    SC_LandingGear = 0xBE,
    SC_ToeBrake = 0xBF,
    SC_Trigger = 0xC0,
    SC_WeaponsArm = 0xC1,
    SC_WeaponsSelect = 0xC2,
    SC_WingFlaps = 0xC3,
    SC_Accelerator = 0xC4,
    SC_Brake = 0xC5,
    SC_Clutch = 0xC6,
    SC_Shifter = 0xC7,
    SC_Steering = 0xC8,
    SC_TurretDirection = 0xC9,
    SC_BarrelElevation = 0xCA,
    SC_DivePlane = 0xCB,
    SC_Ballast = 0xCC,
    SC_BicycleCrank = 0xCD,
    SC_HandleBars= 0xCE,
    SC_FrontBrake = 0xCF,
    SC_RearBrake = 0xD0

};


enum GenericDesktopUsage
{
    // generic desktop section
    GD_Undefined= 0x00,
    GD_Pointer = 0x01,
    GD_Mouse = 0x02,
    GD_Reserved03 = 0x03,
    GD_Joystick = 0x04,
    GD_GamePad = 0x05,
    GD_Keyboard = 0x06,
    GD_Keypad = 0x07,
    GD_MultiAxisController = 0x08,
    GD_TabletPCSysCtrls = 0x09,
    GD_WaterCoolingDevice = 0x0A,
    GD_ComputerChassisDevice = 0x0B,
    GD_WirelessRadioControls = 0x0C,
    GD_PortableDeviceControl = 0x0D,
    GD_SystemMultiAxisController = 0x0E,
    GD_SpatialController = 0x0F,
    GD_AssistiveControl = 0x10,
    GD_DeviceDock = 0x11,
    GD_DockableDevice = 0x12,
    GD_CallStateManagementControl = 0x13,
    GD_Reserved14 = 0x14,
    GD_Reserved15 = 0x15,
    GD_Reserved16 = 0x16,
    GD_Reserved17 = 0x17,
    GD_Reserved18 = 0x18,
    GD_Reserved19 = 0x19,
    GD_Reserved1A = 0x1A,
    GD_Reserved1B = 0x1B,
    GD_Reserved1C = 0x1C,
    GD_Reserved1D = 0x1D,
    GD_Reserved1E = 0x1E,
    GD_Reserved1F = 0x1F,
    GD_Reserved20 = 0x20,
    GD_Reserved21 = 0x21,
    GD_Reserved22 = 0x22,
    GD_Reserved23 = 0x23,
    GD_Reserved24 = 0x24,
    GD_Reserved25 = 0x25,
    GD_Reserved26 = 0x26,
    GD_Reserved27 = 0x27,
    GD_Reserved28 = 0x28,
    GD_Reserved29 = 0x29,
    GD_Reserved2A = 0x2A,
    GD_Reserved2B = 0x2B,
    GD_Reserved2C = 0x2C,
    GD_Reserved2D = 0x2D,
    GD_Reserved2E = 0x2E,
    GD_Reserved2F = 0x2F,
    GD_X = 0x30,
    GD_Y = 0x31,
    GD_Z = 0x32,
    GD_Rx = 0x33,
    GD_Ry = 0x34,
    GD_Rz = 0x35,
    GD_Slider = 0x36,
    GD_Dial = 0x37,
    GD_Wheel = 0x38,
    GD_Hatswitch = 0x39,
    GD_CountedBuffer= 0x3A,
    GD_ByteCount = 0x3B,
    GD_MotionWakeUp = 0x3C,
    GD_Start = 0x3D,
    GD_Select = 0x3E,
    GD_Reserved3F = 0x3F,
    GD_Vx = 0x40,
    GD_Vy = 0x41,
    GD_Vz = 0x42,
    GD_Vbrx = 0x43,
    GD_Vbry = 0x44,
    GD_Vbrz = 0x45,
    GD_Vno = 0x46,
    GD_FeatureNotification = 0x47,
    GD_ResolutionMultiplier = 0x48,
    GD_Qx = 0x49,
    GD_Qy = 0x4A,
    GD_Qz = 0x4B,
    GD_Qw = 0x4C,
    GD_SystemControl = 0x80,
    GD_SystemPowerDown = 0x81,
    GD_SystemSleep = 0x82,
    GD_SystemWakeUp = 0x83,
    GD_SystemContextMenu = 0x84,
    GD_SystemMainMenu = 0x85,
    GD_SystemAppMenu = 0x86,
    GD_SystemMenuHelp = 0x87,
    GD_SystemMenuExit = 0x88,
    GD_SystemMenuSelect = 0x89,
    GD_SystemMenuRight = 0x8A,
    GD_SystemMenuLeft = 0x8B,
    GD_SystemMenuUp= 0x8C,
    GD_SystemMenuDown = 0x8D,
    GD_SystemColdRestart = 0x8E,
    GD_SystemWarmRestart = 0x8F,
    GD_DpadUp = 0x90,
    GD_DpadDown = 0x91,
    GD_DpadRight = 0x92,
    GD_DpadLeft = 0x93,
    GD_IndexTrigger = 0x94,
    GD_PalmTrigger = 0x95,
    GD_Thumbstick = 0x96,
    GD_SystemFunctionShift = 0x97,
    GD_SystemFunctionShiftLock = 0x98,
    GD_SystemFunctionShiftLockIndicator = 0x99,
    GD_SystemDismissNotification = 0x9A,
    GD_SystemDoNotDisturb = 0x9B,
    GD_SystemDock = 0xA0,
    GD_SystemUndock = 0xA1,
    GD_SystemSetup  = 0xA2,
    GD_SystemBreak = 0xA3,
    GD_SystemDebuggerBreak = 0xA4,
    GD_ApplicationBreak = 0xA5,
    GD_ApplicationDebuggerBreak = 0xA6,
    GD_SystemSpeakerMute = 0xA7,
    GD_SystemHibernate = 0xA8,
    GD_SystemMicrophoneMute = 0xA9,
    GD_SystemDisplayInvert = 0xB0,
    GD_SystemDisplayInternal = 0xB1,
    GD_SystemDisplayExternal = 0xB2,
    GD_SystemDisplayBoth = 0xB3,
    GD_SystemDisplayDual = 0xB4,
    GD_SystemDisplayToggleIntExtMode = 0xB5,
    GD_SystemDisplaySwapPrimarySecondary = 0xB6,
    GD_SystemDisplayToggleLCDAutoscale = 0xB7,
    GD_SensorZone = 0xC0,
    GD_RPM= 0xC1,
    GD_CoolantLevel = 0xC2,
    GD_CoolantCriticalLevel = 0xC3,
    GD_CoolantPump = 0xC4,
    GD_ChassisEnclosure = 0xC5,
    GD_WirelessRadioButton = 0xC6,
    GD_WirelessRadioLED = 0xC7,
    GD_WirelessRadioSliderSwitch = 0xC8,
    GD_SystemDisplayRotationLockButton = 0xC9,
    GD_SystemDisplayRotationLockSliderSwitch = 0xCA,
    GD_ControlEnable = 0xCB,
    GD_DockableDeviceUniqueID = 0xD0,
    GD_DockableDeviceVendorID = 0xD1,
    GD_DockableDevicePrimaryUsagePage = 0xD2,
    GD_DockableDevicePrimaryUsageID = 0xD3,
    GD_DockableDeviceDockingState = 0xD4,
    GD_DockableDeviceDisplayOcclusion = 0xD5,
    GD_DockableDeviceObjectType = 0xD6,
    GD_CallActiveLED = 0xE0,
    GD_CallMuteToggle = 0xE1,
    GD_CallMuteLED = 0xE2
};

enum LEDUsage
{
    LED_Undefined = 0,
    LED_NumLock = 0x01,
    LED_CapsLock = 0x02,
    LED_ScrollLock = 0x03,
    LED_Compose = 0x04,
    LED_Kana = 0x05,
    LED_Power = 0x06,
    LED_Shift = 0x07,
    LED_DoNotDisturb = 0x08,
    LED_Mute = 0x09,
    LED_ToneEnable = 0x0A,
    LED_HighCutFilter = 0x0B,
    LED_LowCutFilter = 0x0C,
    LED_EqualizerEnable = 0x0D,
    LED_SoundFieldOn = 0x0E,
    LED_SurroundOn = 0x0F,
    LED_Repeat = 0x10,
    LED_Stereo = 0x11,
    LED_SampligRateDetect = 0x12,
    LED_Spinning = 0x013,
    LED_CAV = 0x14,
    LED_CLV = 0x15,
    LED_RecordingFormatDetect = 0x16,
    LED_OffHook = 0x17,
    LED_Ring = 0x18,
    LED_MessageWaiting= 0x19,
    LED_DataMode = 0x1A,
    LED_BatteryOperation = 0x1B,
    LED_BatteryOk = 0x1C,
    LED_BatteryLow = 0x1D,
    LED_Speaker = 0x1E,
    LED_HeadSet = 0x1F,
    LED_Hold = 0x20,
    LED_Microphone = 0x21,
    LED_Coverage = 0x22,
    LED_NightMode = 0x23,
    LED_SendCalls = 0x24,
    LED_CallPickup = 0x25,
    LED_Conference = 0x26,
    LED_StandBy = 0x27,
    LED_CameraOn = 0x28,
    LED_CameraOff = 0x29,
    LED_OnLine = 0x2A,
    LED_OffLine = 0x2B,
    LED_Busy = 0x2C,
    LED_Ready = 0x2D,
    LED_PaperOut = 0x2E,
    LED_PaperJam = 0x2F,
    LED_Remote = 0x30,
    LED_Forward = 0x31,
    LED_Reverse = 0x32,
    LED_Stop = 0x33,
    LED_Rewind = 0x34,
    LED_FastForward = 0x35,
    LED_Play = 0x36,
    LED_Pause = 0x37,
    LED_Record = 0x38,
    LED_Error = 0x39,
    LED_UsageSelectedIndicator = 0x3A,
    LED_UsageInUseIndicator = 0x3B,
    LED_UsageMultiModeIndicator = 0x3C,
    LED_IndicatorOn = 0x3D,
    LED_IndicatorFlash= 0x3E,
    LED_IndicatorSlowBlink = 0x3F,
    LED_IndicatorFastBlink = 0x40,
    LED_IndicatorOff = 0x41,
    LED_FlashOnTime = 0x42,
    LED_SlowBlinkOnTime = 0x43,
    LED_SlowBlinkOffTime = 0x44,
    LED_FastBlinkOnTime = 0x45,
    LED_FastBlinkOfftime = 0x46,
    LED_UsageIndicatorColor = 0x47,
    LED_IndicatorRed = 0x48,
    LED_IndicatorGreen = 0x49,
    LED_IndicatorAmber = 0x4A,
    LED_GenericIndicator = 0x4B,
    LED_SystemSuspend = 0x4C,
    LED_ExternalPowerConnected = 0x4D
};

enum AlphanumericDisplayUsage
{
    AD_AlphanumericDisplay = 0x01,
    AD_BitmappedDisplay = 0x02,
    AD_DisplayControlReport = 0x24,
    AD_ClearDisplay = 0x25,
    AD_CharacterReport = 0x2B,
    AD_DisplayData = 0x2C,
    AD_DisplayStatus = 0x2D,
    AD_Rows = 0x35,
    AD_Columns = 0x36,
    AD_7SegmentDirectMap = 0x43,
    AD_14SegmentDirectMap = 0x45,
    AD_DisplayBrightness = 0x46,
    AD_DisplayContrast = 0x47
};

enum VRUsage
{
    VR_Undefined = 0x00,
    VR_Belt = 0x01,
    VR_BodySuit = 0x02,
    VR_Flexor = 0x03,
    VR_Glove = 0x04,
    VR_HeadTracker = 0x05,
    VR_HeadMountedDisplay = 0x06,
    VR_HandTracker = 0x07,
    VR_Oculometer = 0x08,
    VR_Vest = 0x09,
    VR_AnimatronicDevice = 0x0A,
    VR_StereoEnable = 0x20,
    VR_DisplayEnable = 0x21
};

enum class ReportType
{
    Invalid = 0,
    In = 0x08,
    Out = 0x09,
    Feature = 0x0B
};

// clang-format on

/**
     * @brief return the usage string for a page+code.
     * These values need to be stable and also consistent with event-input on Linux, which
     * is not always easy.
     *
     * @param usagePage
     * @param usage
     */
std::string nameForUsage(uint32_t usagePage, uint32_t usage);

std::pair<UsagePage, uint32_t> usage(uint32_t);

} // namespace HID
