#include "Device.h"

void thermoCamera::Device::AddNewDevice(VideoCapture** device)
{
	if (_isAlreadyInit() == true)	_AlreadyInit();

	_ePlayback = Playback::fromCamera;

	_device = device;

	////
	//if (_timer.GetStatus() == false)
	//{
	//	_timer.setInterval(1000);
	//	std::function<void()> func = std::bind(&Device::_RecordData, this);
	//	_timer.setFunction(func);
	//}

	bool result = _InitDevice(**_device);

	if (result == true)				
	{
		_setAccessAllowed();
	}
	else _DeviceNotInit();
}

void thermoCamera::Device::AddRecord(HWND hWnd, int index, int left, int top, int width, int height)
{
	if (_isAccessForbidden() == false && _isRecordPause() == false) 
	{
		try
		{
			RemoveDevice();
		}
		catch(MyError& e){}
	}

	_ePlayback = Playback::fromRecord;
	_setAccessAllowed();
	
	////
	//if (_timer.GetStatus() == false)
	//{
	//	_timer.setInterval(_intervalOfRecord);
	//	std::function<void()> func = std::bind(&Device::_RecordData, this);
	//	_timer.setFunction(func);
	//}

	if(_isRecordPause() == false)
		ConfigureDisplay(hWnd, index, left, top, width, height);
}

void thermoCamera::Device::RemoveDevice()
{
	if (_isAccessForbidden() == true) _AccessDeniedEmpty();
	
	try
	{
		Stop();
	}
	catch(MyError& e)
	{

	}

	_FaceDetector.ResetNumOfTrackers();
	_ePlayback = Playback::fromCamera;

	_RemoveDevice();

	if (_display) _display->DeleteObjects();

	_sizeOfVideoDisplay.clear();
	if (_display) { delete _display; _display = NULL; }
	_record.setImageNumber(0);
	_timer.~Timer();

	_setAccessForbidden();

	_VideoIsDeleted();
}

void thermoCamera::Device::ConfigureDisplay(HWND hWnd, int index,int left, int top, int widthOut, int heightOut)
{
	bool result = _CheckInputParam(left, top, widthOut, heightOut);

	if (result == false) _BadInput();

	_setDisplay(left,top, widthOut, heightOut);

	if (_isPlaybackFromCamera())
	{
		if (_setSizeOfImage() == false) _BadSizeOfInputImage();
	}
	else
	{
		if (_display) _display->LoadWidthHeight(_record.getCurrentPath(), _sizeOfImage,_record.getCurrentNumber());
	}

	_SettingDisplayWithWindow(hWnd, index,widthOut, heightOut);

	// bar
	_setDisplay(LEFTOUTBAR, TOPOUTBAR, WIDTHBAROUT, HEIGHTBAROUT);
	_SettingDisplayWithWindow(hWnd, 1, WIDTHBAROUT, HEIGHTBAROUT);

	// for detect
	_setDisplay(left + widthOut+60, top, _sizeOfImage.cx, _sizeOfImage.cy);
	_SettingDisplayWithWindow(hWnd, 2, _sizeOfImage.cx, _sizeOfImage.cy);
}

void thermoCamera::Device::ConfigureBuffer(int index, int width, int height)
{
	if (_display == NULL) return;
	_display->EraseHDC(index);
	_display->EraseBitMap(index);
	HWND hWnd = _display->GetMainWindow();
	
	HDC current = GetDC(hWnd);
	RECT clientrect;
	GetClientRect(hWnd, &clientrect);

	HDC buff = CreateCompatibleDC(current);
	_display->SetHDC(buff,index);

	HBITMAP hbitmap = CreateCompatibleBitmap(current, width, height);
	_display->SetBitMap(hbitmap,index);

	SelectObject(_display->GetHDC(index), (HGDIOBJ)_display->GetHBITMAP(index));

}

void thermoCamera::Device::SaveImageAfterAlarm()
{
	if (_display == NULL) return;
	if (isAlarmPathSet() == false) return;

	RECT videoRect = _display->GetSizeOfVideo(INDEX_HBITMAP_OF_VIDEO);

	if (_isPlaybackFromCamera())
	{		
		_display->SaveScreenShot(_display->GetMainWindow(), videoRect,_pathToAlarmImage, _numOfAlarmImages);
		++_numOfAlarmImages;
	}
	else
	{
		_display->SaveScreenShot(_display->GetMainWindow(),videoRect, _pathToAlarmImage, _numOfAlarmImages);
		++_numOfAlarmImages;
	}
}

