/*******************************************************
 HIDAPI - Multi-Platform library for
 communication with HID devices.
 
 Alan Ott
 Signal 11 Software
 
 2010-07-03
 
 Copyright 2010, All Rights Reserved.
 
 At the discretion of the user of this library,
 this software may be licensed under the terms of the
 GNU Public License v3, a BSD-Style license, or the
 original HIDAPI license as outlined in the LICENSE.txt,
 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
 files located at the root of the source distribution.
 These files may also be found in the public source
 code repository located at:
 https://github.com/libusb/hidapi .
 ********************************************************/
#include "../../SDL_internal.h"

#ifdef SDL_JOYSTICK_HIDAPI

/* See Apple Technical Note TN2187 for details on IOHidManager. */

#include <IOKit/hid/IOHIDManager.h>
#include <IOKit/hid/IOHIDKeys.h>
#include <CoreFoundation/CoreFoundation.h>
#include <wchar.h>
#include <locale.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>

#include "hidapi.h"

/* Barrier implementation because Mac OSX doesn't have pthread_barrier.
 It also doesn't have clock_gettime(). So much for POSIX and SUSv2.
 This implementation came from Brent Priddy and was posted on
 StackOverflow. It is used with his permission. */
typedef int pthread_barrierattr_t;
typedef struct pthread_barrier {
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    int count;
    int trip_count;
} pthread_barrier_t;

static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
{
	if(count == 0) {
		errno = EINVAL;
		return -1;
	}
	
	if(pthread_mutex_init(&barrier->mutex, 0) < 0) {
		return -1;
	}
	if(pthread_cond_init(&barrier->cond, 0) < 0) {
		pthread_mutex_destroy(&barrier->mutex);
		return -1;
	}
	barrier->trip_count = count;
	barrier->count = 0;
	
	return 0;
}

static int pthread_barrier_destroy(pthread_barrier_t *barrier)
{
	pthread_cond_destroy(&barrier->cond);
	pthread_mutex_destroy(&barrier->mutex);
	return 0;
}

static int pthread_barrier_wait(pthread_barrier_t *barrier)
{
	pthread_mutex_lock(&barrier->mutex);
	++(barrier->count);
	if(barrier->count >= barrier->trip_count)
	{
		barrier->count = 0;
		pthread_cond_broadcast(&barrier->cond);
		pthread_mutex_unlock(&barrier->mutex);
		return 1;
	}
	else
	{
		pthread_cond_wait(&barrier->cond, &(barrier->mutex));
		pthread_mutex_unlock(&barrier->mutex);
		return 0;
	}
}

static int return_data(hid_device *dev, unsigned char *data, size_t length);

/* Linked List of input reports received from the device. */
struct input_report {
	uint8_t *data;
	size_t len;
	struct input_report *next;
};

struct hid_device_ {
	IOHIDDeviceRef device_handle;
	int blocking;
	int uses_numbered_reports;
	int disconnected;
	CFStringRef run_loop_mode;
	CFRunLoopRef run_loop;
	CFRunLoopSourceRef source;
	uint8_t *input_report_buf;
	CFIndex max_input_report_len;
	struct input_report *input_reports;
	
	pthread_t thread;
	pthread_mutex_t mutex; /* Protects input_reports */
	pthread_cond_t condition;
	pthread_barrier_t barrier; /* Ensures correct startup sequence */
	pthread_barrier_t shutdown_barrier; /* Ensures correct shutdown sequence */
	int shutdown_thread;
};

struct hid_device_list_node
{
	struct hid_device_ *dev;
	struct hid_device_list_node *next;
};

static 	IOHIDManagerRef hid_mgr = 0x0;
static 	struct hid_device_list_node *device_list = 0x0;

static hid_device *new_hid_device(void)
{
	hid_device *dev = (hid_device*)calloc(1, sizeof(hid_device));
	dev->device_handle = NULL;
	dev->blocking = 1;
	dev->uses_numbered_reports = 0;
	dev->disconnected = 0;
	dev->run_loop_mode = NULL;
	dev->run_loop = NULL;
	dev->source = NULL;
	dev->input_report_buf = NULL;
	dev->input_reports = NULL;
	dev->shutdown_thread = 0;
	
	/* Thread objects */
	pthread_mutex_init(&dev->mutex, NULL);
	pthread_cond_init(&dev->condition, NULL);
	pthread_barrier_init(&dev->barrier, NULL, 2);
	pthread_barrier_init(&dev->shutdown_barrier, NULL, 2);
	
	return dev;
}

