/*
  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 (bstr_name != NULL) {
        SysFreeString(bstr_name);
    }
	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;

	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: */