void thermoCamera::Device::DrawOutput(const HDC& hdc, const RECT& location, const HDC& buffer) const
{
	_display->Draw(hdc,location,buffer);
}

void thermoCamera::Device::DrawTemperature(const HDC& hdc, COLORREF color) const
{
	if (hdc == NULL) return;
	if (_display)
	{
		_display->DrawTemperature(hdc, color,_TemperatureOfRegion);
	}
}

void thermoCamera::Device::DrawMinMaxBar(const HDC& hdc, RECT locationOfBar) const
{
	if (hdc == NULL) return;
	if (_display)
	{
		_display->DrawMinMaxTempBar(hdc, locationOfBar);
	}
}

void thermoCamera::Device::DrawRectOfFaces(HWND hWnd, HDC hdc) const 
{
	if (hWnd == NULL || hdc == NULL) return;
	if (_display == NULL) return;
	_FaceDetector.DrawFaceRectangle(hWnd, hdc);
}

void thermoCamera::Device::DrawTemperatureOfFaces(HWND hWnd, HDC hdc) const
{
	if (hWnd == NULL || hdc == NULL) return;

	if (_display == NULL) return;

	_FaceDetector.DrawTempFace(hWnd,*_display, hdc);
}

void thermoCamera::Device::DrawRectangleOnScreen(HWND hWnd,HDC hdc)
{
	_drawRegion.hWnd = hWnd;

	POINT rightRegion;
	POINT leftRegion;

	RECT rect = GetRectangleVideo(INDEX_HBITMAP_OF_VIDEO);

	leftRegion.x = rect.left;
	leftRegion.y = rect.top;
	rightRegion.x = rect.left + rect.right;
	rightRegion.y = rect.top + rect.bottom;
	_drawRegion.setRange(leftRegion, rightRegion);
	_drawRegion.Draw(hdc);
}

void thermoCamera::Device::SetTemperatureOfRegion()
{
	if (_drawRegion.isDrawn() == false) return;

	RECT rc = _drawRegion.getRectangleOfRegion();
	if (rc.left <= 0 || rc.right <= 0 || rc.top <= 0 || rc.bottom <= 0) return;

	if (_display)
	{
		float val = _display->ReturnTemperature(rc, 0);

		if (std::abs(val - _TemperatureOfRegion) > 1.f)
			_TemperatureOfRegion = val;
		
	}
}

void thermoCamera::Device::TrackingObject(HWND hWnd, HDC hdc) 
{
	if (hWnd == NULL || hdc == NULL) return;

	if (_display == NULL) return;

	_FaceDetector.Tracking(*_display);
}

void thermoCamera::Device::EraseOutput(RECT& location) const
{
	if (location.left <= 0 || location.top <= 0 || location.right <= 0 || location.bottom <= 0) return;
	location.right += location.left;
	location.bottom += location.top;
	_display->ValidateRect(location);
}

void thermoCamera::Device::EraseAndUpdateWindow()
{
	if (_display) _display->EraseAndUpdateWindow();
}

void thermoCamera::Device::StartFaceDetection()
{
	if (_isFaceDetection == true) return;

	if (_RunThreadFaceDetection() == true) _isFaceDetection = true;
	else _isFaceDetection = false;
}

void thermoCamera::Device::StopFaceDetection()
{
	if (_isFaceDetection == false) return;

	if (_StopThreadFaceDetection() == true)
	{
		_isFaceDetection = false;
		_FaceDetector.ResetNumOfTrackers();
	}
	else _isFaceDetection = true;

}

void thermoCamera::Device::SetManualRangeTemperature()
{
	if (_display)
	{
		_display->SetManualRangeTemperature();
	}
}

void thermoCamera::Device::ResetManualRangeTemperature()
{
	if (_display)
	{
		_display->ResetManualRangeTemperature();
		_display->EraseAndUpdateWindow();
	}
}

void thermoCamera::Device::Play()
{
	if (_isAccessForbidden() == true)			_AccessDenied();

	if (_isDisplaySet() == false)				_FirstConfigureDevice();

	if (_Play() == false) return;

	if (_isPlaybackFromCamera())
	{
		if (_isDevicePlay() == false)				_CannotPlayVideo();

		_RunThreadPlay();

		if (_isDevicePlay() == false)				_CannotPlayVideo();
	}
	else
	{
		if (_isRecordPlay() == false)				_CannotPlayVideo();

		_RunThreadPlay();

		if (_isRecordPlay() == false)				_CannotPlayVideo();
	}
}