static void free_hid_device(hid_device *dev)
{
	if (!dev)
		return;
	
	/* Delete any input reports still left over. */
	struct input_report *rpt = dev->input_reports;
	while (rpt) {
		struct input_report *next = rpt->next;
		free(rpt->data);
		free(rpt);
		rpt = next;
	}
	
	/* Free the string and the report buffer. The check for NULL
	 is necessary here as CFRelease() doesn't handle NULL like
	 free() and others do. */
	if (dev->run_loop_mode)
		CFRelease(dev->run_loop_mode);
	if (dev->source)
		CFRelease(dev->source);
	free(dev->input_report_buf);

	if (device_list) {
    	if (device_list->dev == dev) {
    		device_list = device_list->next;
    	}
    	else {
    		struct hid_device_list_node *node = device_list;
    		while (node) {
    			if (node->next && node->next->dev == dev) {
    				struct hid_device_list_node *new_next = node->next->next;
    				free(node->next);
    				node->next = new_next;
    				break;
    			}

    			node = node->next;
    		}
    	}
	}
	
	/* Clean up the thread objects */
	pthread_barrier_destroy(&dev->shutdown_barrier);
	pthread_barrier_destroy(&dev->barrier);
	pthread_cond_destroy(&dev->condition);
	pthread_mutex_destroy(&dev->mutex);
	
	/* Free the structure itself. */
	free(dev);
}

#if 0
static void register_error(hid_device *device, const char *op)
{
	
}
#endif


static int32_t get_int_property(IOHIDDeviceRef device, CFStringRef key)
{
	CFTypeRef ref;
	int32_t value;
	
	ref = IOHIDDeviceGetProperty(device, key);
	if (ref) {
		if (CFGetTypeID(ref) == CFNumberGetTypeID()) {
			CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, &value);
			return value;
		}
	}
	return 0;
}

static unsigned short get_vendor_id(IOHIDDeviceRef device)
{
	return get_int_property(device, CFSTR(kIOHIDVendorIDKey));
}

static unsigned short get_product_id(IOHIDDeviceRef device)
{
	return get_int_property(device, CFSTR(kIOHIDProductIDKey));
}


static int32_t get_max_report_length(IOHIDDeviceRef device)
{
	return get_int_property(device, CFSTR(kIOHIDMaxInputReportSizeKey));
}

static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, wchar_t *buf, size_t len)
{
	CFStringRef str;
	
	if (!len)
		return 0;
	
	str = (CFStringRef)IOHIDDeviceGetProperty(device, prop);
	
	buf[0] = 0;
	
	if (str) {
		len --;
		
		CFIndex str_len = CFStringGetLength(str);
		CFRange range;
		range.location = 0;
		range.length = (str_len > len)? len: str_len;
		CFIndex used_buf_len;
		CFIndex chars_copied;
		chars_copied = CFStringGetBytes(str,
										range,
										kCFStringEncodingUTF32LE,
										(char)'?',
										FALSE,
										(UInt8*)buf,
										len,
										&used_buf_len);
		
		buf[chars_copied] = 0;
		return (int)chars_copied;
	}
	else
		return 0;
	
}

static int get_string_property_utf8(IOHIDDeviceRef device, CFStringRef prop, char *buf, size_t len)
{
	CFStringRef str;
	if (!len)
		return 0;
	
	str = (CFStringRef)IOHIDDeviceGetProperty(device, prop);
	
	buf[0] = 0;
	
	if (str) {
		len--;
		
		CFIndex str_len = CFStringGetLength(str);
		CFRange range;
		range.location = 0;
		range.length = (str_len > len)? len: str_len;
		CFIndex used_buf_len;
		CFIndex chars_copied;
		chars_copied = CFStringGetBytes(str,
										range,
										kCFStringEncodingUTF8,
										(char)'?',
										FALSE,
										(UInt8*)buf,
										len,
										&used_buf_len);
		
		buf[chars_copied] = 0;
		return (int)used_buf_len;
	}
	else
		return 0;
}


