/* --------------------------------------------------------------------------------
 #
 #	4DPlugin.c
 #	source generated by 4D Plugin Wizard
 #	Project : ORiN CaoSQL Project
 #	author : Yukishige Yoshida, (C) DENSO-WAVE
 #	2011/07/11
 #
 # --------------------------------------------------------------------------------*/

#include "4DPluginAPI.h"
#include "4DPlugin.h"

// CaoSQLEngine
ICaoSQLEngine* g_pISqlEng = NULL;


extern "C" {

/**	4D Plugin メイン関数
 *
 *	@param	selector	:	[in] 機能ID
 *	@param	params		:	[in] 引数情報
 *	@retval	なし
 *
 */ 
void PluginMain( long selector, PA_PluginParameters params )
{
	switch( selector )
	{
		case kInitPlugin :
			InitPlugin();
			break;

		case kDeinitPlugin :
			DeinitPlugin();
			break;

// --- CaoSQL
		case eCMD_GetLongItem :
		case eCMD_GetIntegerItem :
		case eCMD_GetRealItem :
		case eCMD_GetTextItem :
			GetSQLItem(selector, params);
			break;

		case eCMD_PutIntegerItem :
		case eCMD_PutLongItem :
		case eCMD_PutRealItem :
		case eCMD_PutTextItem :
			PutSQLItem(selector, params);
			break;
	}
}

} // extern "C"

void InitPlugin()
{
	HRESULT hr = Init();
}

void DeinitPlugin()
{
	HRESULT hr = Term();
}

// ------------------------------------ CaoSQL ------------------------------------

void GetSQLItem( long selector, PA_PluginParameters params )
{
	PA_Unistring* Param1 = PA_GetStringParameter( params, 1 );
	PA_Unichar* Param1_uchars = PA_GetUnistring( Param1 );
	PA_Unistring* Param2 = PA_GetStringParameter( params, 2 );
	PA_Unichar* Param2_uchars = PA_GetUnistring( Param2 );

	// アイテムの値を取得する
	VARIANT vValue;
	VariantInit(&vValue);
	HRESULT hr = AccessSQLItem( GET_SQLITEM, (BSTR)(Param1_uchars), (BSTR)(Param2_uchars), &vValue);
	if (FAILED(hr)) {
		TCHAR s[256];
		wsprintf(s, _T("Error : GetSQLItem(%s, %s)\n"), (BSTR)(Param1_uchars), (BSTR)(Param2_uchars) );
		OutputDebugString( s );
		return;
	}

	switch( selector ) {
	case eCMD_GetIntegerItem :
		{
			hr = VariantChangeType( &vValue, &vValue, 0, VT_I2);
			PA_ReturnShort( params, vValue.iVal );
		}
		break;
	case eCMD_GetLongItem :
		{
			hr = VariantChangeType( &vValue, &vValue, 0, VT_I4);
			PA_ReturnLong( params, vValue.lVal );
		}
		break;
	case eCMD_GetRealItem :
		{
			hr = VariantChangeType( &vValue, &vValue, 0, VT_R8);
			PA_ReturnDouble( params, vValue.dblVal );
		}
		break;
	case eCMD_GetTextItem :
		{
			hr = VariantChangeType( &vValue, &vValue, 0, VT_BSTR);
			if (SUCCEEDED(hr)) {
				PA_ReturnString(params, (PA_Unichar*)vValue.bstrVal);
			} else {
				PA_ReturnString(params, (PA_Unichar*)(L""));
			}
		}
		break;
	}

	VariantClear(&vValue);

}