void thermoCamera::Device::Stop()
{
	if (_isAccessForbidden() == true)				_AccessDenied();

	if (_Stop() == false)  return;

	if(_isPlaybackFromCamera()) 
	{
		_StopThreadPlay();
		if (_isDevicePlay() == true)				_CannotStopVideo();
	}
	else
	{
		_StopThreadPlay();
		if(_isRecordPlay() == true)					_CannotStopVideo();
	}
	if (_isFaceDetection)
	{
		StopFaceDetection();
	}
}

void thermoCamera::Device::Pause()
{
	if (_isAccessForbidden() == true)			_AccessDenied();

	if (_Pause() == false) return;
}

bool thermoCamera::Device::isStreaming()
{
	if (_isPlaybackFromCamera())
	{
		if (_device == NULL) return false;
		return (_isDevicePlay() || _isDevicePause()) ? true : false;
	}
	else
	{
		return (_record.getFlag() == 0 || _record.getFlag() == 1);
	}
}

void thermoCamera::Device::SetPalleteImage(int index)
{
	if (index >= 1 && index <= 11)
	{
		if (_display) _display->ChangePallete(index);
	}
}

void thermoCamera::Device::SetAutoSize(int left, int top)
{
	if (top < 0 || left < 0) return;
	if (_display == NULL) return;
	if (_sizeOfVideoDisplay.size() < 2) return;

	HWND hWnd = _display->GetMainWindow();

	HDC current = GetDC(hWnd);
	RECT clientrect;
	GetClientRect(hWnd, &clientrect);

	int widthVideo = clientrect.right - _sizeOfVideoDisplay[1].right-left;
	int heightVideo = clientrect.bottom - top;

	SetWidthVideo(widthVideo);
	SetHeightVideo(heightVideo);

	ConfigureBuffer(0, widthVideo, heightVideo);

	int widthBar = _sizeOfVideoDisplay[1].right;
	int heightBar = _sizeOfVideoDisplay[1].bottom;
	ConfigureBuffer(1, widthBar, heightBar);
}

void thermoCamera::Device::SetTimerIntervalForRecord(unsigned int tim)
{
	////
	//_timer.~Timer();
	//if (_timer.GetStatus() == false)
	//{
	//	_timer.setInterval(tim);
	//	std::function<void()> func = std::bind(&Device::_RecordData, this);
	//	_timer.setFunction(func);
	//}
	_intervalOfRecord = tim;
}

HDC thermoCamera::Device::GetHDCBackBuffer(int index)
{
	if (_display)
	{
		HDC hdc = _display->GetHDC(index);
		return hdc;
	}

}

RECT thermoCamera::Device::GetRectangleVideo(int index)
{
	return _sizeOfVideoDisplay[index];
}

const TCHAR* thermoCamera::Device::GetPathRecord()
{
	return _record.getCurrentPath();
}

void thermoCamera::Device::SetPathToRecord(const TCHAR* path)
{
	if (!path) return;

	_record.SetPath(path);
}

void thermoCamera::Device::SetPathToAlarmSaving(const TCHAR* path)
{
	if (path == NULL)
	{
		_isAlaramSavingOn.second = false;
		return;
	}

	#if UNICODE
		wcscpy_s(_pathToAlarmImage, MAX_PATH, path);
	#else
		strcpy_s(_pathToAlarmImage, MAX_PATH, path);
	#endif

	_isAlaramSavingOn.second = true;;
}

void thermoCamera::Device::SetWidthVideo(int width)
{
	if (_sizeOfVideoDisplay.size() > 0)
	{
		_sizeOfVideoDisplay[0].right = width;
		int LeftBar = _sizeOfVideoDisplay[0].left + _sizeOfVideoDisplay[0].right + 1;
		_sizeOfVideoDisplay[1].left = LeftBar;
		if (_display)
		{
			RECT rec = { _sizeOfVideoDisplay[0].left,_sizeOfVideoDisplay[0].top,width,_sizeOfVideoDisplay[0].bottom };
			_display->SetPosition(rec, 0);
			rec = { LeftBar,_sizeOfVideoDisplay[1].top,_sizeOfVideoDisplay[1].right,_sizeOfVideoDisplay[1].bottom };
			_display->SetPosition(rec, 1);
		}
	}

}