static int get_serial_number(IOHIDDeviceRef device, wchar_t *buf, size_t len)
{
	return get_string_property(device, CFSTR(kIOHIDSerialNumberKey), buf, len);
}

static int get_manufacturer_string(IOHIDDeviceRef device, wchar_t *buf, size_t len)
{
	return get_string_property(device, CFSTR(kIOHIDManufacturerKey), buf, len);
}

static int get_product_string(IOHIDDeviceRef device, wchar_t *buf, size_t len)
{
	return get_string_property(device, CFSTR(kIOHIDProductKey), buf, len);
}


/* Implementation of wcsdup() for Mac. */
static wchar_t *dup_wcs(const wchar_t *s)
{
	size_t len = wcslen(s);
	wchar_t *ret = (wchar_t *)malloc((len+1)*sizeof(wchar_t));
	wcscpy(ret, s);
	
	return ret;
}


static int make_path(IOHIDDeviceRef device, char *buf, size_t len)
{
	int res;
	unsigned short vid, pid;
	char transport[32];
	
	buf[0] = '\0';
	
	res = get_string_property_utf8(
								   device, CFSTR(kIOHIDTransportKey),
								   transport, sizeof(transport));
	
	if (!res)
		return -1;
	
	vid = get_vendor_id(device);
	pid = get_product_id(device);
	
	res = snprintf(buf, len, "%s_%04hx_%04hx_%p",
				   transport, vid, pid, device);
	
	
	buf[len-1] = '\0';
	return res+1;
}

/* Initialize the IOHIDManager. Return 0 for success and -1 for failure. */
static int init_hid_manager(void)
{

	/* Initialize all the HID Manager Objects */
	hid_mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
	if (hid_mgr) {
		IOHIDManagerSetDeviceMatching(hid_mgr, NULL);
		IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
		return 0;
	}
	
	return -1;
}

/* Initialize the IOHIDManager if necessary. This is the public function, and
 it is safe to call this function repeatedly. Return 0 for success and -1
 for failure. */
int HID_API_EXPORT hid_init(void)
{
	if (!hid_mgr) {
		return init_hid_manager();
	}
	
	/* Already initialized. */
	return 0;
}

int HID_API_EXPORT hid_exit(void)
{
	if (hid_mgr) {
		/* Close the HID manager. */
		IOHIDManagerClose(hid_mgr, kIOHIDOptionsTypeNone);
		CFRelease(hid_mgr);
		hid_mgr = NULL;
	}
	
	return 0;
}

static void process_pending_events() {
	SInt32 res;
	do {
		res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.001, FALSE);
	} while(res != kCFRunLoopRunFinished && res != kCFRunLoopRunTimedOut);
}

struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	struct hid_device_info *root = NULL; // return object
	struct hid_device_info *cur_dev = NULL;
	CFIndex num_devices;
	int i;
	
	setlocale(LC_ALL,"");
	
	/* Set up the HID Manager if it hasn't been done */
	if (hid_init() < 0)
		return NULL;
	
	/* give the IOHIDManager a chance to update itself */
	process_pending_events();
	
	/* Get a list of the Devices */
	CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr);
	if (!device_set)
		return NULL;

	/* Convert the list into a C array so we can iterate easily. */	
	num_devices = CFSetGetCount(device_set);
	if (!num_devices) {
		CFRelease(device_set);
		return NULL;
	}
	IOHIDDeviceRef *device_array = (IOHIDDeviceRef*)calloc(num_devices, sizeof(IOHIDDeviceRef));
	CFSetGetValues(device_set, (const void **) device_array);
	
	/* Iterate over each device, making an entry for it. */	
	for (i = 0; i < num_devices; i++) {
		unsigned short dev_vid;
		unsigned short dev_pid;
#define BUF_LEN 256
		wchar_t buf[BUF_LEN];
		char cbuf[BUF_LEN];
		
		IOHIDDeviceRef dev = device_array[i];
		
        if (!dev) {
            continue;
        }
		dev_vid = get_vendor_id(dev);
		dev_pid = get_product_id(dev);
		
		/* Check the VID/PID against the arguments */
		if ((vendor_id == 0x0 && product_id == 0x0) ||
		    (vendor_id == dev_vid && product_id == dev_pid)) {
			struct hid_device_info *tmp;
			size_t len;
			
			/* VID/PID match. Create the record. */
			tmp = (struct hid_device_info *)calloc(1, sizeof(struct hid_device_info));
			if (cur_dev) {
				cur_dev->next = tmp;
			}
			else {
				root = tmp;
			}
			cur_dev = tmp;
			
			// Get the Usage Page and Usage for this device.
			cur_dev->usage_page = get_int_property(dev, CFSTR(kIOHIDPrimaryUsagePageKey));
			cur_dev->usage = get_int_property(dev, CFSTR(kIOHIDPrimaryUsageKey));
			
			/* Fill out the record */
			cur_dev->next = NULL;
			len = make_path(dev, cbuf, sizeof(cbuf));
			cur_dev->path = strdup(cbuf);
			
			/* Serial Number */
			get_serial_number(dev, buf, BUF_LEN);
			cur_dev->serial_number = dup_wcs(buf);
			
			/* Manufacturer and Product strings */
			get_manufacturer_string(dev, buf, BUF_LEN);
			cur_dev->manufacturer_string = dup_wcs(buf);
			get_product_string(dev, buf, BUF_LEN);
			cur_dev->product_string = dup_wcs(buf);
			
			/* VID/PID */
			cur_dev->vendor_id = dev_vid;
			cur_dev->product_id = dev_pid;
			
			/* Release Number */
			cur_dev->release_number = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey));
			
			/* Interface Number (Unsupported on Mac)*/
			cur_dev->interface_number = -1;
		}
	}
	
	free(device_array);
	CFRelease(device_set);
	
	return root;
}

void  HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
{
	/* This function is identical to the Linux version. Platform independent. */
	struct hid_device_info *d = devs;
	while (d) {
		struct hid_device_info *next = d->next;
		free(d->path);
		free(d->serial_number);
		free(d->manufacturer_string);
		free(d->product_string);
		free(d);
		d = next;
	}
}

hid_device * HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
{
	/* This function is identical to the Linux version. Platform independent. */
	struct hid_device_info *devs, *cur_dev;
	const char *path_to_open = NULL;
	hid_device * handle = NULL;
	
	devs = hid_enumerate(vendor_id, product_id);
	cur_dev = devs;
	while (cur_dev) {
		if (cur_dev->vendor_id == vendor_id &&
		    cur_dev->product_id == product_id) {
			if (serial_number) {
				if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
					path_to_open = cur_dev->path;
					break;
				}
			}
			else {
				path_to_open = cur_dev->path;
				break;
			}
		}
		cur_dev = cur_dev->next;
	}
	
	if (path_to_open) {
		/* Open the device */
		handle = hid_open_path(path_to_open, 0);
	}
	
	hid_free_enumeration(devs);
	
	return handle;
}

static void hid_device_removal_callback(void *context, IOReturn result,
                                        void *sender)
{
	/* Stop the Run Loop for this device. */
	hid_device *dev = (hid_device *)context;

	// The device removal callback is sometimes called even after being
	// unregistered, leading to a crash when trying to access fields in
	// the already freed hid_device. We keep a linked list of all created
	// hid_device's so that the one being removed can be checked against
	// the list to see if it really hasn't been closed yet and needs to
	// be dealt with here.
	struct hid_device_list_node *node = device_list;
	while (node) {
		if (node->dev == dev) {
			dev->disconnected = 1;
			CFRunLoopStop(dev->run_loop);
			break;
		}

		node = node->next;
	}
}

/* The Run Loop calls this function for each input report received.
 This function puts the data into a linked list to be picked up by
 hid_read(). */
