/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016 Raytrix GmbH. All rights reserved.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once

#include "DLLInterface.h"
#include "ParametersPimpl.h"
#include "Parameters.h"

#include "CudaDevice.h"
#include "Rx.Core.Ex/RxImage.h"

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// namespace: Rx.LFR
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace Rx
{
	namespace LFR
	{
		class CSuperResolution_Impl;
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Provides methods to perform super resolution.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		class RX_API CSuperResolution : public CParametersPimpl<CSuperResolution_Impl, Params::ESuperResolution::ID, Interfaces::ESuperResolution::ID>
		{
		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Default constructor.
			/// </summary>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			CSuperResolution();

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Move constructor.
			/// </summary>
			///
			/// <param name="xSuperResolution"> [in,out] The super resolution instance. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			CSuperResolution(CSuperResolution&& xSuperResolution);

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Destructor.
			/// </summary>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			~CSuperResolution();

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Add image to the super resolution algorithm.
			/// </summary>
			///
			/// <param name="xImage"> [in] The image. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			void AddImage(const CRxImage& xImage);

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Executes the super resolution.
			/// </summary>
			///
			/// <param name="xSuperResolvedImage"> [out] The super resolved image. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			void Execute(CRxImage& xSuperResolvedImage);

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Sets the CUDA device for the super resolution algorithm.
			///
			///		If no CUDA device is set then the CPU implementation of the super resolution algorithm is used.
			/// </summary>
			///
			/// <param name="xCudaDevice"> The CUDA device. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			void SetCudaDevice(const CCudaDevice& xCudaDevice);

		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Move assignment operator.
			/// </summary>
			///
			/// <param name="xSuperResolution"> [in,out] The super resolution instance. </param>
			///
			/// <returns> The instance. </returns>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			CSuperResolution& operator=(CSuperResolution&& xSuperResolution);
		};
	}
}