void  thermoCamera::Device::SetHeightVideo(int height)
{
	if (_sizeOfVideoDisplay.size() > 0)
	{
		_sizeOfVideoDisplay[0].bottom = height;
		int h = _sizeOfVideoDisplay[0].bottom;
		_sizeOfVideoDisplay[1].bottom = h- MARGINBAR- MARGINBAR;
		if (_display)
		{
			RECT rec = { _sizeOfVideoDisplay[0].left,_sizeOfVideoDisplay[0].top,_sizeOfVideoDisplay[0].right,height };
			_display->SetPosition(rec, 0);
			 rec = { _sizeOfVideoDisplay[1].left,_sizeOfVideoDisplay[1].top,_sizeOfVideoDisplay[1].right,_sizeOfVideoDisplay[1].bottom };
			_display->SetPosition(rec, 1);
		}
	}
}

void thermoCamera::Device::SetMinRangeTemperature(float min)
{
	if (_display)
	{
		_display->SetMinRangeTemperature(min);
	}
}

void thermoCamera::Device::SetTemperatureMethod(int index)
{
	if (index == 0)
	{
		if (_display) _display->ResetRelativeTemp();
		_FaceDetector.ResetRelativeTemp();
		_TempRelative = false;
	}
	else if (index == 1)
	{
		if (_display) _display->SetRelativeTemp();
		_FaceDetector.SetRelativeTemp();
		_TempRelative = true;
	}
}

void thermoCamera::Device::SetMaxRangeTemperature(float max)
{
	if (_display)
	{
		_display->SetMaxRangeTemperature(max);
	}
}

std::pair<float, float> thermoCamera::Device::GetMinMaxTemperature()
{
	std::pair<float, float> temp = { 0.f,0.f };

	if (_display)
	{
		temp.first = _display->GetMinRangeTemperature();
		temp.second = _display->GetMaxRangeTemperature();
	}

	return temp;
}

void thermoCamera::Device::_setDisplay(int left, int top, int width, int height)
{
	if(!_display)	_display = new VideoDisplay();

	if (_display)
	{
		if (_TempRelative) _display->SetRelativeTemp();

		RECT rect = { left, top, width, height };
		_sizeOfVideoDisplay.push_back(rect);
		_display->SetAbsolutePosition(rect);
	}
}

bool thermoCamera::Device::_CheckInputParam( int& left, int& top, int& width, int& height)
{

	if (left <= 0 || top <= 0 || width <= 0 || height <= 0) return false;
	else
		return true;
}

bool thermoCamera::Device::_setSizeOfImage()
{
	if (_device)
	{
		_sizeOfImage = (*_device)->getSizeOfImage();
		if (_sizeOfImage.cx <= 0 || _sizeOfImage.cy <= 0) return false;
		else return true;
	}
	return false;
}

bool thermoCamera::Device::_isDisplaySet()
{
	if (_isPlaybackFromCamera())
	{
		if (_device == NULL) return false;
		if (_sizeOfImage.cx <= 0 || _sizeOfImage.cy <= 0) return false;
	}

	if (_display == NULL) return false;

	return true;
}

bool thermoCamera::Device::_StartDevice()
{
	if (_isPlaybackFromCamera())
	{
		if ((*_device)->StartStreaming() == false)
		{
			(*_device)->eFlag = thermoCamera::StateFlag::stop;
			return false;
		}
		return true;
	}
}

void thermoCamera::Device::_RemoveDevice()
{
	if (_device) {  _device = NULL; }
	if (_StreamingThread) { delete _StreamingThread; _StreamingThread = NULL; }
	if (_RecordingThread) { delete _RecordingThread; _RecordingThread = NULL; }
	if (_FaceDetectionThread) { delete _FaceDetectionThread; _FaceDetectionThread = NULL; }
}

