//=================== Copyright Valve Corporation, All rights reserved. =======
//
// Purpose: A wrapper implementing "HID" API for Android
//
//          This layer glues the hidapi API to Android's USB and BLE stack.
//
//=============================================================================

#include <jni.h>
#include <android/log.h>
#include <pthread.h>
#include <errno.h>	// For ETIMEDOUT and ECONNRESET
#include <stdlib.h> // For malloc() and free()
#include <string.h>	// For memcpy()

#define TAG "hidapi"

// Have error log always available
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)

#ifdef DEBUG
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#else
#define LOGV(...)
#define LOGD(...)
#endif

#define SDL_JAVA_PREFIX                                 org_libsdl_app
#define CONCAT1(prefix, class, function)                CONCAT2(prefix, class, function)
#define CONCAT2(prefix, class, function)                Java_ ## prefix ## _ ## class ## _ ## function
#define HID_DEVICE_MANAGER_JAVA_INTERFACE(function)     CONCAT1(SDL_JAVA_PREFIX, HIDDeviceManager, function)

#include "../hidapi/hidapi.h"

typedef uint32_t uint32;
typedef uint64_t uint64;


struct hid_device_
{
	int m_nId;
	int m_nDeviceRefCount;
};

static JavaVM *g_JVM;
static pthread_key_t g_ThreadKey;

template<class T>
class hid_device_ref
{
public:
	hid_device_ref( T *pObject = nullptr ) : m_pObject( nullptr )
	{
		SetObject( pObject );
	}

	hid_device_ref( const hid_device_ref &rhs ) : m_pObject( nullptr )
	{
		SetObject( rhs.GetObject() );
	}

	~hid_device_ref()
	{
		SetObject( nullptr );
	}

	void SetObject( T *pObject )
	{
		if ( m_pObject && m_pObject->DecrementRefCount() == 0 )
		{
			delete m_pObject;
		}

		m_pObject = pObject;

		if ( m_pObject )
		{
			m_pObject->IncrementRefCount();
		}
	}

	hid_device_ref &operator =( T *pObject )
	{
		SetObject( pObject );
		return *this;
	}

	hid_device_ref &operator =( const hid_device_ref &rhs )
	{
		SetObject( rhs.GetObject() );
		return *this;
	}

	T *GetObject() const
	{
		return m_pObject;
	}

	T* operator->() const
	{
		return m_pObject;
	}

	operator bool() const
	{
		return ( m_pObject != nullptr );
	}

private:
	T *m_pObject;
};

class hid_mutex_guard
{
public:
	hid_mutex_guard( pthread_mutex_t *pMutex ) : m_pMutex( pMutex )
	{
		pthread_mutex_lock( m_pMutex );
	}
	~hid_mutex_guard()
	{
		pthread_mutex_unlock( m_pMutex );
	}

private:
	pthread_mutex_t *m_pMutex;
};

class hid_buffer
{
public:
	hid_buffer() : m_pData( nullptr ), m_nSize( 0 ), m_nAllocated( 0 )
	{
	}

	hid_buffer( const uint8_t *pData, size_t nSize ) : m_pData( nullptr ), m_nSize( 0 ), m_nAllocated( 0 )
	{
		assign( pData, nSize );
	}

	~hid_buffer()
	{
		delete[] m_pData;
	}

	void assign( const uint8_t *pData, size_t nSize )
	{
		if ( nSize > m_nAllocated )
		{
			delete[] m_pData;
			m_pData = new uint8_t[ nSize ];
			m_nAllocated = nSize;
		}

		m_nSize = nSize;
		memcpy( m_pData, pData, nSize );
	}

	void clear()
	{
		m_nSize = 0;
	}

	size_t size() const
	{
		return m_nSize;
	}

	const uint8_t *data() const
	{
		return m_pData;
	}

private:
	uint8_t *m_pData;
	size_t m_nSize;
	size_t m_nAllocated;
};

class hid_buffer_pool
{
public:
	hid_buffer_pool() : m_nSize( 0 ), m_pHead( nullptr ), m_pTail( nullptr ), m_pFree( nullptr )
	{
	}

