#include "Navigation3D.h"
#include <exception>


/// <summary>
/// 全局初始化3D鼠标
/// </summary>
void three_mouse_global_init()
{
	try
	{
		ZeroMemory(device_datas, sizeof(device_datas));
	}
	catch (const std::exception&)
	{

	}
}

/// <summary>
/// 销毁3D鼠标
/// </summary>
void three_mouse_global_dispose()
{
	try
	{
		SiTerminate();
	}
	catch (const std::exception&)
	{

	}
}


/// <summary>
/// 获取3D鼠标个数
/// </summary>
/// <returns>3D鼠标个数</returns>
int three_mouse_get_device_number()
{
	try
	{
		return SiGetNumDevices();
	}
	catch (const std::exception&)
	{
		return -1;
	}
}

/// <summary>
/// 打开3D鼠标设备
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <param name="id">编号</param>
/// <returns>3D鼠标数据</returns>
ThreeDDeviceData* three_mouse_open_device(HWND hWnd, int id)
{
	try
	{
		if (SiInitialize() == SPW_DLL_LOAD_ERROR)   //init the 3DxWare input library
		{
			return NULL;
		}

		ThreeDDeviceData* device_data = new ThreeDDeviceData();
		ZeroMemory(device_data, sizeof(ThreeDDeviceData));
		device_data->id = id;

		SiOpenData oData;
		SiOpenWinInit(&oData, hWnd);

		device_data->device = SiOpen("Navigation3D00", id, SI_NO_MASK, SI_EVENT, &oData);
		if (device_data->device == NULL)
		{
			delete device_data;

			SiTerminate();
			return NULL;
		}

		SiGrabDevice(device_data->device, TRUE);

		device_data->WM_3DMOUSE = RegisterWindowMessage(L"SpaceWareMessage00");

		device_datas[id] = device_data;

		return NULL;
	}
	catch (const std::exception&)
	{
		return NULL;
	}
}

/// <summary>
/// 处理3D鼠标消息
/// </summary>
/// <param name="id">设备编号</param>
/// <param name="wParam">窗口消息</param>
/// <param name="lParam">窗口消息</param>
/// <returns>3D鼠标数据</returns>
ThreeDMouseData* three_mouse_on_message(int id, WPARAM wParam, LPARAM lParam)
{
	try
	{
		if (id == 0 || id > 100)
			return NULL;

		ThreeDDeviceData* device_data = device_datas[id];
		if (device_data == NULL)
			return NULL;

		ThreeDMouseData* data = new ThreeDMouseData();
		data->result = 0;
		data->tx = 0;
		data->ty = 0;
		data->tz = 0;
		data->rx = 0;
		data->ry = 0;
		data->rz = 0;

		SiSpwEvent     Event;    /* 3DxWare Event */
		SiGetEventData EData;    /* 3DxWare Event Data */

		/* init Window platform specific data for a call to SiGetEvent */
		SiGetEventWinInit(&EData, device_data->WM_3DMOUSE, wParam, lParam);

		/* check whether msg was a 3D mouse event and process it */
		if (SiGetEvent(device_data->device, 0, &EData, &Event) == SI_IS_EVENT)
		{
			switch (Event.type)
			{
			case SI_MOTION_EVENT:
				data->result = 1;
				data->tx = Event.u.spwData.mData[SI_TX];
				data->ty = Event.u.spwData.mData[SI_TY];
				data->tz = Event.u.spwData.mData[SI_TZ];
				data->rx = Event.u.spwData.mData[SI_RX];
				data->ry = Event.u.spwData.mData[SI_RY];
				data->rz = Event.u.spwData.mData[SI_RZ];

				break;

			case SI_ZERO_EVENT:
				data->result = 1;
				data->tx = 0;
				data->ty = 0;
				data->tz = 0;
				data->rx = 0;
				data->ry = 0;
				data->rz = 0;

				break;

			case  SI_BUTTON_EVENT:

				break;
			} /* end switch */
		} /* end SiGetEvent */
		return (data);
	}
	catch (const std::exception&)
	{
		return NULL;
	}
}

/// <summary>
/// 销毁3D鼠标指针
/// </summary>
/// <param name="ptr">指针</param>
void three_mouse_dispose_ptr(void* ptr)
{
	try
	{
		delete ptr;
	}
	catch (const std::exception&)
	{

	}
}