/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016 Raytrix GmbH. All rights reserved.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once

#include "DLLInterface.h"
#include "Pimpl.h"
#include "Camera.h"

#include "Rx.Core/RxString.h"

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// namespace: Rx.LFR
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace Rx
{
	namespace LFR
	{
		class CCameraServer_Impl;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	The camera server.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		class RX_API CCameraServer : public CPimpl<CCameraServer_Impl, Interfaces::ECameraServer::ID>
		{
		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Default constructor.
			/// </summary>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			CCameraServer();

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Move constructor.
			/// </summary>
			///
			/// <param name="xCameraServer"> [in,out]The camera server instance. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			CCameraServer(CCameraServer&& xCameraServer);

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Destructor.
			/// </summary>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			~CCameraServer();

		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Sets a string that activates a find filter in the FindCameras method.
			///
			/// 	By default the FindCameras method searches for all cameras (empty string). If you want to find only cameras of a
			/// 	certain type you can provide a filter here.
			///
			/// 	Examples:
			/// 	- Find only type A cameras:            "TypeA"
			/// 	- Find only type A and type D cameras: "TypeA;TypeD"
			/// </summary>
			///
			/// <param name="sxFilter"> The filter string. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			void SetFindOnlyFilterString(const CRxString& sxFilter);

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Searches for all cameras.
			/// </summary>
			///
			/// <param name="sxDllLookupPath"> (Optional) Full path to device driver files. </param>
			///
			/// <returns> The number of found cameras. </returns>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			unsigned FindCameras(const CRxString& sxDllLookupPath = "");

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Releases the driver DLLs and destroys all cameras.
			/// </summary>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			void Release();

		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Gets IDevice with given ID.
			/// </summary>
			///
			/// <param name="uCamIndex"> Zero-based ID of the device. </param>
			///
			/// <returns> null if it fails, else the device. </returns>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			CCamera& GetCamera(unsigned uCamIndex);

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Gets the total number of devices.
			/// </summary>
			///
			/// <returns> The device count. </returns>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			unsigned GetCameraCount() const;

		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Adds the given status message callback function to the internal list of callbacks.
			///
			/// 	Adding the same function pointer twice will only update the given context pointer. This prevents multiple adds of the
			/// 	same callback function.
			/// </summary>
			///
			/// <param name="pxCallback"> The callback function. </param>
			/// <param name="pvContext">  [in] The callback context. Can be any pointer that is passed to the callback function. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			void AddStatusMessageCallback(TFuncStatusMsg pxCallback, void* pvContext);

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Removes the given status message callback function.
			///
			/// 	Does nothing if the given function pointer has not been added to the list of callbacks.
			/// </summary>
			///
			/// <param name="pxCallback"> The callback function to remove. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			void RemoveStatusMessageCallback(TFuncStatusMsg pxCallback);

		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Move assignment operator.
			/// </summary>
			///
			/// <param name="xCameraServer"> [in,out]The camera server. </param>
			///
			/// <returns> The instance. </returns>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			CCameraServer& operator=(CCameraServer&& xCameraServer);
		};
	}
}
