/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#include "SDL_config.h"

#if defined(SDL_SENSOR_WINDOWS)

#include "SDL_error.h"
#include "SDL_mutex.h"
#include "SDL_sensor.h"
#include "SDL_windowssensor.h"
#include "../SDL_syssensor.h"
#include "../../core/windows/SDL_windows.h"

#define COBJMACROS
#include <InitGuid.h>
#include <SensorsApi.h>
#include <Sensors.h>

DEFINE_GUID(CLSID_SensorManager, 0x77A1C827, 0xFCD2, 0x4689, 0x89, 0x15, 0x9D, 0x61, 0x3C, 0xC5, 0xFA, 0x3E);
DEFINE_GUID(IID_SensorManager, 0xBD77DB67, 0x45A8, 0x42DC, 0x8D, 0x00, 0x6D, 0xCF, 0x15, 0xF8, 0x37, 0x7A);
DEFINE_GUID(IID_SensorManagerEvents, 0x9B3B0B86, 0x266A, 0x4AAD, 0xB2, 0x1F, 0xFD, 0xE5, 0x50, 0x10, 0x01, 0xB7);
DEFINE_GUID(IID_SensorEvents, 0x5D8DCC91, 0x4641, 0x47E7, 0xB7, 0xC3, 0xB7, 0x4F, 0x48, 0xA6, 0xC3, 0x91);

DEFINE_PROPERTYKEY(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND, 0X3F8A69A2, 0X7C5, 0X4E48, 0XA9, 0X65, 0XCD, 0X79, 0X7A, 0XAB, 0X56, 0XD5, 10); //[VT_R8]
DEFINE_PROPERTYKEY(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND, 0X3F8A69A2, 0X7C5, 0X4E48, 0XA9, 0X65, 0XCD, 0X79, 0X7A, 0XAB, 0X56, 0XD5, 11); //[VT_R8]
DEFINE_PROPERTYKEY(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND, 0X3F8A69A2, 0X7C5, 0X4E48, 0XA9, 0X65, 0XCD, 0X79, 0X7A, 0XAB, 0X56, 0XD5, 12); //[VT_R8]

typedef struct
{
	SDL_SensorID id;
	ISensor *sensor;
	SENSOR_ID sensor_id;
	char *name;
	SDL_SensorType type;
	SDL_Sensor *sensor_opened;

} SDL_Windows_Sensor;

static SDL_bool SDL_windowscoinit;
static ISensorManager *SDL_sensor_manager;
static int SDL_num_sensors;
static SDL_Windows_Sensor *SDL_sensors;

static int ConnectSensor(ISensor *sensor);
static int DisconnectSensor(ISensor *sensor);

static HRESULT STDMETHODCALLTYPE ISensorManagerEventsVtbl_QueryInterface(ISensorManagerEvents * This, REFIID riid, void **ppvObject)
{
	if (!ppvObject) {
		return E_INVALIDARG;
	}

	*ppvObject = NULL;
	if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_SensorManagerEvents)) {
		*ppvObject = This;
		return S_OK;
	}
	return E_NOINTERFACE;
}

static ULONG STDMETHODCALLTYPE ISensorManagerEventsVtbl_AddRef(ISensorManagerEvents * This)
{
	return 1;
}

static ULONG STDMETHODCALLTYPE ISensorManagerEventsVtbl_Release(ISensorManagerEvents * This)
{
	return 1;
}

static HRESULT STDMETHODCALLTYPE ISensorManagerEventsVtbl_OnSensorEnter(ISensorManagerEvents * This, ISensor *pSensor, SensorState state)
{
	ConnectSensor(pSensor);
	return S_OK;
}

static ISensorManagerEventsVtbl sensor_manager_events_vtbl = {
	ISensorManagerEventsVtbl_QueryInterface,
	ISensorManagerEventsVtbl_AddRef,
	ISensorManagerEventsVtbl_Release,
	ISensorManagerEventsVtbl_OnSensorEnter
};
static ISensorManagerEvents sensor_manager_events = {
	&sensor_manager_events_vtbl
};

