namespace RioJoy.Core.Mapping;

/// <summary>Mouse actions encoded in a mouse entry's low byte (docs/PROTOCOL.md §5).</summary>
public enum MouseAction : byte
{
    MoveUp = 0,
    MoveRight = 1,
    MoveDown = 2,
    MoveLeft = 3,
    LeftClick = 4,
    RightClick = 5,
}

/// <summary>Which mouse button a click action targets.</summary>
public enum MouseButton
{
    Left,
    Right,
}

/// <summary>Discrete 4-way POV hat position. <see cref="Centered"/> = released.</summary>
public enum RioHat
{
    Centered = -1,
    Up = 0,
    Right = 1,
    Down = 2,
    Left = 3,
}

/// <summary>
/// Internal RIO commands (the low byte when an entry is a RIO command). Port of
/// the <c>RIOcmd</c> switch (riovjoy2.cpp#L1852).
/// </summary>
public enum RioCommandCode : byte
{
    ResetAllAxes = 0,
    ResetThrottle = 1,
    ResetLeftPedal = 2,
    ResetRightPedal = 3,
    ResetVerticalJoystick = 4,
    ResetHorizontalJoystick = 5,
    GeneralReset = 6,
    RequestVersionAndCheck = 7,
    ToggleRawAxesReadout = 8,
    TogglePollRateReadout = 9,
}

/// <summary>
/// Keyboard + mouse output (the <c>SendInput</c> target). The router holds the
/// ordering logic and emits virtual-key codes; a sink implementation maps VK to
/// scancode and calls <c>SendInput</c>. Keys are addressed by Windows virtual-key
/// code; modifiers are sent as ordinary keys (VK_SHIFT/CONTROL/MENU).
/// </summary>
public interface IInputSink
{
    void KeyDown(byte virtualKey, bool extended);

    void KeyUp(byte virtualKey, bool extended);

    /// <summary>Relative mouse move by (<paramref name="dx"/>, <paramref name="dy"/>) pixels.</summary>
    void MouseMove(int dx, int dy);

    void MouseButton(MouseButton button, bool down);
}

/// <summary>
/// Virtual joystick output (the HID feeder → RioGamepad driver in Phase 1).
/// Button numbers are 0-based into the 96-button report; the hat is the single POV;
/// axis values are in the range <c>0..32766</c> (see <c>AxisOutputs</c>).
/// </summary>
public interface IJoystickSink
{
    void SetButton(int button, bool pressed);

    void SetHat(RioHat position);

    void SetAxis(Calibration.JoyAxis axis, int value);
}

/// <summary>Lamp (lighted-button) feedback, sent back to the RIO over serial.</summary>
public interface ILampSink
{
    void SetLamp(int address, byte lampState);
}

/// <summary>Handles internal RIO commands routed from the input map.</summary>
public interface IRioCommandSink
{
    void Execute(RioCommandCode command);
}

/// <summary>Well-known Windows virtual-key codes used by the router for modifiers.</summary>
public static class VirtualKey
{
    public const byte Shift = 0x10;   // VK_SHIFT
    public const byte Control = 0x11; // VK_CONTROL
    public const byte Menu = 0x12;    // VK_MENU (ALT)
}
