#include "Camera.h"
/*
#include <Mil.h>
#pragma comment(lib, "mil.lib")

// 
typedef J_STATUS_TYPE (*tJ_Image_Free)(J_tIMAGE_INFO * pBufferInfo);
typedef J_STATUS_TYPE (*tJ_Image_CloseStream)(THRD_HANDLE hThread);
typedef J_STATUS_TYPE (*tJ_Camera_Close)(CAM_HANDLE hCam);
typedef J_STATUS_TYPE (*tJ_Image_Malloc)(J_tIMAGE_INFO * pAqImageInfo, J_tIMAGE_INFO * pBufferInfo);
typedef J_STATUS_TYPE (*tJ_Image_FromRawToImageEx)(J_tIMAGE_INFO * pAqImageInfo, J_tIMAGE_INFO * pBufferInfo, J_BAYER_ALGORITHM iBayerAlgorithm, uint32_t iRGain, uint32_t iGGain, uint32_t iBGain);
typedef J_STATUS_TYPE (*tJ_Camera_GetNodeByName)(CAM_HANDLE hCam, int8_t* sNodeName, NODE_HANDLE * phNode);
typedef J_STATUS_TYPE (*tJ_Node_SetValueInt64)(NODE_HANDLE hNode, bool Verify, int64_t Value);
typedef J_STATUS_TYPE (*tJ_Node_GetValueInt64)(NODE_HANDLE hNode, bool Verify, int64_t* pValue);
typedef J_STATUS_TYPE (*tJ_Image_OpenStream)(CAM_HANDLE hCam, uint32_t iChannel, J_IMG_CALLBACK_OBJECT CBObject, J_IMG_CALLBACK_FUNCTION CBFunction, THRD_HANDLE * phThread, uint32_t iBufferSize, DWORD iMcIP);
typedef J_STATUS_TYPE (*tJ_Camera_ExecuteCommand)(CAM_HANDLE hCam, int8_t* sNodeName);
typedef J_STATUS_TYPE (*tJ_Camera_SetValueString)(CAM_HANDLE hCam, int8_t* sNodeName, int8_t* ValueStr);
typedef J_STATUS_TYPE (*tJ_Camera_GetNodeByName)(CAM_HANDLE hCam, int8_t* sNodeName, NODE_HANDLE * phNode);

typedef J_STATUS_TYPE (*tJ_Factory_Open)(const int8_t* psPrivateData, FACTORY_HANDLE *pHandle);
typedef J_STATUS_TYPE (*tJ_Factory_Close)(FACTORY_HANDLE hFac);
typedef J_STATUS_TYPE (*tJ_Factory_UpdateCameraList)(FACTORY_HANDLE hFac, bool8_t *bHasChanged);
typedef J_STATUS_TYPE (*tJ_Factory_GetNumOfCameras)(FACTORY_HANDLE hFac, uint32_t *pNum);


typedef J_STATUS_TYPE (*tJ_Factory_GetCameraIDByIndex)(FACTORY_HANDLE hFac, int32_t iNum, int8_t* pBuffer, uint32_t* pSize);
typedef J_STATUS_TYPE (*tJ_Camera_Open)(FACTORY_HANDLE hFac, int8_t* pCameraID, CAM_HANDLE* hCam);


//#pragma comment( lib, "../lib/jai/lib/Win32_i86/Jai_Factory.lib")

// DWORD ProcessCaller(CConnectionEventSampleDlg* pThread)
// {
// 	pThread->ConnectionSupervisionProcess();
// 
// 	return 0;
// }





ECamera::ECamera( void )
	: m_pImgByte( 0 )	
	, m_hThread( 0 )
	, m_pImageRoi( NULL )
{	
	m_Handle = LoadLibrary( L"Jai_Factory" );

	m_BufferInfo.pImageBuffer = NULL;	


	J_STATUS_TYPE   retval;	
	uint32_t        iNumDev;
	bool8_t         bHasChange;

	{
		tJ_Factory_Open Open;
		Open = (tJ_Factory_Open)GetProcAddress(m_Handle, "J_Factory_Open");
		retval = Open("" , &m_hFactory);
	}
	

	tJ_Factory_UpdateCameraList CameraList;
	CameraList = (tJ_Factory_UpdateCameraList)GetProcAddress(m_Handle, "J_Factory_UpdateCameraList");
	retval = CameraList(m_hFactory, &bHasChange);	



	//----------------------------------------------------
	// 카메라의 갯수를 받아온다.
	//----------------------------------------------------	
	tJ_Factory_GetNumOfCameras GetNumOfCameras;
	GetNumOfCameras = (tJ_Factory_GetNumOfCameras)GetProcAddress(m_Handle, "J_Factory_GetNumOfCameras");
	GetNumOfCameras( m_hFactory, &iNumDev);


	int8_t			m_CameraId[J_CAMERA_ID_SIZE];
	uint32_t iCameraIdSize = J_CAMERA_ID_SIZE;

	tJ_Factory_GetCameraIDByIndex GetCameraIDByIndex;
	GetCameraIDByIndex = (tJ_Factory_GetCameraIDByIndex)GetProcAddress(m_Handle, "J_Factory_GetCameraIDByIndex");
	J_STATUS_TYPE status = GetCameraIDByIndex(m_hFactory, 1, m_CameraId, &iCameraIdSize);

	{
		tJ_Camera_Open Open;	
		Open = (tJ_Camera_Open)GetProcAddress(m_Handle, "J_Camera_Open");	
		retval = Open(m_hFactory, m_CameraId, &m_hCam);
	}


	StartStreaming();
}

ECamera::~ECamera(void)
{

	Disconnect( );

	FreeLibrary( m_Handle );

	MbufFree(m_pImageRoi);
}



void ECamera::Disconnect()
{
	if(m_hThread)
	{
		tJ_Image_CloseStream CloseStream;
		CloseStream = (tJ_Image_CloseStream)GetProcAddress(m_Handle, "J_Image_CloseStream");
		CloseStream(m_hThread);

		m_hThread = NULL;
	}

	// Frees buffer memory.
	if (m_BufferInfo.pImageBuffer != NULL)
	{
		tJ_Image_Free Image_free;
		Image_free = (tJ_Image_Free)GetProcAddress(m_Handle, "J_Image_Free");
		Image_free(&m_BufferInfo);
		m_BufferInfo.pImageBuffer = NULL;
	}

	//---------------------------------------------
	// 카메라 핸들을 닫아준다.
	//---------------------------------------------
	if (m_hCam)
	{		
		tJ_Camera_Close Camera_Close;
		Camera_Close = (tJ_Camera_Close)GetProcAddress(m_Handle, "J_Camera_Close");
		Camera_Close(m_hCam);
		m_hCam = NULL;		
	}
}



//--------------------------------------------------------------------------------------------------
//  해당 이미지를 얻어온다.
//--------------------------------------------------------------------------------------------------
void ECamera::StreamCBFunc(J_tIMAGE_INFO * pAqImageInfo)
{
	int i = 0;

	J_STATUS_TYPE status = J_ST_SUCCESS;

	if (m_BufferInfo.pImageBuffer == NULL)
	{
		tJ_Image_Malloc Image_Malloc;
		Image_Malloc = (tJ_Image_Malloc)GetProcAddress(m_Handle, "J_Image_Malloc");

		Image_Malloc(pAqImageInfo, &m_BufferInfo );
	}






	if (m_BufferInfo.pImageBuffer != NULL)
	{
		// Converts from RAW to full bit image using extended (zipper-effect free) color interpolation.

		tJ_Image_FromRawToImageEx Image_FromRawToImageEx;
		Image_FromRawToImageEx = (tJ_Image_FromRawToImageEx)GetProcAddress(m_Handle, "J_Image_FromRawToImageEx");
		if(J_ST_SUCCESS == Image_FromRawToImageEx(pAqImageInfo, &m_BufferInfo, BAYER_EXTEND, 0x01000, 0x01000, 0x01000))
		{				
		}
	}

	m_bGrab =true;
}



void ECamera::InitBuf( void )
{

	J_STATUS_TYPE status;
	J_STATUS_TYPE retval;


	tJ_Camera_GetNodeByName Camera_GetNodeByName;
	Camera_GetNodeByName = (tJ_Camera_GetNodeByName)GetProcAddress(m_Handle, "J_Camera_GetNodeByName");

	tJ_Node_SetValueInt64 Node_SetValueInt64;
	Node_SetValueInt64 = (tJ_Node_SetValueInt64)GetProcAddress(m_Handle, "J_Node_SetValueInt64");

	tJ_Node_GetValueInt64 Node_GetValueInt64;
	Node_GetValueInt64 = (tJ_Node_GetValueInt64)GetProcAddress(m_Handle, "J_Node_GetValueInt64");

	tJ_Image_OpenStream Image_OpenStream;
	Image_OpenStream = (tJ_Image_OpenStream)GetProcAddress(m_Handle, "J_Image_OpenStream");

	tJ_Camera_ExecuteCommand Camera_ExecuteCommand;
	Camera_ExecuteCommand = (tJ_Camera_ExecuteCommand)GetProcAddress(m_Handle, "J_Camera_ExecuteCommand");

	tJ_Camera_SetValueString Camera_SetValueString;
	Camera_SetValueString = (tJ_Camera_SetValueString)GetProcAddress(m_Handle, "J_Camera_SetValueString");


	//-----------------------------------------------------------------
	// 크기를 정해준다.
	//-----------------------------------------------------------------
	int Width = 1392;
	int Height = 1040;
	int64_t int64Val;
	NODE_HANDLE hNode;
	retval = Camera_GetNodeByName(m_hCam, "Width", &hNode);
	retval = Node_SetValueInt64(  hNode, true, Width );	
	retval = Node_GetValueInt64(hNode, FALSE, &int64Val);


	// Get Height from the camera
	retval = Camera_GetNodeByName(m_hCam, "Height", &hNode);
	retval = Node_SetValueInt64(  hNode, true, Height );
	retval = Node_GetValueInt64(hNode, FALSE, &int64Val);	

	// Get Pixel Format
	retval = Camera_GetNodeByName(m_hCam, "PixelFormat", &hNode);
	retval = Node_GetValueInt64(hNode, FALSE, &int64Val);
	uint32_t  PixelFormat = (uint32_t)int64Val;	
	int bpp = J_BitsPerPixel(PixelFormat);	



	retval = Image_OpenStream(m_hCam, 0, reinterpret_cast<J_IMG_CALLBACK_OBJECT>(this),
		reinterpret_cast<J_IMG_CALLBACK_FUNCTION>(&ECamera::StreamCBFunc), &m_hThread
		, (Width*Height*bpp)/8, 0);
	if (retval != J_ST_SUCCESS)
	{		
		return;
	}



	retval = Camera_ExecuteCommand(m_hCam, "AcquisitionStart");	
	status = Camera_SetValueString(m_hCam, "TriggerSelector", "FrameStart");



	//----------------------------------------------------------
	// 트리거 모드 세팅
	//----------------------------------------------------------
	// Set TriggerMode="On"
	status = Camera_SetValueString(m_hCam, "TriggerMode", "On");	
	status = Camera_SetValueString(m_hCam,"TriggerSource", "Software");	
	status = Camera_SetValueString(m_hCam,"SequenceMode", "Off");


// 	MIL_ID Sys =  CDisplayManager::GetSingleton().GetSysId();
// 	MbufAllocColor( Sys, 3L, 1390, 1040, 8L+M_UNSIGNED, M_IMAGE +M_PROC, &m_pImageRoi );


	// 
	// 	double Width = cvGetCaptureProperty( m_pCapter, 3 );
	// 	double Height = cvGetCaptureProperty( m_pCapter, 4 );


}


void ECamera::StartStreaming( void )
{


}

void ECamera::StopStreaming(void )
{
	if(m_hThread)
	{
		tJ_Image_CloseStream Image_CloseStream;
		Image_CloseStream = (tJ_Image_CloseStream)GetProcAddress(m_Handle, "J_Image_CloseStream");

		// Close stream
		J_STATUS_TYPE retval;
		retval = Image_CloseStream(m_hThread);
		m_hThread = NULL;		
	}
}

//-------------------------------------------------------------------
// 
//-------------------------------------------------------------------
void ECamera::TriggerStart( void )
{
	J_STATUS_TYPE status = J_ST_SUCCESS;

	tJ_Camera_GetNodeByName Camera_GetNodeByName;
	Camera_GetNodeByName = (tJ_Camera_GetNodeByName)GetProcAddress(m_Handle, "J_Camera_GetNodeByName");

	tJ_Camera_ExecuteCommand Camera_ExecuteCommand;
	Camera_ExecuteCommand = (tJ_Camera_ExecuteCommand)GetProcAddress(m_Handle, "J_Camera_ExecuteCommand");

	tJ_Camera_SetValueString Camera_SetValueString;
	Camera_SetValueString = (tJ_Camera_SetValueString)GetProcAddress(m_Handle, "J_Camera_SetValueString");


	NODE_HANDLE hNode = NULL;
	status = Camera_GetNodeByName(m_hCam, "TriggerSoftware", &hNode);

	// Does the "TriggerSoftware" node exist?
	if ((status == J_ST_SUCCESS) && (hNode != NULL))
	{
		// Here we assume that this is GenICam SFNC software trigger so we do the following:
		// TriggerSelector=FrameStart
		// Execute TriggerSoftware Command
		status = Camera_SetValueString(m_hCam,"TriggerSelector", "FrameStart");		
		status = Camera_ExecuteCommand(m_hCam,"TriggerSoftware");			
	}

}


void ECamera::Grab( MIL_ID aId )
{

	m_bGrab = false;
	TriggerStart();

	DWORD Tick = 0;
	DWORD StartTime = GetTickCount();

	while( !m_bGrab && Tick < 400 )
	{
		Tick = GetTickCount() - StartTime;
	}

	if( m_bGrab )
	{
		MbufPutColor( aId, M_BGR24_PACKED, M_ALL_BANDS, m_BufferInfo.pImageBuffer );
	}	

}
*/