static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_QueryInterface(ISensorEvents * This, REFIID riid, void **ppvObject)
{
	if (!ppvObject) {
		return E_INVALIDARG;
	}

	*ppvObject = NULL;
	if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_SensorEvents)) {
		*ppvObject = This;
		return S_OK;
	}
	return E_NOINTERFACE;
}

static ULONG STDMETHODCALLTYPE ISensorEventsVtbl_AddRef(ISensorEvents * This)
{
	return 1;
}

static ULONG STDMETHODCALLTYPE ISensorEventsVtbl_Release(ISensorEvents * This)
{
	return 1;
}

static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnStateChanged(ISensorEvents * This, ISensor *pSensor, SensorState state)
{
#ifdef DEBUG_SENSORS
	int i;

	SDL_LockSensors();
	for (i = 0; i < SDL_num_sensors; ++i) {
		if (pSensor == SDL_sensors[i].sensor) {
			SDL_Log("Sensor %s state changed to %d\n", SDL_sensors[i].name, state);
		}
	}
	SDL_UnlockSensors();
#endif
	return S_OK;
}

static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnDataUpdated(ISensorEvents * This, ISensor *pSensor, ISensorDataReport *pNewData)
{
	int i;

	SDL_LockSensors();
	for (i = 0; i < SDL_num_sensors; ++i) {
		if (pSensor == SDL_sensors[i].sensor) {
			if (SDL_sensors[i].sensor_opened) {
				HRESULT hrX, hrY, hrZ;
				PROPVARIANT valueX, valueY, valueZ;

#ifdef DEBUG_SENSORS
				SDL_Log("Sensor %s data updated\n", SDL_sensors[i].name);
#endif
				switch (SDL_sensors[i].type) {
				case SDL_SENSOR_ACCEL:
					hrX = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ACCELERATION_X_G, &valueX);
					hrY = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ACCELERATION_Y_G, &valueY);
					hrZ = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ACCELERATION_Z_G, &valueZ);
					if (SUCCEEDED(hrX) && SUCCEEDED(hrY) && SUCCEEDED(hrZ) &&
						valueX.vt == VT_R8 && valueY.vt == VT_R8 && valueZ.vt == VT_R8) {
						float values[3];

						values[0] = (float)valueX.dblVal;
						values[1] = (float)valueY.dblVal;
						values[2] = (float)valueZ.dblVal;
						SDL_PrivateSensorUpdate(SDL_sensors[i].sensor_opened, values, 3);
					}
					break;
				case SDL_SENSOR_GYRO:
					hrX = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND, &valueX);
					hrY = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND, &valueY);
					hrZ = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND, &valueZ);
					if (SUCCEEDED(hrX) && SUCCEEDED(hrY) && SUCCEEDED(hrZ) &&
						valueX.vt == VT_R8 && valueY.vt == VT_R8 && valueZ.vt == VT_R8) {
						float values[3];

						values[0] = (float)(valueX.dblVal * (M_PI / 180.0));
						values[1] = (float)(valueY.dblVal * (M_PI / 180.0));
						values[2] = (float)(valueZ.dblVal * (M_PI / 180.0));
						SDL_PrivateSensorUpdate(SDL_sensors[i].sensor_opened, values, 3);
					}
					break;
				default:
					/* FIXME: Need to know how to interpret the data for this sensor */
					break;
				}
			}
			break;
		}
	}
	SDL_UnlockSensors();

	return S_OK;
}

static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnEvent(ISensorEvents * This, ISensor *pSensor, REFGUID eventID, IPortableDeviceValues *pEventData)
{
#ifdef DEBUG_SENSORS
	int i;

	SDL_LockSensors();
	for (i = 0; i < SDL_num_sensors; ++i) {
		if (pSensor == SDL_sensors[i].sensor) {
			SDL_Log("Sensor %s event occurred\n", SDL_sensors[i].name);
		}
	}
	SDL_UnlockSensors();
#endif
	return S_OK;
}