void PutSQLItem( long selector, PA_PluginParameters params )
{
	PA_Unistring* Param1 = PA_GetStringParameter( params, 1 );
	PA_Unichar* Param1_uchars = PA_GetUnistring( Param1 );
	PA_Unistring* Param2 = PA_GetStringParameter( params, 2 );
	PA_Unichar* Param2_uchars = PA_GetUnistring( Param2 );

	VARIANT vValue;
	VariantInit(&vValue);

	switch( selector ) {
	case eCMD_PutIntegerItem :
		{
			vValue.iVal = PA_GetShortParameter(params, 3);
			vValue.vt = VT_I2;
		}
		break;
	case eCMD_PutLongItem :
		{
			vValue.lVal = PA_GetLongParameter(params, 3);
			vValue.vt = VT_I4;
		}
		break;
	case eCMD_PutRealItem :
		{
			vValue.dblVal = PA_GetDoubleParameter(params, 3);
			vValue.vt = VT_R8;
		}
		break;
	case eCMD_PutTextItem :
		{
			PA_Unistring* Param3 = PA_GetStringParameter( params, 3 );
			PA_Unichar* Param3_uchars = PA_GetUnistring( Param3 );

			vValue.bstrVal = SysAllocString((OLECHAR*)(Param3_uchars));
			vValue.vt = VT_BSTR;
		}
		break;
	}

	HRESULT hr = AccessSQLItem( PUT_SQLITEM, (BSTR)(Param1_uchars), (BSTR)(Param2_uchars), &vValue);
	if (FAILED(hr)) {
		TCHAR s[256];
		wsprintf(s, _T("Error : PutSQLItem(%s, %s)\n"), (BSTR)(Param1_uchars), (BSTR)(Param2_uchars) );
		OutputDebugString( s );
	}

	VariantClear(&vValue);
}

/**	初期化処理
 *
 *　本プラグインの機能を呼び出す前に初期化が必要です。
 *
 */ 
HRESULT Init() 
{
	HRESULT hr = S_OK;

	// DCOMライブラリの初期化
	CoInitialize(0);

	// CaoSQLエンジンの生成
	if (g_pISqlEng == NULL) {
		hr = CoCreateInstance(CLSID_CaoSQLEngine, NULL, CLSCTX_LOCAL_SERVER, IID_ICaoSQLEngine, (void **)&g_pISqlEng);
		if (FAILED(hr)) {
			OutputDebugString( _T("Error : CoCreateInstance - CaoSQLEngine\n") );
			return E_FAIL;
		}
		OutputDebugString( _T("CoCreateInstance(CaoSQLEngine)\n") );
	}

	return hr;
}

/**	指定コントローラの指定アイテムへのGet/Put処理
 *
 *	@param	lMode			:	[in] 0:GET, 1:PUT
 *	@param	bstrCtrlName	:	[in] コントローラ名
 *	@param	bstrItemName	:	[in] アイテム名
 *	@param	pvValue			:	[in/out] 値
 *	@retval	HRESULT
 *
 */ 
// lMode = 0: Get, 1:Put
HRESULT AccessSQLItem(long lMode, BSTR bstrCtrlName, BSTR bstrItemName, VARIANT *pvValue)
{
	if (g_pISqlEng == NULL) return E_POINTER;

	ICaoSQLController* pCtrl = NULL;

	HRESULT hr;
	VARIANT vIndex;

	vIndex.bstrVal = SysAllocString(bstrCtrlName);
	vIndex.vt = VT_BSTR;
	hr = g_pISqlEng->Controller(vIndex, &pCtrl );

	if (SUCCEEDED(hr)) {
		VariantClear(&vIndex);

		vIndex.bstrVal = SysAllocString(bstrItemName);
		vIndex.vt = VT_BSTR;

		ICaoSQLItem* pItem = NULL;
		hr = pCtrl->Item(vIndex, &pItem);

		if (SUCCEEDED(hr)) {
			if (lMode) {
				hr = pItem->put_Value(*pvValue);
			} else {
				hr = pItem->get_Value(pvValue);
			}
			pItem->Release();
		}
		else {
			OutputDebugString( _T("Error : get_Item()\n") );
		}
		pCtrl->Release();
	}
	else {
		OutputDebugString( _T("Error : get_Controller()\n") );
	}

	VariantClear(&vIndex);

	return hr;
}


/**	終了処理
 *
 *　本プラグインの機能を呼び出し終えたら、最後に終了処理が必要です。
 *
 */ 
HRESULT Term() 
{
	// CaoSQLエンジンの開放
	if (g_pISqlEng) {
		g_pISqlEng->Release();
		OutputDebugString( _T("ICaoSQLEngine_Release\n") );
		g_pISqlEng = NULL;	
	}

	// DCOMライブラリの終了処理
	CoUninitialize();

	return S_OK;
}
