#ifndef __SWEBCAM_HANDLER_H__
#define __SWEBCAM_HANDLER_H__

#include <rdr/mutex.h>
#include <rfb/SSecurityMulti.h>

#if defined(__APPLE__)
#include </usr/SDK/MacOSX10.15.sdk/usr/include/c++/v1/math.h>
#include </usr/SDK/MacOSX10.15.sdk/usr/include/c++/v1/cmath>
#include </usr/SDK/MacOSX10.15.sdk/usr/include/c++/v1/queue>
#include </usr/SDK/MacOSX10.15.sdk/usr/include/c++/v1/unordered_map>
#else
#include <math.h>
#include <cmath>
#include <queue>
#include <unordered_map>
#endif

#define WEBCAM_WAIT_TIMEOUT_IN_SEC 10

namespace rfb {
	class SSecurityMulti;
}

typedef std::unordered_map<int, time_t> lastTimeMap_t;
typedef std::unordered_map<int, THREAD_ID> threadMap_t;

class SWebcamHandler {
	public:
		SWebcamHandler(rfb::SSecurityMulti* multi);
		~SWebcamHandler();
		bool handlePacket(const rdr::U8* buf, int bufLen);
		bool handleOldPacket(const rdr::U8* buf, int bufLen);
		void setClientSupportsWebcam(bool value);
		lastTimeMap_t lastTime;

	private:
		int udpPort;
		int minPort;
		int portRange;
		bool clientSupportsWebcam;
		char* userVideoDev;
		int findUdpPort();
		char* getUserVideoDev();
		static bool oldPacketType;
		bool commonHandlePacket(const rdr::U8* buf, int bufLen);
		static threadMap_t ffmpegThreadId;

		static THREAD_FUNC ffmpegThread(void* param);
		static THREAD_FUNC fifoReaderThread(void* param);
		static THREAD_FUNC udpSocketThread(void* param);
		static THREAD_FUNC fallbackStillFrameLoopThread(void* param);
		static THREAD_ID fifoReaderThreadId;
		static int fifoReaderPid;
		static THREAD_ID fallbackStillFrameLoopThreadId;
};

#endif /* __SWEBCAM_HANDLER_H__ */