	~hid_buffer_pool()
	{
		clear();

		while ( m_pFree )
		{
			hid_buffer_entry *pEntry = m_pFree;
			m_pFree = m_pFree->m_pNext;
			delete pEntry;
		}
	}

	size_t size() const { return m_nSize; }

	const hid_buffer &front() const { return m_pHead->m_buffer; }

	void pop_front()
	{
		hid_buffer_entry *pEntry = m_pHead;
		if ( pEntry )
		{
			m_pHead = pEntry->m_pNext;
			if ( !m_pHead )
			{
				m_pTail = nullptr;
			}
			pEntry->m_pNext = m_pFree;
			m_pFree = pEntry;
			--m_nSize;
		}
	}

	void emplace_back( const uint8_t *pData, size_t nSize )
	{
		hid_buffer_entry *pEntry;

		if ( m_pFree )
		{
			pEntry = m_pFree;
			m_pFree = m_pFree->m_pNext;
		}
		else
		{
			pEntry = new hid_buffer_entry;
		}
		pEntry->m_pNext = nullptr;

		if ( m_pTail )
		{
			m_pTail->m_pNext = pEntry;
		}
		else
		{
			m_pHead = pEntry;
		}
		m_pTail = pEntry;

		pEntry->m_buffer.assign( pData, nSize );
		++m_nSize;
	}

	void clear()
	{
		while ( size() > 0 )
		{
			pop_front();
		}
	}

private:
	struct hid_buffer_entry
	{
		hid_buffer m_buffer;
		hid_buffer_entry *m_pNext;
	};

	size_t m_nSize;
	hid_buffer_entry *m_pHead;
	hid_buffer_entry *m_pTail;
	hid_buffer_entry *m_pFree;
};

static jbyteArray NewByteArray( JNIEnv* env, const uint8_t *pData, size_t nDataLen )
{
	jbyteArray array = env->NewByteArray( nDataLen );
	jbyte *pBuf = env->GetByteArrayElements( array, NULL );
	memcpy( pBuf, pData, nDataLen );
	env->ReleaseByteArrayElements( array, pBuf, 0 );

	return array;
}

static char *CreateStringFromJString( JNIEnv *env, const jstring &sString )
{
	size_t nLength = env->GetStringUTFLength( sString );
	const char *pjChars = env->GetStringUTFChars( sString, NULL );
	char *psString = (char*)malloc( nLength + 1 );
	memcpy( psString, pjChars, nLength );
	psString[ nLength ] = '\0';
	env->ReleaseStringUTFChars( sString, pjChars );
	return psString;
}

static wchar_t *CreateWStringFromJString( JNIEnv *env, const jstring &sString )
{
	size_t nLength = env->GetStringLength( sString );
	const jchar *pjChars = env->GetStringChars( sString, NULL );
	wchar_t *pwString = (wchar_t*)malloc( ( nLength + 1 ) * sizeof( wchar_t ) );
	wchar_t *pwChars = pwString;
	for ( size_t iIndex = 0; iIndex < nLength; ++iIndex )
	{
		pwChars[ iIndex ] = pjChars[ iIndex ];
	}
	pwString[ nLength ] = '\0';
	env->ReleaseStringChars( sString, pjChars );
	return pwString;
}

static wchar_t *CreateWStringFromWString( const wchar_t *pwSrc )
{
	size_t nLength = wcslen( pwSrc );
	wchar_t *pwString = (wchar_t*)malloc( ( nLength + 1 ) * sizeof( wchar_t ) );
	memcpy( pwString, pwSrc, nLength * sizeof( wchar_t ) );
	pwString[ nLength ] = '\0';
	return pwString;
}

static hid_device_info *CopyHIDDeviceInfo( const hid_device_info *pInfo )
{
	hid_device_info *pCopy = new hid_device_info;
	*pCopy = *pInfo;
	pCopy->path = strdup( pInfo->path );
	pCopy->product_string = CreateWStringFromWString( pInfo->product_string );
	pCopy->manufacturer_string = CreateWStringFromWString( pInfo->manufacturer_string );
	pCopy->serial_number = CreateWStringFromWString( pInfo->serial_number );
	return pCopy;
}

