#include "CameraControl.h"

CameraControl::CameraControl()
{
	if(this->Init() != EDS_ERR_OK)
		return;
	fireEvent("OpenSession");	
}

CameraControl::~CameraControl()
{
	if(this->_controller == NULL)
		return;
	fireEvent("CloseSession");	
	this->releaseSources();

}

EdsError CameraControl::Init()
{
	EdsError	 err = EDS_ERR_OK;
	EdsCameraListRef cameraList = NULL;
	EdsCameraRef camera = NULL;
	EdsUInt32	 count = 0;	
	isSDKLoaded = false;
	this->_model = NULL;
	// Initialization of SDK
	err = EdsInitializeSDK();

	if(err == EDS_ERR_OK)
	{
		isSDKLoaded = true;
	}

	//Acquisition of camera list
	if(err == EDS_ERR_OK)
	{
		err = EdsGetCameraList(&cameraList);
	}

	//Acquisition of number of Cameras
	if(err == EDS_ERR_OK)
	{
		err = EdsGetChildCount(cameraList, &count);
		if(count == 0)
		{
			err = EDS_ERR_DEVICE_NOT_FOUND;
		}
	}

	//Acquisition of camera at the head of the list
	if(err == EDS_ERR_OK)
	{	
		err = EdsGetChildAtIndex(cameraList , 0 , &camera);	
	}

	//Acquisition of camera information
	EdsDeviceInfo deviceInfo;
	if(err == EDS_ERR_OK)
	{	
		err = EdsGetDeviceInfo(camera , &deviceInfo);	
		if(err == EDS_ERR_OK && camera == NULL)
		{
			err = EDS_ERR_DEVICE_NOT_FOUND;
		}
	}

	//Release camera list
	if(cameraList != NULL)
	{
		EdsRelease(cameraList);
	}
	//Create Camera model
	if(err == EDS_ERR_OK )
	{
		_model = cameraModelFactory(camera, deviceInfo);
		if(_model == NULL)
		{
			err = EDS_ERR_DEVICE_NOT_FOUND;
		}
	}
	
	if(err != EDS_ERR_OK)
	{
		::MessageBox(NULL,"Cannot detect camera",NULL,MB_OK);
		return err;
	}

	if(err == EDS_ERR_OK )
	{
		//Create CameraController
		_controller = new CameraController();
		_controller->setCameraModel(_model);
		_controller->run();
		//Set Property Event Handler
		if(err == EDS_ERR_OK)
		{
			err = EdsSetPropertyEventHandler( camera, kEdsPropertyEvent_All, CameraEventListener::handlePropertyEvent , (EdsVoid *)_controller);
		}

		//Set Object Event Handler
		if(err == EDS_ERR_OK)
		{
			err = EdsSetObjectEventHandler( camera, kEdsObjectEvent_All, CameraEventListener::handleObjectEvent , (EdsVoid *)_controller);
		}

		//Set State Event Handler
		if(err == EDS_ERR_OK)
		{
			err = EdsSetCameraStateEventHandler( camera, kEdsStateEvent_All, CameraEventListener::handleStateEvent , (EdsVoid *)_controller);
		}
	}
	return err;
}

void CameraControl::releaseSources()
{
	//Release Camera
	EdsCameraRef camera = _model->getCameraObject();
	if( camera != NULL )
	{
		EdsRelease(camera);
		camera = NULL;
	}

	//Termination of SDK
	if(isSDKLoaded)
	{
		EdsTerminateSDK();
	}
		
	if(_model != NULL)
	{
		delete _model;
		_model = NULL;
	}


	if(_controller != NULL)
	{
		delete _controller;
		_controller = NULL;
	}
}

CameraModel* CameraControl::cameraModelFactory(EdsCameraRef camera, EdsDeviceInfo deviceInfo)
{
	// if Legacy protocol.
	if(deviceInfo.deviceSubType == 0)
	{
		return new CameraModelLegacy(camera);
	}

	// PTP protocol.
	return new CameraModel(camera);
}

void CameraControl::fireEvent(std::string command, void* arg)
{
	if(this->_model == NULL)
			return;
	ActionEvent event(command, arg);
	_controller->actionPerformed(event);
}

void CameraControl::takePicture()
{
	fireEvent("TakePicture");
}

char* CameraControl::getImageName()
{
	if(this->_model == NULL)
		return NULL;
	return this->_model->getImageFileName();
}