bool thermoCamera::Device::_Play()
{
	if (_isPlaybackFromCamera())
	{
		if (_isDevicePlay()) return false;
		RECT rec = GetRectangleVideo(0);
		if (_isDevicePause()) EraseOutput(rec);

	}
	else
	{
		if (_record.getFlag() == 0) return false;
		RECT rec = GetRectangleVideo(0);
		if (_record.getFlag() == 1) EraseOutput(rec);
	}

	if (_ePlayback == Playback::fromCamera || _record.GetMode() == 1)
	{
		bool result = _StartDevice();

		try
		{
			_record.startRecord();
		}
		catch(MyError& e){}

		if (result == false)
		{
			return false;
		}
		else
		{
			_SetFlagPlay();
			return true;
		}

	}
	else if (_ePlayback == Playback::fromRecord)
	{
		_record.startRecord();
		return true;
	}
	return false;
}

bool thermoCamera::Device::_Stop()
{
	if (_isPlaybackFromCamera())
	{
		if (_isDevicePlay() == false && _isDevicePause() == false) return false;
	}
	else
	{
		if (_isRecordPlay() == false && _isRecordPause() == false) return false;
	}

	if (_ePlayback == Playback::fromCamera)
	{
		_record.stopRecord();

		(*_device)->StopStreaming();
		RECT rec = GetRectangleVideo(0);
		EraseAndUpdateWindow();
		(*_device)->eFlag = thermoCamera::StateFlag::stop;
		return true;
	}
	else
	{
		_record.stopRecord();
		return true;
	}
}

bool thermoCamera::Device::_Pause()
{
	if (_isPlaybackFromCamera())
	{
		if (_isDevicePlay() == false || _isDevicePause()) return false;
	}
	else
	{
		if (_record.getFlag() == 2 || _record.getFlag() == 1) return false;
	}

	if (_ePlayback == Playback::fromCamera)
	{
		_record.pauseRecord();

		(*_device)->eFlag = thermoCamera::StateFlag::pause;
		return true;
	}
	else
	{
		_record.pauseRecord();
		return true;
	}
	return false;
}

bool thermoCamera::Device::_RunThreadPlay()
{
	if (_isPlaybackFromCamera())
	{
		_RunThreadRecord();

		if (_StreamingThread != NULL)
		{
			if (_StreamingThread->joinable()) return true;
			else false;
		}

		_StreamingThread = new std::thread(&Device::_StreamVideo, this);
		if (_StreamingThread->joinable())
		{
			return true;
		}
		else {
			(*_device)->eFlag = thermoCamera::StateFlag::stop;
			return false;;
		}
	}
	else
	{

		_RunThreadRecord();

		if (_RecordingThread != NULL)
		{
			if (_RecordingThread->joinable()) return true;
			else false;
		}

		_RecordingThread = new std::thread(&Device::_StreamFromRecordVideo, this);
		if (_RecordingThread->joinable())
		{
			return true;
		}
		else {
			_record.stopRecord();
			return false;;
		}
	}
	
}

bool thermoCamera::Device::_RunThreadFaceDetection()
{
	if (_FaceDetectionThread != NULL)
	{
		if (_FaceDetectionThread->joinable()) return true;
		else false;
	}

	_FaceDetectionStreaming = true;

	_FaceDetectionThread = new std::thread(&Device::_FaceDetection, this);
	if (_FaceDetectionThread->joinable())
	{		
		return true;
	}
	else {
		_FaceDetectionStreaming = false;
		return false;;
	}
}

bool thermoCamera::Device::_RunThreadRecord()
{
	if (_RecordReadWriteThread != NULL)
	{
		if (_RecordReadWriteThread->joinable()) return true;
		else false;
	}

	_RecordReadWriteStreaming = true;

	_RecordReadWriteThread = new std::thread(&Device::_RecordData, this);
	if (_RecordReadWriteThread->joinable())
	{
		return true;
	}
	else {
		_RecordReadWriteStreaming = false;
		return false;;
	}
}

bool thermoCamera::Device::_StopThreadRecord()
{
	if (_RecordReadWriteStreaming == false) return false;

	_RecordReadWriteStreaming = false;

	if (_RecordReadWriteThread->joinable())
	{
		_RecordReadWriteThread->join();
		return true;
	}
	else {
		return false;
	}
}

bool thermoCamera::Device::_StopThreadPlay()
{	
	if (_isPlaybackFromCamera())
	{
		_StopThreadRecord();

		if (_StreamingThread->joinable())
		{
			_StreamingThread->join();
			if (_StreamingThread) { delete _StreamingThread; _StreamingThread = NULL; }
			return true;
		}
		else {
			return false;
		}
	}
	else
	{
		_StopThreadRecord();

		if (_RecordingThread->joinable())
		{
			_RecordingThread->join();
			if (_RecordingThread) { delete _RecordingThread; _RecordingThread = NULL; }
			return true;
		}
		else {
			return false;
		}
	}
}