static void FreeHIDDeviceInfo( hid_device_info *pInfo )
{
	free( pInfo->path );
	free( pInfo->serial_number );
	free( pInfo->manufacturer_string );
	free( pInfo->product_string );
	delete pInfo;
}

static jclass  g_HIDDeviceManagerCallbackClass;
static jobject g_HIDDeviceManagerCallbackHandler;
static jmethodID g_midHIDDeviceManagerOpen;
static jmethodID g_midHIDDeviceManagerSendOutputReport;
static jmethodID g_midHIDDeviceManagerSendFeatureReport;
static jmethodID g_midHIDDeviceManagerGetFeatureReport;
static jmethodID g_midHIDDeviceManagerClose;

static uint64_t get_timespec_ms( const struct timespec &ts )
{
	return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}

class CHIDDevice
{
public:
	CHIDDevice( int nDeviceID, hid_device_info *pInfo )
	{
		m_nId = nDeviceID;
		m_pInfo = pInfo;

		// The Bluetooth Steam Controller needs special handling
		const int VALVE_USB_VID	= 0x28DE;
		const int D0G_BLE2_PID = 0x1106;
		if ( pInfo->vendor_id == VALVE_USB_VID && pInfo->product_id == D0G_BLE2_PID )
		{
			m_bIsBLESteamController = true;
		}
	}

	~CHIDDevice()
	{
		FreeHIDDeviceInfo( m_pInfo );

		// Note that we don't delete m_pDevice, as the app may still have a reference to it
	}

	int IncrementRefCount()
	{
		int nValue;
		pthread_mutex_lock( &m_refCountLock );
		nValue = ++m_nRefCount;
		pthread_mutex_unlock( &m_refCountLock );
		return nValue;
	}

	int DecrementRefCount()
	{
		int nValue;
		pthread_mutex_lock( &m_refCountLock );
		nValue = --m_nRefCount;
		pthread_mutex_unlock( &m_refCountLock );
		return nValue;
	}

	int GetId()
	{
		return m_nId;
	}

	const hid_device_info *GetDeviceInfo()
	{
		return m_pInfo;
	}

	hid_device *GetDevice()
	{
		return m_pDevice;
	}

	void ExceptionCheck( JNIEnv *env, const char *pszMethodName )
	{
		if ( env->ExceptionCheck() )
		{
			// Get our exception
			jthrowable jExcept = env->ExceptionOccurred();

			// Clear the exception so we can call JNI again
			env->ExceptionClear();

			// Get our exception message
			jclass jExceptClass = env->GetObjectClass( jExcept );
			jmethodID jMessageMethod = env->GetMethodID( jExceptClass, "getMessage", "()Ljava/lang/String;" );
			jstring jMessage = (jstring)( env->CallObjectMethod( jExcept, jMessageMethod ) );
			const char *pszMessage = env->GetStringUTFChars( jMessage, NULL );

			// ...and log it.
			LOGE( "CHIDDevice::%s threw an exception: %s", pszMethodName, pszMessage );

			// Cleanup
			env->ReleaseStringUTFChars( jMessage, pszMessage );
			env->DeleteLocalRef( jMessage );
			env->DeleteLocalRef( jExceptClass );
			env->DeleteLocalRef( jExcept );
		}
	}

	bool BOpen()
	{
		// Make sure thread is attached to JVM/env
		JNIEnv *env;
		g_JVM->AttachCurrentThread( &env, NULL );
		pthread_setspecific( g_ThreadKey, (void*)env );

		m_bIsWaitingForOpen = false;
		m_bOpenResult = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerOpen, m_nId );
		ExceptionCheck( env, "BOpen" );

		if ( m_bIsWaitingForOpen )
		{
			hid_mutex_guard cvl( &m_cvLock );

			const int OPEN_TIMEOUT_SECONDS = 60;
			struct timespec ts, endtime;
			clock_gettime( CLOCK_REALTIME, &ts );
			endtime = ts;
			endtime.tv_sec += OPEN_TIMEOUT_SECONDS;
			do
			{
				if ( pthread_cond_timedwait( &m_cv, &m_cvLock, &endtime ) != 0 )
				{
					break;
				}
			}
			while ( m_bIsWaitingForOpen && get_timespec_ms( ts ) < get_timespec_ms( endtime ) );
		}

