/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016 Raytrix GmbH. All rights reserved.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once

#include "DLLInterface.h"

#include "OpenGlInterop.h"

#include "Rx.Core.Ex/RxImage.h"
#include "Rx.Core.Ex/RxArrayDouble.h"

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// namespace: Rx.LFR
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace Rx
{
	namespace LFR
	{
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	CUDA data: Images.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		class RX_API ICudaDataImages
		{
		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			virtual void Upload(EImage::ID eImgID, const Interop::Runtime28::IImage* pxImage) = 0;

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			virtual void Upload(EImage::ID eImgID, const CRxImage& xImage) = 0;

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			virtual void Download(EImage::ID eImgID, Interop::Runtime28::IImage* pxImage) const = 0;

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			virtual void Download(EImage::ID eImgID, CRxImage& xImage) const = 0;

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			virtual bool IsValid(EImage::ID eImgID) const = 0;

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Gets the image format of the image defined by the given ID.
			/// </summary>
			///
			/// <param name="eImgID"> The image ID. </param>
			///
			/// <returns> The image format. </returns>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			virtual const CRxImageFormat& GetImageFormat(EImage::ID eImgID) const = 0;

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Frees memory used by image defined by eImgID. This invalidates the image.
			/// </summary>
			///
			/// <param name="eImgID"> The image ID. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			virtual void Free(EImage::ID eImgID) = 0;

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Frees the memory used by all images. This invalidates all images.
			/// </summary>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			virtual void FreeAll() = 0;

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Gets the CUDA device pointer to the data of the image defined by the given ID.
			/// </summary>
			///
			/// <remarks> The pointer maps to the memory on a CUDA device and cannot be used on the host. </remarks>
			///
			/// <param name="eImgID"> The image ID. </param>
			///
			/// <returns> The image device pointer. </returns>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			virtual void* GetImageDevicePointer(EImage::ID eImgID) const = 0;

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Gets device pointer pitch.
			/// </summary>
			///
			/// <param name="eImgID"> The image ID. </param>
			///
			/// <returns> The device pointer pitch. </returns>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			virtual size_t GetDevicePointerPitch(EImage::ID eImgID) const = 0;

		protected:

			ICudaDataImages() { }
			virtual ~ICudaDataImages() { }
		};

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	CUDA data: Textures.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		class RX_API ICudaDataTextures
		{
		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Updates the OpenGL texture of the image defined by the given ID.
			///
			/// 	This copies the image into the texture and creates a valid texture ID if the texture has not been created before. The
			/// 	calling thread must own the OpenGL context that owns the texture.
			/// </summary>
			///
			/// <param name="eImgID">		  The image ID. </param>
			/// <param name="xOpenGL">		  [in] The OpenGlInterop class. </param>
			/// <param name="bCreateMipmaps"> (optional) True to create mipmaps of the texture. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			virtual void UpdateTexture(EImage::ID eImgID, COpenGlInterop& xOpenGL, bool bCreateMipmaps = false) = 0;

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Gets the image format of the image defined by the given ID.
			/// </summary>
			///
			/// <param name="eImgID"> The image ID. </param>
			///
			/// <returns> The image format. </returns>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			virtual const CRxImageFormat& GetImageFormat(EImage::ID eImgID) const = 0;

		protected:

			ICudaDataTextures() { }
			virtual ~ICudaDataTextures() { }
		};
	}
}