bool  thermoCamera::Device::_StopThreadFaceDetection()
{
	if (_FaceDetectionStreaming == false) return false;

	_FaceDetectionStreaming = false;

	if (_FaceDetectionThread->joinable())
	{
		_FaceDetectionThread->join();
		return true;
	}
	else {
		return false;
	}
}

void thermoCamera::Device::_StreamVideo()
{
	while (_isDevicePlay() || _isDevicePause())
	{		
		if (_isDevicePlay())
		{
			if (_display->Show(_sizeOfVideoDisplay[0].left, _sizeOfVideoDisplay[0].top, (*_device)->getWidth(), (*_device)->getHeight(), _sizeOfVideoDisplay[0].right, _sizeOfVideoDisplay[0].bottom, (*_device)->getThermalData()) == false)
			{
				(*_device)->eFlag = thermoCamera::StateFlag::stop;
			}
		}
		else if(_isDevicePause())
		{
			
			if (_display->ShowWhilePause(_sizeOfVideoDisplay[0].left, _sizeOfVideoDisplay[0].top, (*_device)->getWidth(), (*_device)->getHeight(), _sizeOfVideoDisplay[0].right, _sizeOfVideoDisplay[0].bottom) == false)
			{
				(*_device)->eFlag = thermoCamera::StateFlag::stop;
			}
		}
	}
}

void thermoCamera::Device::_StreamFromRecordVideo()
{
	while (_isRecordPlay() || _isRecordPause())
	{
		if (_record.GetMode() == 0 && _isRecordPlay())
		{
			unsigned short** data = _display->GetThermalFromRecord();
			SIZE sizeOfImage = _display->GetSizeOfInputImage();
			_display->Show(_sizeOfVideoDisplay[0].left, _sizeOfVideoDisplay[0].top, sizeOfImage.cx, sizeOfImage.cy, _sizeOfVideoDisplay[0].right, _sizeOfVideoDisplay[0].bottom, data);
		}
		else if (_record.GetMode() == 0 && _isRecordPause())
		{
			unsigned short** data = _display->GetThermalFromRecord();
			SIZE sizeOfImage = _display->GetSizeOfInputImage();
			_display->Show(_sizeOfVideoDisplay[0].left, _sizeOfVideoDisplay[0].top, sizeOfImage.cx, sizeOfImage.cy, _sizeOfVideoDisplay[0].right, _sizeOfVideoDisplay[0].bottom,data);
		}
	}
}

void thermoCamera::Device::_RecordData()
{
	while (_RecordReadWriteStreaming)
	{
		try
		{
			if (_display == NULL && _sizeOfVideoDisplay.size() <= 0) return;

			if (_isPlaybackFromCamera())
			{
				if ((_isDevicePlay() || _isDevicePause()) && _isRecordPlay() && _RecordFromCameraAllowed)
				{
					if (_record.GetMode() == 1)
					{
						if (_RecordOnlyAreFaceDetected)
						{
							if (_FaceDetector.getNumOfTrackers() > 0)
							{
								_display->SaveData(_record.getCurrentPath(), _record.getCurrentNumber());
								_record.Save(_display->GetHBITMAP(2));
							}
						}
						else{
							_display->SaveData(_record.getCurrentPath(), _record.getCurrentNumber());
							_record.Save(_display->GetHBITMAP(2));
						}
					}
				}
			}
			else
			{
				if (_record.GetMode() == 0 && _isRecordPlay())
				{
					_display->LoadData(_record.getCurrentImagePath(), _record.getCurrentNumber());
					_record.Load();
				}
			}
		}
		catch (thermoCamera::MyError& e)
		{
			if (_display)
			{
				_record.stopRecord();
				_StopThreadPlay();
				_StopThreadFaceDetection();
				RECT rec = GetRectangleVideo(0);
				EraseOutput(rec);
				_ePlayback = Playback::fromCamera;
				try
				{
					RemoveDevice();
				}
				catch (thermoCamera::MyError& e) {}
			}
			switch (e)
			{
			case thermoCamera::MyError::badInput:
				MessageBox(NULL, TEXT("Wrong input!"), TEXT("Warning"), MB_OK);
				break;
			case thermoCamera::MyError::cannotOpenFile:
				MessageBox(NULL, TEXT("Cannot open the file!"), TEXT("Warning"), MB_OK);
				break;
			case thermoCamera::MyError::notInit:
				MessageBox(NULL, TEXT("Not initialize!"), TEXT("Warning"), MB_OK);
				break;
			default:
				break;
			}
		}
		std::this_thread::sleep_for(std::chrono::milliseconds(_intervalOfRecord));
	}	
}

