#include <vector>

#include "stdint.h"
#include <atlbase.h>
#include "dn_common.h"
#include "bCapBase.h"
#include "bCapVariable.h"
#include "bCapController.h"

using namespace std;

bCapController::bCapController(BSTR Name) : bCapBase(TYPE_CTRL, Name)
{

}

bCapController::~bCapController()
{
	vec_obj::iterator it;
	for(it = m_vec_var.begin(); it != m_vec_var.end(); ++it){
		put_Parent(*it, NULL);
	}
	m_vec_var.clear();
}

HRESULT bCapController::AddVariable(BSTR Name, BSTR Option, bCapVariable **pVar)
{
	bCapVariable *tmpVar = NULL;

	tmpVar = new bCapVariable(TYPE_CTRL_VAR, Name);
	if(tmpVar == NULL) return E_OUTOFMEMORY;

	put_Parent(tmpVar, this);

	m_vec_var.push_back(tmpVar);
	*pVar = tmpVar;

	return S_OK;
}

HRESULT bCapController::Execute(BSTR Command, VARIANT Param, VARIANT *pVal)
{
	HRESULT hr = E_INVALIDARG;

	if(!_wcsicmp(Command, L"Get")){
		hr = ExecGet(Param, pVal);
	}
	else if(!_wcsicmp(Command, L"Put")){
		hr = ExecPut(Param, pVal);
	}

	return hr;
}

HRESULT bCapController::ExecGet(VARIANT Param, VARIANT *pVal)
{
	HRESULT hr;
	uint32_t index;
	VARIANT vntTmp;
	bCapVariable *pVar;

	VariantInit(&vntTmp);

	index = ChangeVarType(Param, VT_BSTR, &vntTmp.bstrVal, 1);
	if(index < 1) { hr = E_INVALIDARG; goto exit_proc; }

	hr = find_Object(TYPE_CTRL_VAR, vntTmp.bstrVal, (bCapBase **)&pVar);
	if(FAILED(hr)) goto exit_proc;

	hr = pVar->get_Value(pVal);

exit_proc:
	VariantClear(&vntTmp);
	return hr;
}

HRESULT bCapController::ExecPut(VARIANT Param, VARIANT *pVal)
{
	HRESULT hr;
	uint32_t index;
	VARIANT vntTmp[2];
	bCapVariable *pVar;

	for(index = 0; index < 2; index++){
		VariantInit(&vntTmp[index]);
	}

	index = ChangeVarType(Param, VT_VARIANT, vntTmp, 2);
	if(index < 2) { hr = E_INVALIDARG; goto exit_proc; }

	hr = VariantChangeType(&vntTmp[0], &vntTmp[0], 0, VT_BSTR);
	if(FAILED(hr)) goto exit_proc;

	hr = find_Object(TYPE_CTRL_VAR, vntTmp[0].bstrVal, (bCapBase **)&pVar);
	if(FAILED(hr)) goto exit_proc;


	hr = pVar->put_Value(vntTmp[1]);

exit_proc:
	for(index = 0; index < 2; index++){
		VariantClear(&vntTmp[index]);
	}
	return hr;
}

HRESULT bCapController::find_Object(int Type, BSTR Name, bCapBase **pObj)
{
	HRESULT hr = E_HANDLE;
	vec_obj *vec;
	vec_obj::iterator it;
	BSTR bstrName = NULL;

	switch(Type){
		case TYPE_CTRL_VAR:
			vec = &m_vec_var;
			break;
		default:
			return E_INVALIDARG;
	}

	for(it = vec->begin(); it != vec->end(); ++it){
		(*it)->get_Name(&bstrName);
		if(!_wcsicmp(bstrName, Name)){
			*pObj = *it;
			hr = S_OK;
			goto exit_proc;
		}
		SysFreeString(bstrName);
		bstrName = NULL;
	}

exit_proc:
	if(bstrName != NULL){
		SysFreeString(bstrName);
		bstrName = NULL;
	}

	return hr;
}

HRESULT bCapController::remove_Object(int Type, BSTR Name)
{
	HRESULT hr = E_HANDLE;
	vec_obj *vec;
	vec_obj::iterator it;
	BSTR bstrName = NULL;

	switch(Type){
		case TYPE_CTRL_VAR:
			vec = &m_vec_var;
			break;
		default:
			return E_INVALIDARG;
	}

	for(it = vec->begin(); it != vec->end(); ++it){
		(*it)->get_Name(&bstrName);
		if(!_wcsicmp(bstrName, Name)){
			vec->erase(it);
			hr = S_OK;
			goto exit_proc;
		}
		SysFreeString(bstrName);
		bstrName = NULL;
	}

exit_proc:
	if(bstrName != NULL){
		SysFreeString(bstrName);
		bstrName = NULL;
	}

	return hr;
}
