/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016 Raytrix GmbH. All rights reserved.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once

#include "DLLInterface.h"
#include "Pimpl.h"

#include "CudaCompute.h"
#include "Rx.Core/RxString.h"

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// namespace: Rx.LFR
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace Rx
{
	namespace LFR
	{
		class CExport_Impl;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	An export.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		class RX_API CExport : public CPimpl<CExport_Impl, Interfaces::EExport::ID>
		{
		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Default constructor.
			/// </summary>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			CExport();

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Move constructor.
			/// </summary>
			///
			/// <param name="xExport"> [in,out] The exporter. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			CExport(CExport&& xExport);

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Destructor.
			/// </summary>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			~CExport();

		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Saves the 3D mesh provided by the given 3D depth image to binary STL format.
			/// </summary>
			///
			/// <param name="sxFile">		  The file name. </param>
			/// <param name="xImgDepth3D">    The 3D depth image. Must be of type RGBA float. </param>
			/// <param name="bUseVD">		  True to save the mesh in virtual depth units instead of metric units. </param>
			/// <param name="dMaxEdgeLength"> Vertices with a depth-variation larger than this value for at least one vertex pair are not
			/// 							  added to the mesh. </param>
			/// <param name="pdCropXY">		  (Optional) Pointer to 4 double values defining a mesh crop in X and Y. The values must be given
			/// 							  in percentage of the image dimension in the order: Left, Right, Top, Bottom. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			static void SaveMeshSTL(const CRxString& sxFile, const CRxImage& xImgDepth3D, bool bUseVD, double dMaxEdgeLength, const double* pdCropXY = nullptr);

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Saves the 3D mesh provided by the given 3D depth image to binary PLY format.
			/// </summary>
			///
			/// <param name="sxFile">	   The file name. </param>
			/// <param name="xImgFocus">   The total focus image used as color values for each vertex in the mesh. Must be of type RGBA
			/// 						   unsigned char or luminance unsigned char. </param>
			/// <param name="xImgDepth3D"> The 3D depth image. Must be of type RGBA float. </param>
			/// <param name="bUseVD">	   True to save the mesh in virtual depth units instead of metric units. </param>
			/// <param name="pdCropXYZ">   (Optional) Pointer to 6 double values defining a mesh crop in X, Y and Z. The first 4 double
			/// 						   values must be given in percentage of the image dimension in the order: Left, Right, Top,
			/// 						   Bottom. The next 2 values must be given as absolute depth values in the order: Minimum,
			/// 						   Maximum. If both values are 0, no depth crop is applied. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			static void SaveMeshPLY(const CRxString& sxFile, const CRxImage& xImgFocus, const CRxImage& xImgDepth3D, bool bUseVD, const double* pdCropXYZ = nullptr);

		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Saves the 3D point list provided by the given 3D depth image to binary PCD format.
			///
			/// 	Point Cloud Data: http://pointclouds.org/documentation/tutorials/pcd_file_format.php.
			/// </summary>
			///
			/// <param name="sxFile">	   The file name. </param>
			/// <param name="xImgDepth3D"> The 3D depth image. Must be of type RGBA float. </param>
			/// <param name="bUseVD">	   True to save the mesh in virtual depth units instead of metric units. </param>
			/// <param name="pdCropXY">    (Optional) Pointer to 4 double values defining a mesh crop in X and Y. The values must be given
			/// 						   in percentage of the image dimension in the order: Left, Right, Top, Bottom. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			static void SavePointListPCD(const CRxString& sxFile, const CRxImage& xImgDepth3D, bool bUseVD, const double* pdCropXY = nullptr);

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Saves the 3D point list provided by the given 3D depth image to binary PCD format.
			///
			/// 	Point Cloud Data: http://pointclouds.org/documentation/tutorials/pcd_file_format.php.
			/// </summary>
			///
			/// <param name="sxFile">	   The file name. </param>
			/// <param name="xImgFocus">   The total focus image used as color values for each point in the data. Must be of type RGBA
			/// 						   unsigned char or luminance unsigned char. </param>
			/// <param name="xImgDepth3D"> The 3D depth image. Must be of type RGBA float. </param>
			/// <param name="bUseVD">	   True to save the mesh in virtual depth units instead of metric units. </param>
			/// <param name="pdCropXY">    (Optional) Pointer to 4 double values defining a mesh crop in X and Y. The values must be given
			/// 						   in percentage of the image dimension in the order: Left, Right, Top, Bottom. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			static void SavePointListPCD(const CRxString& sxFile, const CRxImage& xImgFocus, const CRxImage& xImgDepth3D, bool bUseVD, const double* pdCropXY = nullptr);

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			///		Saves the 3D point list provided by the given 3D depth image to ASCII XYZ format.
			/// </summary>
			///
			/// <param name="sxFile">	   The file name. </param>
			/// <param name="xImgDepth3D"> The 3D depth image. Must be of type RGBA float. </param>
			/// <param name="bUseVD">	   True to save the mesh in virtual depth units instead of metric units. </param>
			/// <param name="pdCropXY">    (Optional) Pointer to 4 double values defining a mesh crop in X and Y. The values must be given
			/// 						   in percentage of the image dimension in the order: Left, Right, Top, Bottom. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			static void SavePointListXYZ(const CRxString& sxFile, const CRxImage& xImgDepth3D, bool bUseVD, const double* pdCropXY = nullptr);

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			///		Saves the 3D point list provided by the given 3D depth image to ASCII TXT format.
			/// </summary>
			///
			/// <param name="sxFile">	   The file name. </param>
			/// <param name="xImgDepth3D"> The 3D depth image. Must be of type RGBA float. </param>
			/// <param name="bUseVD">	   True to save the mesh in virtual depth units instead of metric units. </param>
			/// <param name="pdCropXY">    (Optional) Pointer to 4 double values defining a mesh crop in X and Y. The values must be given
			/// 						   in percentage of the image dimension in the order: Left, Right, Top, Bottom. </param>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			static void SavePointListTXT(const CRxString& sxFile, const CRxImage& xImgDepth3D, bool bUseVD, const double* pdCropXY = nullptr);

		public:

			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>
			/// 	Move assignment operator.
			/// </summary>
			///
			/// <param name="xExporter"> [in,out] The exporter. </param>
			///
			/// <returns> The instance. </returns>
			/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			CExport& operator=(CExport&& xExporter);
		};
	}
}