static void hid_report_callback(void *context, IOReturn result, void *sender,
								IOHIDReportType report_type, uint32_t report_id,
								uint8_t *report, CFIndex report_length)
{
	struct input_report *rpt;
	hid_device *dev = (hid_device *)context;
	
	/* Make a new Input Report object */
	rpt = (struct input_report *)calloc(1, sizeof(struct input_report));
	rpt->data = (uint8_t *)calloc(1, report_length);
	memcpy(rpt->data, report, report_length);
	rpt->len = report_length;
	rpt->next = NULL;
	
	/* Lock this section */
	pthread_mutex_lock(&dev->mutex);
	
	/* Attach the new report object to the end of the list. */
	if (dev->input_reports == NULL) {
		/* The list is empty. Put it at the root. */
		dev->input_reports = rpt;
	}
	else {
		/* Find the end of the list and attach. */
		struct input_report *cur = dev->input_reports;
		int num_queued = 0;
		while (cur->next != NULL) {
			cur = cur->next;
			num_queued++;
		}
		cur->next = rpt;
		
		/* Pop one off if we've reached 30 in the queue. This
		 way we don't grow forever if the user never reads
		 anything from the device. */
		if (num_queued > 30) {
			return_data(dev, NULL, 0);
		}
	}
	
	/* Signal a waiting thread that there is data. */
	pthread_cond_signal(&dev->condition);
	
	/* Unlock */
	pthread_mutex_unlock(&dev->mutex);
	
}

/* This gets called when the read_thred's run loop gets signaled by
 hid_close(), and serves to stop the read_thread's run loop. */
static void perform_signal_callback(void *context)
{
	hid_device *dev = (hid_device *)context;
	CFRunLoopStop(dev->run_loop); //TODO: CFRunLoopGetCurrent()
}

static void *read_thread(void *param)
{
	hid_device *dev = (hid_device *)param;
	
	/* Move the device's run loop to this thread. */
	IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode);
	
	/* Create the RunLoopSource which is used to signal the
	 event loop to stop when hid_close() is called. */
	CFRunLoopSourceContext ctx;
	memset(&ctx, 0, sizeof(ctx));
	ctx.version = 0;
	ctx.info = dev;
	ctx.perform = &perform_signal_callback;
	dev->source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0/*order*/, &ctx);
	CFRunLoopAddSource(CFRunLoopGetCurrent(), dev->source, dev->run_loop_mode);
	
	/* Store off the Run Loop so it can be stopped from hid_close()
	 and on device disconnection. */
	dev->run_loop = CFRunLoopGetCurrent();
	
	/* Notify the main thread that the read thread is up and running. */
	pthread_barrier_wait(&dev->barrier);
	
	/* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input
	 reports into the hid_report_callback(). */
	SInt32 code;
	while (!dev->shutdown_thread && !dev->disconnected) {
		code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE);
		/* Return if the device has been disconnected */
		if (code == kCFRunLoopRunFinished) {
			dev->disconnected = 1;
			break;
		}
		
		
		/* Break if The Run Loop returns Finished or Stopped. */
		if (code != kCFRunLoopRunTimedOut &&
		    code != kCFRunLoopRunHandledSource) {
			/* There was some kind of error. Setting
			 shutdown seems to make sense, but
			 there may be something else more appropriate */
			dev->shutdown_thread = 1;
			break;
		}
	}
	
	/* Now that the read thread is stopping, Wake any threads which are
	 waiting on data (in hid_read_timeout()). Do this under a mutex to
	 make sure that a thread which is about to go to sleep waiting on
	 the condition acutally will go to sleep before the condition is
	 signaled. */
	pthread_mutex_lock(&dev->mutex);
	pthread_cond_broadcast(&dev->condition);
	pthread_mutex_unlock(&dev->mutex);
	
	/* Wait here until hid_close() is called and makes it past
	 the call to CFRunLoopWakeUp(). This thread still needs to
	 be valid when that function is called on the other thread. */
	pthread_barrier_wait(&dev->shutdown_barrier);
	
	return NULL;
}

hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
{
  	int i;
	hid_device *dev = NULL;
	CFIndex num_devices;
	
	dev = new_hid_device();
	
	/* Set up the HID Manager if it hasn't been done */
	if (hid_init() < 0)
		return NULL;
	
	/* give the IOHIDManager a chance to update itself */
	process_pending_events();
	
	CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr);
	
	num_devices = CFSetGetCount(device_set);
	IOHIDDeviceRef *device_array = (IOHIDDeviceRef *)calloc(num_devices, sizeof(IOHIDDeviceRef));
	CFSetGetValues(device_set, (const void **) device_array);	
	for (i = 0; i < num_devices; i++) {
		char cbuf[BUF_LEN];
		size_t len;
		IOHIDDeviceRef os_dev = device_array[i];
		
		len = make_path(os_dev, cbuf, sizeof(cbuf));
		if (!strcmp(cbuf, path)) {
			// Matched Paths. Open this Device.
			IOReturn ret = IOHIDDeviceOpen(os_dev, kIOHIDOptionsTypeNone);
			if (ret == kIOReturnSuccess) {
				char str[32];
				
				free(device_array);
				CFRelease(device_set);
				dev->device_handle = os_dev;
				
				/* Create the buffers for receiving data */
				dev->max_input_report_len = (CFIndex) get_max_report_length(os_dev);
				dev->input_report_buf = (uint8_t *)calloc(dev->max_input_report_len, sizeof(uint8_t));
				
				/* Create the Run Loop Mode for this device.
				 printing the reference seems to work. */
				sprintf(str, "HIDAPI_%p", os_dev);
				dev->run_loop_mode = 
				CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII);
				
				/* Attach the device to a Run Loop */
				IOHIDDeviceRegisterInputReportCallback(
													   os_dev, dev->input_report_buf, dev->max_input_report_len,
													   &hid_report_callback, dev);
				IOHIDDeviceRegisterRemovalCallback(dev->device_handle, hid_device_removal_callback, dev);

				struct hid_device_list_node *node = (struct hid_device_list_node *)calloc(1, sizeof(struct hid_device_list_node));
				node->dev = dev;
				node->next = device_list;
				device_list = node;

				/* Start the read thread */
				pthread_create(&dev->thread, NULL, read_thread, dev);
				
				/* Wait here for the read thread to be initialized. */
				pthread_barrier_wait(&dev->barrier);
				
				return dev;
			}
			else {
				goto return_error;
			}
		}
	}
	
return_error:
	free(device_array);
	CFRelease(device_set);
	free_hid_device(dev);
	return NULL;
}

static int set_report(hid_device *dev, IOHIDReportType type, const unsigned char *data, size_t length)
{
	const char *pass_through_magic = "MAGIC0";
	size_t pass_through_magic_length = strlen(pass_through_magic);
	unsigned char report_id = data[0];
	const unsigned char *data_to_send;
	size_t length_to_send;
	IOReturn res;
	
	/* Return if the device has been disconnected. */
   	if (dev->disconnected)
   		return -1;
	
	if (report_id == 0x0) {
		/* Not using numbered Reports.
		 Don't send the report number. */
		data_to_send = data+1;
		length_to_send = length-1;
	}
	else if (length > 6 && memcmp(data, pass_through_magic, pass_through_magic_length) == 0) {
		report_id = data[pass_through_magic_length];
		data_to_send = data+pass_through_magic_length;
		length_to_send = length-pass_through_magic_length;
	}
	else {
		/* Using numbered Reports.
		 Send the Report Number */
		data_to_send = data;
		length_to_send = length;
	}
	
	if (!dev->disconnected) {
		res = IOHIDDeviceSetReport(dev->device_handle,
								   type,
								   report_id, /* Report ID*/
								   data_to_send, length_to_send);
		
		if (res == kIOReturnSuccess) {
			return (int)length;
		}
		else if (res == kIOReturnUnsupported) {
			/*printf("kIOReturnUnsupported\n");*/
			return -1;
		}
		else {
			/*printf("0x%x\n", res);*/
			return -1;
		}
	}
	
	return -1;
}

int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
{
	return set_report(dev, kIOHIDReportTypeOutput, data, length);
}

/* Helper function, so that this isn't duplicated in hid_read(). */
static int return_data(hid_device *dev, unsigned char *data, size_t length)
{
	/* Copy the data out of the linked list item (rpt) into the
	 return buffer (data), and delete the liked list item. */
	struct input_report *rpt = dev->input_reports;
	size_t len = (length < rpt->len)? length: rpt->len;
	memcpy(data, rpt->data, len);
	dev->input_reports = rpt->next;
	free(rpt->data);
	free(rpt);
	return (int)len;
}