		if ( !m_bOpenResult )
		{
			if ( m_bIsWaitingForOpen )
			{
				LOGV( "Device open failed - timed out waiting for device permission" );
			}
			else
			{
				LOGV( "Device open failed" );
			}
			return false;
		}

		m_pDevice = new hid_device;
		m_pDevice->m_nId = m_nId;
		m_pDevice->m_nDeviceRefCount = 1;
		LOGD("Creating device %d (%p), refCount = 1\n", m_pDevice->m_nId, m_pDevice);
		return true;
	}

	void SetOpenPending()
	{
		m_bIsWaitingForOpen = true;
	}

	void SetOpenResult( bool bResult )
	{
		if ( m_bIsWaitingForOpen )
		{
			m_bOpenResult = bResult;
			m_bIsWaitingForOpen = false;
			pthread_cond_signal( &m_cv );
		}
	}

	void ProcessInput( const uint8_t *pBuf, size_t nBufSize )
	{
		hid_mutex_guard l( &m_dataLock );

		size_t MAX_REPORT_QUEUE_SIZE = 16;
		if ( m_vecData.size() >= MAX_REPORT_QUEUE_SIZE )
		{
			m_vecData.pop_front();
		}
		m_vecData.emplace_back( pBuf, nBufSize );
	}

	int GetInput( unsigned char *data, size_t length )
	{
		hid_mutex_guard l( &m_dataLock );

		if ( m_vecData.size() == 0 )
		{
//			LOGV( "hid_read_timeout no data available" );
			return 0;
		}

		const hid_buffer &buffer = m_vecData.front();
		size_t nDataLen = buffer.size() > length ? length : buffer.size();
		if ( m_bIsBLESteamController )
		{
			data[0] = 0x03;
			memcpy( data + 1, buffer.data(), nDataLen );
			++nDataLen;
		}
		else
		{
			memcpy( data, buffer.data(), nDataLen );
		}
		m_vecData.pop_front();

//		LOGV("Read %u bytes", nDataLen);
//		LOGV("%02x %02x %02x %02x %02x %02x %02x %02x ....",
//			 data[0], data[1], data[2], data[3],
//			 data[4], data[5], data[6], data[7]);

		return nDataLen;
	}

	int SendOutputReport( const unsigned char *pData, size_t nDataLen )
	{
		// Make sure thread is attached to JVM/env
		JNIEnv *env;
		g_JVM->AttachCurrentThread( &env, NULL );
		pthread_setspecific( g_ThreadKey, (void*)env );

		jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
		int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendOutputReport, m_nId, pBuf );
		ExceptionCheck( env, "SendOutputReport" );

		env->DeleteLocalRef( pBuf );
		return nRet;
	}

	int SendFeatureReport( const unsigned char *pData, size_t nDataLen )
	{
		// Make sure thread is attached to JVM/env
		JNIEnv *env;
		g_JVM->AttachCurrentThread( &env, NULL );
		pthread_setspecific( g_ThreadKey, (void*)env );

		jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
		int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendFeatureReport, m_nId, pBuf );
		ExceptionCheck( env, "SendFeatureReport" );
		env->DeleteLocalRef( pBuf );
		return nRet;
	}

	void ProcessFeatureReport( const uint8_t *pBuf, size_t nBufSize )
	{
		hid_mutex_guard cvl( &m_cvLock );
		if ( m_bIsWaitingForFeatureReport )
		{
			m_featureReport.assign( pBuf, nBufSize );

			m_bIsWaitingForFeatureReport = false;
			m_nFeatureReportError = 0;
			pthread_cond_signal( &m_cv );
		}
	}

	int GetFeatureReport( unsigned char *pData, size_t nDataLen )
	{
		// Make sure thread is attached to JVM/env
		JNIEnv *env;
		g_JVM->AttachCurrentThread( &env, NULL );
		pthread_setspecific( g_ThreadKey, (void*)env );

		{
			hid_mutex_guard cvl( &m_cvLock );
			if ( m_bIsWaitingForFeatureReport )
			{
				LOGV( "Get feature report already ongoing... bail" );
				return -1; // Read already ongoing, we currently do not serialize, TODO
			}
			m_bIsWaitingForFeatureReport = true;
		}

		jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
		int nRet = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerGetFeatureReport, m_nId, pBuf ) ? 0 : -1;
		ExceptionCheck( env, "GetFeatureReport" );
		env->DeleteLocalRef( pBuf );
		if ( nRet < 0 )
		{
			LOGV( "GetFeatureReport failed" );
			m_bIsWaitingForFeatureReport = false;
			return -1;
		}

		{
			hid_mutex_guard cvl( &m_cvLock );
			if ( m_bIsWaitingForFeatureReport )
			{
				LOGV("=== Going to sleep" );
				// Wait in CV until we are no longer waiting for a feature report.
				const int FEATURE_REPORT_TIMEOUT_SECONDS = 2;
				struct timespec ts, endtime;
				clock_gettime( CLOCK_REALTIME, &ts );
				endtime = ts;
				endtime.tv_sec += FEATURE_REPORT_TIMEOUT_SECONDS;
				do
				{
					if ( pthread_cond_timedwait( &m_cv, &m_cvLock, &endtime ) != 0 )
					{
						break;
					}
				}
				while ( m_bIsWaitingForFeatureReport && get_timespec_ms( ts ) < get_timespec_ms( endtime ) );

				// We are back
				if ( m_bIsWaitingForFeatureReport )
				{
					m_nFeatureReportError = -ETIMEDOUT;
					m_bIsWaitingForFeatureReport = false;
				}
				LOGV( "=== Got feature report err=%d", m_nFeatureReportError );
				if ( m_nFeatureReportError != 0 )
				{
					return m_nFeatureReportError;
				}
			}

			size_t uBytesToCopy = m_featureReport.size() > nDataLen ? nDataLen : m_featureReport.size();
			memcpy( pData, m_featureReport.data(), uBytesToCopy );
			m_featureReport.clear();
			LOGV( "=== Got %u bytes", uBytesToCopy );

			return uBytesToCopy;
		}
	}

	void Close( bool bDeleteDevice )
	{
		// Make sure thread is attached to JVM/env
		JNIEnv *env;
		g_JVM->AttachCurrentThread( &env, NULL );
		pthread_setspecific( g_ThreadKey, (void*)env );

		env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId );
		ExceptionCheck( env, "Close" );
	
		hid_mutex_guard dataLock( &m_dataLock );
		m_vecData.clear();

		// Clean and release pending feature report reads
		hid_mutex_guard cvLock( &m_cvLock );
		m_featureReport.clear();
		m_bIsWaitingForFeatureReport = false;
		m_nFeatureReportError = -ECONNRESET;
		pthread_cond_broadcast( &m_cv );

		if ( bDeleteDevice )
		{
			delete m_pDevice;
			m_pDevice = nullptr;
		}
	}

