
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "debugrep.h"
#include "usbjoystick.h"
#include "errors.h"
#include "joyhelp.h"

#include "cmdmap.h"


// Joystick_SetStick / *USBJoystick_SetStick: assign a device (slot) to a legacy
// Joystick_Read "stick number" (0..JOY_MAX-1) - the number that classic
// Joystick_Read/Status calls index by, and that JoySetup shows as "Stick N".
// A device attribute, not an input->output binding, so it is separate from the
// binding table (see h.binding).


_kernel_oserror *joy_set_stick(uint32_t slot, int32_t number)
{
  _kernel_oserror *err = validate_joystick_slot("Joystick_SetStick", slot);
  if (err) return err;

  if (number >= JOY_MAX) {
    debug_printf("Joystick_SetStick: Bad arguments, number (%d) is out of range\n", number);
    return geterror(Error_BadNoParms);
  }

  err = validate_joystick_slot_active("Joystick_SetStick", slot);
  if (err) return err;

  // A stick number is unique: clear it from any other device first.
  for (uint32_t i=0; i<JOY_MAX; i++) {
    if (joy_data[i].mapped_number == number)
      joy_data[i].mapped_number = NOT_MAPPED;
  }

  joy_data[slot].mapped_number = number;

  return NULL;
}


_kernel_oserror *command_set_stick(const char *args, int32_t argc)
{
  if (argc != 2) {
    debug_printf("command_set_stick: Bad arguments, argc is not 2 (it is %d)\n", argc);
    return geterror(Error_BadNoParms);
  }

  const char s[2] = " ";
  char *t = NULL;

  uint32_t slot = JOY_MAX;      // the usb joystick slot
  int32_t number = JOY_MAX;     // the legacy api number (0-based)

  t = strtok((char*)args, s);
  if (t) slot = atoi(t);

  t = strtok(NULL, s);
  if (t) number = atoi(t);

  return joy_set_stick(slot, number);
}


_kernel_oserror *swi_joystick_set_stick(_kernel_swi_regs *r)
{
  return joy_set_stick((uint32_t) r->r[0], (int32_t) r->r[1]);
}
