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

#include "swis.h"
#include "Global/RISCOS.h"

#include "oslib/os.h"

#include "usbjoystick.h"
#include "usb.h"
#include "joydev.h"
#include "device.h"


static const uint8_t uhid_xb360gp_report_descr[] = {UHID_XB360GP_REPORT_DESCR()};


// todo: can we get away with assuming protocol==0 for standard HID devices?  keyboard is 2
static const struct joy_device_struct joy_devices[] = {
  { 0xFF, 0x5D,   1, 0x45E, 0x028E, "XBOX360 wired controller"         , JOY_TYPE_XBOX360  , (void*)&uhid_xb360gp_report_descr, sizeof(uhid_xb360gp_report_descr), 0, { 0x01, 0x03, 0x00 }                                                      ,  3, { AXIS_Y, AXIS_RY }, 2, 0 },
  { 0xFF, 0x5D, 129, 0x45E, 0x0719, "XBOX360 wireless controller"      , JOY_TYPE_XBOX360WL, (void*)&uhid_xb360gp_report_descr, sizeof(uhid_xb360gp_report_descr), 4, { 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 12, { AXIS_Y, AXIS_RY }, 2, &xbox360wireless_data_validator },
  { 0x03, 0x00,   0,     0,     0 , "Standard HID controller (no boot)", JOY_TYPE_STANDARD ,                                 0,                                 0, 0, { 0x00 }                                                                  ,  0, { 0 }              , 0, 0 },
  { 0x03, 0x01,   0,     0,     0 , "Standard HID controller (boot)"   , JOY_TYPE_STANDARD ,                                 0,                                 0, 0, { 0x00 }                                                                  ,  0, { 0 }              , 0, 0 }
};

uint32_t joy_devices_count = sizeof(joy_devices)/sizeof(joy_devices[0]);




osbool xbox360wireless_data_validator(char *d)
{
  return (osbool)(d[0] == 0 && d[1] == 1);
}



struct joy_device_struct *lookup_joy_device(uint8_t iClass, uint8_t iSubClass, uint8_t iProtocol, uint16_t vendor, uint16_t product)
{
  // look for a full match
  for (uint32_t i=0; i<joy_devices_count; i++) {
    if (joy_devices[i].interface_class == iClass &&
      joy_devices[i].interface_subclass == iSubClass &&
      joy_devices[i].interface_protocol == iProtocol &&
      joy_devices[i].vendor_id == vendor &&
      joy_devices[i].product_id == product)
      return (struct joy_device_struct*)&(joy_devices[i]);
  }

  // look for a match without vendor and product ids
  for (uint32_t i=0; i<joy_devices_count; i++) {
    if (joy_devices[i].interface_class == iClass &&
      joy_devices[i].interface_subclass == iSubClass &&
      joy_devices[i].interface_protocol == iProtocol &&
      joy_devices[i].vendor_id == 0 &&
      joy_devices[i].product_id == 0)
      return (struct joy_device_struct*)&(joy_devices[i]);
  }

  return 0;
}