void thermoCamera::Device::_SettingDisplayWithWindow(const HWND& hWnd, int index,const int& widthOut, const int& heightOut)
{
	//Create a compatible backbuffer
	HDC current = GetDC(hWnd);
	RECT clientrect;

	_display->SetHWND(hWnd);
	GetClientRect(hWnd, &clientrect);

	HDC buff = CreateCompatibleDC(current);
	_display->SetHDC(buff);
	
	HBITMAP hbitmap = CreateCompatibleBitmap(current, widthOut, heightOut);
	_display->SetBitMap(hbitmap);

	SelectObject(_display->GetHDC(index), (HGDIOBJ)_display->GetHBITMAP(index));

	ReleaseDC(hWnd, current);
}

bool thermoCamera::Device::_isDevicePlay() 
{
	if (_isPlaybackFromCamera()) 
	{
		if (_device)
		{
			if ((*_device)->getFlag() == 0)
			{
				return true;
			}
			else return false;
		}
		return false;
	}
	else
	{
		return false;
	}
}

bool thermoCamera::Device::_isDevicePause()
{
	if (_isPlaybackFromCamera())
	{
		if (_device)
		{
			if ((*_device)->getFlag() == 1)
			{
				return true;
			}
			else return false;
		}
		return false;
	}
	else
	{
		return false;
	}
}

bool thermoCamera::Device::_isDeviceStop()
{
	if (_isPlaybackFromCamera())
	{
		if (_device)
		{
			if ((*_device)->getFlag() == 2)
			{
				return true;
			}
			else return false;
		}
		return false;
	}
	else
	{
		return false;
	}
}

void thermoCamera::Device::_FaceDetection()
{
	bool message = true;
	while (_isFaceDetectionStreaming())
	{
		if (_display)
		{
			_FaceDetector.setWidthOut(_sizeOfVideoDisplay[INDEX_HBITMAP_OF_VIDEO].right);
			_FaceDetector.setHeightOut(_sizeOfVideoDisplay[INDEX_HBITMAP_OF_VIDEO].bottom);

			try
			{
				_FaceDetector.LBP(_display->GetHBITMAP(INDEX_HBITMAP_OF_DETECTION), *_display,_sizeOfVideoDisplay[INDEX_HBITMAP_OF_DETECTION].right, _sizeOfVideoDisplay[INDEX_HBITMAP_OF_DETECTION].bottom);				
				//_FaceDetector.TemplateMatching(_display->GetHBITMAP(INDEX_HBITMAP_OF_DETECTION), *_display, _sizeOfVideoDisplay[INDEX_HBITMAP_OF_DETECTION].right, _sizeOfVideoDisplay[INDEX_HBITMAP_OF_DETECTION].bottom);
				//_FaceDetector.FindFace(_display->GetHBITMAP(INDEX_HBITMAP_OF_DETECTION), *_display, _sizeOfVideoDisplay[INDEX_HBITMAP_OF_DETECTION].right, _sizeOfVideoDisplay[INDEX_HBITMAP_OF_DETECTION].bottom);				
			}
			catch (thermoCamera::MyError& e)
			{
				switch (e)
				{
				case MyError::cannotOpenFile:
					if(message) 
					{
						MessageBox(NULL, TEXT("Cannot open cascade classifier file, specify file path in settings!"), TEXT("Warning"), MB_OK);
						message = false;
					}
					break;
				case MyError::cannotDrawOutput:
					if (message)
					{
						MessageBox(NULL, TEXT("Cannot open image in face detector, check if video is streaming!"), TEXT("Warning"), MB_OK);
						message = false;
					}					
					break;
				case MyError::badInput:
					if (message)
					{
						MessageBox(NULL, TEXT("Wrong input parameter in face detector!"), TEXT("Warning"), MB_OK);
						message = false;
					}
					break;
				default:
					break;
				}
			}
		}
		//std::this_thread::sleep_for(std::chrono::milliseconds(sleep_thread_for_face_detection));
	}
}

