#pragma once

#include <conio.h>
#include <chrono>
#include <iostream>
#include <sstream>
#include <queue>
#include "Rx.LFR/LightFieldRuntime.h"
#include "Rx.LFR/ICudaData.h"
#include "Rx.LFR/CalibrationManager.h"
#include "Rx.LFR/Cuda.h"
#include "Rx.LFR/CudaCompute.h"
#include "Rx.LFR/ImageQueue.h"

#include "opencv2/core.hpp"

#include "Rx.Core\RxException.h"
#include "Rx.CluViz.Core.CluVizTool/CvCluVizTool.h"
//#include "Rx.CluViz.Core.ST/ST.h"

#include "ofThread.h"

#include "Poco/Timestamp.h"
#include "Poco/Timer.h"
#include "Poco/Stopwatch.h"

#include <lcm/lcm-cpp.hpp>
#include "total_focus_image.hpp"
#include "recorder_status.hpp"

class RxProcessor : public ofThread {

public:

	enum IMAGE_DISPLAY_TYPE {
		RAW = 0,
		TOTAL_FOCUS = 1,
		DEPTH_MAP = 2,
		REFOCUS = 3
	};

	RxProcessor();
	RxProcessor(unsigned int uID, Rx::LFR::CCalibration& xDefaultCalibration);
	~RxProcessor();
	void setCameraCalibration(unsigned int uID, Rx::LFR::CCalibration& xDefaultCalibration);
	void setImageFormat(Rx::CRxImageFormat fmt);
	int start();
	int stop();
	void threadedFunction();
	void addImage(Rx::CRxImage xImage);
	void drawImage(Rx::CRxImage& img);
	void totalFocusProc();
	void depthMapProc();
	void refocusProc();
	void flipImage(Rx::CRxImage& img, int dir);
	int queueSize();
	void rawImageProc();
	void initCudaWithImage();
	void setDisplayType(IMAGE_DISPLAY_TYPE t);

private:

	queue<unsigned char*> imageQueue;
	//queue<Rx::CRxImage> imageQueue;

	Rx::LFR::CCudaCompute xCudaCompute;
	Rx::LFR::ICudaDataImages* pxImages;
	Rx::LFR::CImageQueue m_xImageBuffer;
	Rx::CRxImage xCapturedImage;
	Rx::CRxImage xOutputImage;
	Rx::CRxImageFormat imageFormat;
	
	unsigned int uID;
	int iHandle;
	int frameCounter;
	int displayRate;
	double dFocus;
	std::chrono::high_resolution_clock::time_point displayClockStart;


	lcm::LCM lcm;
	exlcm::recorder_status recStat;
	exlcm::total_focus_image lcmImage;

	bool haveCameraCal;
	bool imageUpdated;
	bool cudaReady;
	bool downsample;
	bool imageOverLCM;

	cv::Mat tmpImage;

	IMAGE_DISPLAY_TYPE displayType;



};