static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnLeave(ISensorEvents * This, REFSENSOR_ID ID)
{
	int i;

	SDL_LockSensors();
	for (i = 0; i < SDL_num_sensors; ++i) {
		if (WIN_IsEqualIID(ID, &SDL_sensors[i].sensor_id)) {
#ifdef DEBUG_SENSORS
			SDL_Log("Sensor %s disconnected\n", SDL_sensors[i].name);
#endif
			DisconnectSensor(SDL_sensors[i].sensor);
		}
	}
	SDL_UnlockSensors();

	return S_OK;
}

static ISensorEventsVtbl sensor_events_vtbl = {
	ISensorEventsVtbl_QueryInterface,
	ISensorEventsVtbl_AddRef,
	ISensorEventsVtbl_Release,
	ISensorEventsVtbl_OnStateChanged,
	ISensorEventsVtbl_OnDataUpdated,
	ISensorEventsVtbl_OnEvent,
	ISensorEventsVtbl_OnLeave
};
static ISensorEvents sensor_events = {
	&sensor_events_vtbl
};

static int ConnectSensor(ISensor *sensor)
{
	SDL_Windows_Sensor *new_sensor, *new_sensors;
	HRESULT hr;
	SENSOR_ID sensor_id;
	SENSOR_TYPE_ID type_id;
	SDL_SensorType type;
	BSTR bstr_name = NULL;
	char *name;

	hr = ISensor_GetID(sensor, &sensor_id);
	if (FAILED(hr)) {
		return SDL_SetError("Couldn't get sensor ID: 0x%.4x", hr);
	}

	hr = ISensor_GetType(sensor, &type_id);
	if (FAILED(hr)) {
		return SDL_SetError("Couldn't get sensor type: 0x%.4x", hr);
	}

	if (WIN_IsEqualIID(&type_id, &SENSOR_TYPE_ACCELEROMETER_3D)) {
		type = SDL_SENSOR_ACCEL;
	} else if (WIN_IsEqualIID(&type_id, &SENSOR_TYPE_GYROMETER_3D)) {
		type = SDL_SENSOR_GYRO;
	} else {
		return SDL_SetError("Unknown sensor type");
	}

	hr = ISensor_GetFriendlyName(sensor, &bstr_name);
	if (SUCCEEDED(hr) && bstr_name) {
		name = WIN_StringToUTF8(bstr_name);
	} else {
		name = SDL_strdup("Unknown Sensor");
	}
	if (!name) {
		return SDL_OutOfMemory();
	}

	SDL_LockSensors();
	new_sensors = (SDL_Windows_Sensor *)SDL_realloc(SDL_sensors, (SDL_num_sensors + 1) * sizeof(SDL_Windows_Sensor));
	if (new_sensors == NULL) {
		SDL_UnlockSensors();
		return SDL_OutOfMemory();
	}

	ISensor_AddRef(sensor);
	ISensor_SetEventSink(sensor, &sensor_events);

	SDL_sensors = new_sensors;
	new_sensor = &SDL_sensors[SDL_num_sensors];
	++SDL_num_sensors;

	new_sensor->id = SDL_GetNextSensorInstanceID();
	new_sensor->sensor = sensor;
	new_sensor->type = type;
	new_sensor->name = name;

	SDL_UnlockSensors();

	return 0;
}

static int DisconnectSensor(ISensor *sensor)
{
	SDL_Windows_Sensor *old_sensor;
	int i;

	SDL_LockSensors();
	for (i = 0; i < SDL_num_sensors; ++i) {
		old_sensor = &SDL_sensors[i];
		if (sensor == old_sensor->sensor) {
			ISensor_SetEventSink(sensor, NULL);
			ISensor_Release(sensor);
			SDL_free(old_sensor->name);
			--SDL_num_sensors;
			if (i < SDL_num_sensors) {
				SDL_memmove(&SDL_sensors[i], &SDL_sensors[i + 1], (SDL_num_sensors - i) * sizeof(SDL_sensors[i]));
			}
			break;
		}
	}
	SDL_UnlockSensors();

	return 0;
}