private:
	pthread_mutex_t m_refCountLock = PTHREAD_MUTEX_INITIALIZER;
	int m_nRefCount = 0;
	int m_nId = 0;
	hid_device_info *m_pInfo = nullptr;
	hid_device *m_pDevice = nullptr;
	bool m_bIsBLESteamController = false;

	pthread_mutex_t m_dataLock = PTHREAD_MUTEX_INITIALIZER; // This lock has to be held to access m_vecData
	hid_buffer_pool m_vecData;

	// For handling get_feature_report
	pthread_mutex_t m_cvLock = PTHREAD_MUTEX_INITIALIZER; // This lock has to be held to access any variables below
	pthread_cond_t m_cv = PTHREAD_COND_INITIALIZER;
	bool m_bIsWaitingForOpen = false;
	bool m_bOpenResult = false;
	bool m_bIsWaitingForFeatureReport = false;
	int m_nFeatureReportError = 0;
	hid_buffer m_featureReport;

public:
	hid_device_ref<CHIDDevice> next;
};

class CHIDDevice;
static pthread_mutex_t g_DevicesMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t g_DevicesRefCountMutex = PTHREAD_MUTEX_INITIALIZER;
static hid_device_ref<CHIDDevice> g_Devices;

static hid_device_ref<CHIDDevice> FindDevice( int nDeviceId )
{
	hid_device_ref<CHIDDevice> pDevice;

	hid_mutex_guard l( &g_DevicesMutex );
	for ( pDevice = g_Devices; pDevice; pDevice = pDevice->next )
	{
		if ( pDevice->GetId() == nDeviceId )
		{
			break;
		}
	}
	return pDevice;
}