static int cond_wait(const hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex)
{
	while (!dev->input_reports) {
		int res = pthread_cond_wait(cond, mutex);
		if (res != 0)
			return res;
		
		/* A res of 0 means we may have been signaled or it may
		 be a spurious wakeup. Check to see that there's acutally
		 data in the queue before returning, and if not, go back
		 to sleep. See the pthread_cond_timedwait() man page for
		 details. */
		
		if (dev->shutdown_thread || dev->disconnected)
			return -1;
	}
	
	return 0;
}

static int cond_timedwait(const hid_device *dev, pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
{
	while (!dev->input_reports) {
		int res = pthread_cond_timedwait(cond, mutex, abstime);
		if (res != 0)
			return res;
		
		/* A res of 0 means we may have been signaled or it may
		 be a spurious wakeup. Check to see that there's acutally
		 data in the queue before returning, and if not, go back
		 to sleep. See the pthread_cond_timedwait() man page for
		 details. */
		
		if (dev->shutdown_thread || dev->disconnected)
			return -1;
	}
	
	return 0;
	
}

int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
{
	int bytes_read = -1;
	
	/* Lock the access to the report list. */
	pthread_mutex_lock(&dev->mutex);
	
	/* There's an input report queued up. Return it. */
	if (dev->input_reports) {
		/* Return the first one */
		bytes_read = return_data(dev, data, length);
		goto ret;
	}
	
	/* Return if the device has been disconnected. */
	if (dev->disconnected) {
		bytes_read = -1;
		goto ret;
	}
	
	if (dev->shutdown_thread) {
		/* This means the device has been closed (or there
		 has been an error. An error code of -1 should
		 be returned. */
		bytes_read = -1;
		goto ret;
	}
	
	/* There is no data. Go to sleep and wait for data. */
	
	if (milliseconds == -1) {
		/* Blocking */
		int res;
		res = cond_wait(dev, &dev->condition, &dev->mutex);
		if (res == 0)
			bytes_read = return_data(dev, data, length);
		else {
			/* There was an error, or a device disconnection. */
			bytes_read = -1;
		}
	}
	else if (milliseconds > 0) {
		/* Non-blocking, but called with timeout. */
		int res;
		struct timespec ts;
		struct timeval tv;
		gettimeofday(&tv, NULL);
		TIMEVAL_TO_TIMESPEC(&tv, &ts);
		ts.tv_sec += milliseconds / 1000;
		ts.tv_nsec += (milliseconds % 1000) * 1000000;
		if (ts.tv_nsec >= 1000000000L) {
			ts.tv_sec++;
			ts.tv_nsec -= 1000000000L;
		}
		
		res = cond_timedwait(dev, &dev->condition, &dev->mutex, &ts);
		if (res == 0)
			bytes_read = return_data(dev, data, length);
		else if (res == ETIMEDOUT)
			bytes_read = 0;
		else
			bytes_read = -1;
	}
	else {
		/* Purely non-blocking */
		bytes_read = 0;
	}
	
ret:
	/* Unlock */
	pthread_mutex_unlock(&dev->mutex);
	return bytes_read;
}

int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
{
	return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
}

int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
{
	/* All Nonblocking operation is handled by the library. */
	dev->blocking = !nonblock;
	
	return 0;
}

int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
{
	return set_report(dev, kIOHIDReportTypeFeature, data, length);
}

int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
{
	CFIndex len = length;
	IOReturn res;
	
	/* Return if the device has been unplugged. */
	if (dev->disconnected)
		return -1;
	
	int skipped_report_id = 0;
	int report_number = data[0];
	if (report_number == 0x0) {
		/* Offset the return buffer by 1, so that the report ID
		 will remain in byte 0. */
		data++;
		len--;
		skipped_report_id = 1;
	}
	
	res = IOHIDDeviceGetReport(dev->device_handle,
	                           kIOHIDReportTypeFeature,
	                           report_number, /* Report ID */
	                           data, &len);
	if (res != kIOReturnSuccess)
		return -1;

	if (skipped_report_id)
		len++;

	return (int)len;
}


void HID_API_EXPORT hid_close(hid_device *dev)
{
	if (!dev)
		return;
	
	/* Disconnect the report callback before close. */
	if (!dev->disconnected) {
		IOHIDDeviceRegisterInputReportCallback(
											   dev->device_handle, dev->input_report_buf, dev->max_input_report_len,
											   NULL, dev);
		IOHIDDeviceRegisterRemovalCallback(dev->device_handle, NULL, dev);
		IOHIDDeviceUnscheduleFromRunLoop(dev->device_handle, dev->run_loop, dev->run_loop_mode);
		IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
	}
	
	/* Cause read_thread() to stop. */
	dev->shutdown_thread = 1;
	
	/* Wake up the run thread's event loop so that the thread can exit. */
	CFRunLoopSourceSignal(dev->source);
	CFRunLoopWakeUp(dev->run_loop);
	
	/* Notify the read thread that it can shut down now. */
	pthread_barrier_wait(&dev->shutdown_barrier);
	
	/* Wait for read_thread() to end. */
	pthread_join(dev->thread, NULL);
	
	/* Close the OS handle to the device, but only if it's not
	 been unplugged. If it's been unplugged, then calling
	 IOHIDDeviceClose() will crash. */
	if (!dev->disconnected) {
		IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone);
	}
	
	/* Clear out the queue of received reports. */
	pthread_mutex_lock(&dev->mutex);
	while (dev->input_reports) {
		return_data(dev, NULL, 0);
	}
	pthread_mutex_unlock(&dev->mutex);
	
	free_hid_device(dev);
}