static int
SDL_WINDOWS_SensorInit(void)
{
	HRESULT hr;
	ISensorCollection *sensor_collection = NULL;

	while (!IsDebuggerPresent()) Sleep(100);

	if (WIN_CoInitialize() == S_OK) {
		SDL_windowscoinit = SDL_TRUE;
	}

	hr = CoCreateInstance(&CLSID_SensorManager, NULL, CLSCTX_INPROC_SERVER, &IID_SensorManager, &SDL_sensor_manager);
	if (FAILED(hr)) {
		return SDL_SetError("Couldn't create the sensor manager: 0x%.4x", hr);
	}

	hr = ISensorManager_SetEventSink(SDL_sensor_manager, &sensor_manager_events);
	if (FAILED(hr)) {
		ISensorManager_Release(SDL_sensor_manager);
		return SDL_SetError("Couldn't set the sensor manager event sink: 0x%.4x", hr);
	}

	hr = ISensorManager_GetSensorsByCategory(SDL_sensor_manager, &SENSOR_CATEGORY_ALL, &sensor_collection);
	if (SUCCEEDED(hr)) {
		ULONG i, count;

		hr = ISensorCollection_GetCount(sensor_collection, &count);
		if (SUCCEEDED(hr)) {
			for (i = 0; i < count; ++i) {
				ISensor *sensor;

				hr = ISensorCollection_GetAt(sensor_collection, i, &sensor);
				if (SUCCEEDED(hr)) {
					SensorState state;

					hr = ISensor_GetState(sensor, &state);
					if (SUCCEEDED(hr)) {
						ISensorManagerEventsVtbl_OnSensorEnter(&sensor_manager_events, sensor, state);
					}
					ISensorManager_Release(sensor);
				}
			}
		}
		ISensorCollection_Release(sensor_collection);
	}
    return 0;
}

static int
SDL_WINDOWS_SensorGetCount(void)
{
    return SDL_num_sensors;
}

static void
SDL_WINDOWS_SensorDetect(void)
{
}

static const char *
SDL_WINDOWS_SensorGetDeviceName(int device_index)
{
    return SDL_sensors[device_index].name;
}

static SDL_SensorType
SDL_WINDOWS_SensorGetDeviceType(int device_index)
{
	return SDL_sensors[device_index].type;
}

static int
SDL_WINDOWS_SensorGetDeviceNonPortableType(int device_index)
{
    return -1;
}

static SDL_SensorID
SDL_WINDOWS_SensorGetDeviceInstanceID(int device_index)
{
    return SDL_sensors[device_index].id;
}

static int
SDL_WINDOWS_SensorOpen(SDL_Sensor *sensor, int device_index)
{
	SDL_sensors[device_index].sensor_opened = sensor;
    return 0;
}

static void
SDL_WINDOWS_SensorUpdate(SDL_Sensor *sensor)
{
}

static void
SDL_WINDOWS_SensorClose(SDL_Sensor *sensor)
{
	int i;

	for (i = 0; i < SDL_num_sensors; ++i) {
		if (sensor == SDL_sensors[i].sensor_opened) {
			SDL_sensors[i].sensor_opened = NULL;
			break;
		}
	}
}

static void
SDL_WINDOWS_SensorQuit(void)
{
	while (SDL_num_sensors > 0) {
		DisconnectSensor(SDL_sensors[0].sensor);
	}

	if (SDL_sensor_manager) {
		ISensorManager_SetEventSink(SDL_sensor_manager, NULL);
		ISensorManager_Release(SDL_sensor_manager);
		SDL_sensor_manager = NULL;
	}

	if (SDL_windowscoinit) {
		WIN_CoUninitialize();
	}
}

SDL_SensorDriver SDL_WINDOWS_SensorDriver =
{
    SDL_WINDOWS_SensorInit,
    SDL_WINDOWS_SensorGetCount,
    SDL_WINDOWS_SensorDetect,
    SDL_WINDOWS_SensorGetDeviceName,
    SDL_WINDOWS_SensorGetDeviceType,
    SDL_WINDOWS_SensorGetDeviceNonPortableType,
    SDL_WINDOWS_SensorGetDeviceInstanceID,
    SDL_WINDOWS_SensorOpen,
    SDL_WINDOWS_SensorUpdate,
    SDL_WINDOWS_SensorClose,
    SDL_WINDOWS_SensorQuit,
};

#endif /* SDL_SENSOR_WINDOWS */

/* vi: set ts=4 sw=4 expandtab: */