static void ThreadDestroyed(void* value)
{
	/* The thread is being destroyed, detach it from the Java VM and set the g_ThreadKey value to NULL as required */
	JNIEnv *env = (JNIEnv*) value;
	if (env != NULL) {
		g_JVM->DetachCurrentThread();
		pthread_setspecific(g_ThreadKey, NULL);
	}
}


extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz);

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz);

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface );

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID);

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened);

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID);

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);


extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz )
{
	LOGV( "HIDDeviceRegisterCallback()");

	env->GetJavaVM( &g_JVM );

	/*
	 * Create mThreadKey so we can keep track of the JNIEnv assigned to each thread
	 * Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this
	 */
	if (pthread_key_create(&g_ThreadKey, ThreadDestroyed) != 0) {
		__android_log_print(ANDROID_LOG_ERROR, TAG, "Error initializing pthread key");
	}

	if ( g_HIDDeviceManagerCallbackHandler != NULL )
	{
		env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
		g_HIDDeviceManagerCallbackClass = NULL;
		env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler );
		g_HIDDeviceManagerCallbackHandler = NULL;
	}

	g_HIDDeviceManagerCallbackHandler = env->NewGlobalRef( thiz );
	jclass objClass = env->GetObjectClass( thiz );
	if ( objClass )
	{
		g_HIDDeviceManagerCallbackClass = reinterpret_cast< jclass >( env->NewGlobalRef( objClass ) );
		g_midHIDDeviceManagerOpen = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "openDevice", "(I)Z" );
		if ( !g_midHIDDeviceManagerOpen )
		{
			__android_log_print(ANDROID_LOG_ERROR, TAG, "HIDDeviceRegisterCallback: callback class missing openDevice" );
		}
		g_midHIDDeviceManagerSendOutputReport = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "sendOutputReport", "(I[B)I" );
		if ( !g_midHIDDeviceManagerSendOutputReport )
		{
			__android_log_print(ANDROID_LOG_ERROR, TAG, "HIDDeviceRegisterCallback: callback class missing sendOutputReport" );
		}
		g_midHIDDeviceManagerSendFeatureReport = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "sendFeatureReport", "(I[B)I" );
		if ( !g_midHIDDeviceManagerSendFeatureReport )
		{
			__android_log_print(ANDROID_LOG_ERROR, TAG, "HIDDeviceRegisterCallback: callback class missing sendFeatureReport" );
		}
		g_midHIDDeviceManagerGetFeatureReport = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "getFeatureReport", "(I[B)Z" );
		if ( !g_midHIDDeviceManagerGetFeatureReport )
		{
			__android_log_print(ANDROID_LOG_ERROR, TAG, "HIDDeviceRegisterCallback: callback class missing getFeatureReport" );
		}
		g_midHIDDeviceManagerClose = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "closeDevice", "(I)V" );
		if ( !g_midHIDDeviceManagerClose )
		{
			__android_log_print(ANDROID_LOG_ERROR, TAG, "HIDDeviceRegisterCallback: callback class missing closeDevice" );
		}
		env->DeleteLocalRef( objClass );
	}
}

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz)
{
	LOGV("HIDDeviceReleaseCallback");
	if ( env->IsSameObject( thiz, g_HIDDeviceManagerCallbackHandler ) )
	{
		env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
		g_HIDDeviceManagerCallbackClass = NULL;
		env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler );
		g_HIDDeviceManagerCallbackHandler = NULL;
	}
}

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface )
{
	LOGV( "HIDDeviceConnected() id=%d VID/PID = %.4x/%.4x, interface %d\n", nDeviceID, nVendorId, nProductId, nInterface );

	hid_device_info *pInfo = new hid_device_info;
	memset( pInfo, 0, sizeof( *pInfo ) );
	pInfo->path = CreateStringFromJString( env, sIdentifier );
	pInfo->vendor_id = nVendorId;
	pInfo->product_id = nProductId;
	pInfo->serial_number = CreateWStringFromJString( env, sSerialNumber );
	pInfo->release_number = nReleaseNumber;
	pInfo->manufacturer_string = CreateWStringFromJString( env, sManufacturer );
	pInfo->product_string = CreateWStringFromJString( env, sProduct );
	pInfo->interface_number = nInterface;

	hid_device_ref<CHIDDevice> pDevice( new CHIDDevice( nDeviceID, pInfo ) );

	hid_mutex_guard l( &g_DevicesMutex );
	hid_device_ref<CHIDDevice> pLast, pCurr;
	for ( pCurr = g_Devices; pCurr; pLast = pCurr, pCurr = pCurr->next )
	{
		continue;
	}
	if ( pLast )
	{
		pLast->next = pDevice;
	}
	else
	{
		g_Devices = pDevice;
	}
}

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID)
{
	LOGV( "HIDDeviceOpenPending() id=%d\n", nDeviceID );
	hid_device_ref<CHIDDevice> pDevice = FindDevice( nDeviceID );
	if ( pDevice )
	{
		pDevice->SetOpenPending();
	}
}

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened)
{
	LOGV( "HIDDeviceOpenResult() id=%d, result=%s\n", nDeviceID, bOpened ? "true" : "false" );
	hid_device_ref<CHIDDevice> pDevice = FindDevice( nDeviceID );
	if ( pDevice )
	{
		pDevice->SetOpenResult( bOpened );
	}
}

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID)
{
	LOGV( "HIDDeviceDisconnected() id=%d\n", nDeviceID );
	hid_device_ref<CHIDDevice> pDevice;
	{
		hid_mutex_guard l( &g_DevicesMutex );
		hid_device_ref<CHIDDevice> pLast, pCurr;
		for ( pCurr = g_Devices; pCurr; pLast = pCurr, pCurr = pCurr->next )
		{
			if ( pCurr->GetId() == nDeviceID )
			{
				pDevice = pCurr;

				if ( pLast )
				{
					pLast->next = pCurr->next;
				}
				else
				{
					g_Devices = pCurr->next;
				}
			}
		}
	}
	if ( pDevice )
	{
		pDevice->Close( false );
	}
}

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value)
{
	jbyte *pBuf = env->GetByteArrayElements(value, NULL);
	jsize nBufSize = env->GetArrayLength(value);

//	LOGV( "HIDDeviceInput() id=%d len=%u\n", nDeviceID, nBufSize );
	hid_device_ref<CHIDDevice> pDevice = FindDevice( nDeviceID );
	if ( pDevice )
	{
		pDevice->ProcessInput( reinterpret_cast< const uint8_t* >( pBuf ), nBufSize );
	}

	env->ReleaseByteArrayElements(value, pBuf, 0);
}

extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value)
{
	jbyte *pBuf = env->GetByteArrayElements(value, NULL);
	jsize nBufSize = env->GetArrayLength(value);

	LOGV( "HIDDeviceFeatureReport() id=%d len=%u\n", nDeviceID, nBufSize );
	hid_device_ref<CHIDDevice> pDevice = FindDevice( nDeviceID );
	if ( pDevice )
	{
		pDevice->ProcessFeatureReport( reinterpret_cast< const uint8_t* >( pBuf ), nBufSize );
	}

	env->ReleaseByteArrayElements(value, pBuf, 0);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

extern "C"
{

int hid_init(void)
{
	return 0;
}

struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	struct hid_device_info *root = NULL;
	hid_mutex_guard l( &g_DevicesMutex );
	for ( hid_device_ref<CHIDDevice> pDevice = g_Devices; pDevice; pDevice = pDevice->next )
	{
		const hid_device_info *info = pDevice->GetDeviceInfo();
		if ( ( vendor_id == 0 && product_id == 0 ) ||
			 ( vendor_id == info->vendor_id && product_id == info->product_id ) )
		{
			hid_device_info *dev = CopyHIDDeviceInfo( info );
			dev->next = root;
			root = dev;
		}
	}
	return root;
}

void  HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
{
	while ( devs )
	{
		struct hid_device_info *next = devs->next;
		FreeHIDDeviceInfo( devs );
		devs = next;
	}
}

HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
{
	// TODO: Implement
	return NULL;
}

HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bExclusive)
{
	LOGV( "hid_open_path( %s )", path );

	hid_device_ref< CHIDDevice > pDevice;
	{
		hid_mutex_guard r( &g_DevicesRefCountMutex );
		hid_mutex_guard l( &g_DevicesMutex );
		for ( hid_device_ref<CHIDDevice> pCurr = g_Devices; pCurr; pCurr = pCurr->next )
		{
			if ( strcmp( pCurr->GetDeviceInfo()->path, path ) == 0 ) 
			{
				hid_device *pValue = pCurr->GetDevice();
				if ( pValue )
				{
					++pValue->m_nDeviceRefCount;
					LOGD("Incrementing device %d (%p), refCount = %d\n", pValue->m_nId, pValue, pValue->m_nDeviceRefCount);
					return pValue;
				}

				// Hold a shared pointer to the controller for the duration
				pDevice = pCurr;
				break;
			}
		}
	}
	if ( pDevice && pDevice->BOpen() )
	{
		return pDevice->GetDevice();
	}
	return NULL;
}