int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
	return get_manufacturer_string(dev->device_handle, string, maxlen);
}

int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
	return get_product_string(dev->device_handle, string, maxlen);
}

int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
	return get_serial_number(dev->device_handle, string, maxlen);
}

int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
{
	// TODO:
	
	return 0;
}


HID_API_EXPORT const wchar_t * HID_API_CALL  hid_error(hid_device *dev)
{
	// TODO:
	
	return NULL;
}






#if 0
static int32_t get_location_id(IOHIDDeviceRef device)
{
	return get_int_property(device, CFSTR(kIOHIDLocationIDKey));
}

static int32_t get_usage(IOHIDDeviceRef device)
{
	int32_t res;
	res = get_int_property(device, CFSTR(kIOHIDDeviceUsageKey));
	if (!res)
		res = get_int_property(device, CFSTR(kIOHIDPrimaryUsageKey));
	return res;
}

static int32_t get_usage_page(IOHIDDeviceRef device)
{
	int32_t res;
	res = get_int_property(device, CFSTR(kIOHIDDeviceUsagePageKey));
	if (!res)
		res = get_int_property(device, CFSTR(kIOHIDPrimaryUsagePageKey));
	return res;
}

static int get_transport(IOHIDDeviceRef device, wchar_t *buf, size_t len)
{
	return get_string_property(device, CFSTR(kIOHIDTransportKey), buf, len);
}


int main(void)
{
	IOHIDManagerRef mgr;
	int i;
	
	mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
	IOHIDManagerSetDeviceMatching(mgr, NULL);
	IOHIDManagerOpen(mgr, kIOHIDOptionsTypeNone);
	
	CFSetRef device_set = IOHIDManagerCopyDevices(mgr);
	
	CFIndex num_devices = CFSetGetCount(device_set);
	IOHIDDeviceRef *device_array = calloc(num_devices, sizeof(IOHIDDeviceRef));
	CFSetGetValues(device_set, (const void **) device_array);
	
	setlocale(LC_ALL, "");
	
	for (i = 0; i < num_devices; i++) {
		IOHIDDeviceRef dev = device_array[i];
		printf("Device: %p\n", dev);
		printf("  %04hx %04hx\n", get_vendor_id(dev), get_product_id(dev));
		
		wchar_t serial[256], buf[256];
		char cbuf[256];
		get_serial_number(dev, serial, 256);
		
		
		printf("  Serial: %ls\n", serial);
		printf("  Loc: %ld\n", get_location_id(dev));
		get_transport(dev, buf, 256);
		printf("  Trans: %ls\n", buf);
		make_path(dev, cbuf, 256);
		printf("  Path: %s\n", cbuf);
		
	}
	
	return 0;
}
#endif

#endif /* SDL_JOYSTICK_HIDAPI */