int  HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
{
	LOGV( "hid_write id=%d length=%u", device->m_nId, length );
	hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
	if ( pDevice )
	{
		return pDevice->SendOutputReport( data, length );
	}
	return -1; // Controller was disconnected
}

// TODO: Implement timeout?
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
{
//	LOGV( "hid_read_timeout id=%d length=%u timeout=%d", device->m_nId, length, milliseconds );
	hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
	if ( pDevice )
	{
		return pDevice->GetInput( data, length );
	}
	LOGV( "controller was disconnected" );
	return -1; // Controller was disconnected
}

// TODO: Implement blocking
int  HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
{
	LOGV( "hid_read id=%d length=%u", device->m_nId, length );
	return hid_read_timeout( device, data, length, 0 );
}

// TODO: Implement?
int  HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock)
{
	return -1;
}

int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length)
{
	LOGV( "hid_send_feature_report id=%d length=%u", device->m_nId, length );
	hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
	if ( pDevice )
	{
		return pDevice->SendFeatureReport( data, length );
	}
	return -1; // Controller was disconnected
}


// Synchronous operation. Will block until completed.
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
{
	LOGV( "hid_get_feature_report id=%d length=%u", device->m_nId, length );
	hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
	if ( pDevice )
	{
		return pDevice->GetFeatureReport( data, length );
	}
	return -1; // Controller was disconnected
}


void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
{
	LOGV( "hid_close id=%d", device->m_nId );
	hid_mutex_guard r( &g_DevicesRefCountMutex );
	LOGD("Decrementing device %d (%p), refCount = %d\n", device->m_nId, device, device->m_nDeviceRefCount - 1);
	if ( --device->m_nDeviceRefCount == 0 )
	{
		hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
		if ( pDevice )
		{
			pDevice->Close( true );
		}
		else
		{
			delete device;
		}
		LOGD("Deleted device %p\n", device);
	}

}

int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen)
{
	hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
	if ( pDevice )
	{
		wcsncpy( string, pDevice->GetDeviceInfo()->manufacturer_string, maxlen );
		return 0;
	}
	return -1;
}

int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen)
{
	hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
	if ( pDevice )
	{
		wcsncpy( string, pDevice->GetDeviceInfo()->product_string, maxlen );
		return 0;
	}
	return -1;
}

int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen)
{
	hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
	if ( pDevice )
	{
		wcsncpy( string, pDevice->GetDeviceInfo()->serial_number, maxlen );
		return 0;
	}
	return -1;
}

int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen)
{
	return -1;
}

HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device)
{
	return NULL;
}

int hid_exit(void)
{
	return 0;
}

}
