/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2015 Raytrix GmbH. All rights reserved.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once

#ifndef RX_STATIC
    #ifdef RXCOREEX_EXPORTS
		#define RXCOREEX_API __declspec(dllexport)
    #else
		#define RXCOREEX_API __declspec(dllimport)
    #endif
#else
	#define RXCOREEX_API
#endif

#include "Rx.Core/RxString.h"
#include "RxArrayUInt.h"
#include "RxArrayDouble.h"
#include "RxArrayString.h"

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// namespace: Rx
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace Rx
{
	template<class T1, class T2>
	class CKeyValueMap;

	/**
	\addtogroup RxCore_Tools
	**/
	/// @{

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	Handles a collection of meta data of different types.
	/// </summary>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	class RXCOREEX_API CRxMetaData
	{
	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Default constructor.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxMetaData();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Copy constructor.
		/// </summary>
		///
		/// <param name="xData"> The data. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxMetaData(const CRxMetaData& xData);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Destructor.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		~CRxMetaData();

	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Assignment operator.
		/// </summary>
		///
		/// <param name="xData"> The data. </param>
		///
		/// <returns> A shallow copy of this object. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxMetaData& operator=(const CRxMetaData& xData);

	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Clears this object to its blank/initial state.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void Clear();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the element count.
		/// </summary>
		///
		/// <returns> The element count. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		size_t GetElementCount() const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets all information about the given element.
		/// </summary>
		///
		/// <param name="nIdx">    The index of the element. </param>
		/// <param name="sxName">  [out] The name of the element. </param>
		/// <param name="sxType">  [out] The type of the element. </param>
		/// <param name="sxGroup"> [out] The group of the element. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void GetElementInfos(size_t nIdx, CRxString& sxName, CRxString& sxType, CRxString& sxGroup) const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets all information about the given element.
		/// </summary>
		///
		/// <param name="sxName">  [in] The name of the element. </param>
		/// <param name="sxType">  [out] The type of the element. </param>
		/// <param name="sxGroup"> [out] The group of the element. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void GetElementInfos(const CRxString& sxName, CRxString& sxType, CRxString& sxGroup) const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Query if metadata has element with label sxLabel.
		/// </summary>
		///
		/// <param name="sxLabel"> The Label. </param>
		///
		/// <returns> True if element, false if not. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		bool HasElement(const CRxString& sxLabel) const;

	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Adds an element into the respective parameter map.
		/// </summary>
		///
		/// <remarks> If an element already exists in the map it gets overwritten. </remarks>
		///
		/// <param name="sxLabel"> The name of the element. </param>
		/// <param name="sxGroup"> The group of the element. </param>
		/// <param name="uData">   The value of the element. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void AddElement(const CRxString& sxLabel, const CRxString& sxGroup, unsigned uData);
		void AddElement(const CRxString& sxLabel, const CRxString& sxGroup, double dData);
		void AddElement(const CRxString& sxLabel, const CRxString& sxGroup, const CRxString& sxData);
		void AddElement(const CRxString& sxLabel, const CRxString& sxGroup, const CRxArrayUInt& xData);
		void AddElement(const CRxString& sxLabel, const CRxString& sxGroup, const CRxArrayDouble& xData);
		void AddElement(const CRxString& sxLabel, const CRxString& sxGroup, const CRxArrayString& xData);

	public:

		void SetElement(const CRxString& sxLabel, unsigned uData);
		void SetElement(const CRxString& sxLabel, double dData);
		void SetElement(const CRxString& sxLabel, const CRxString& sxData);
		void SetElement(const CRxString& sxLabel, const CRxArrayUInt& xData);
		void SetElement(const CRxString& sxLabel, const CRxArrayDouble& xData);
		void SetElement(const CRxString& sxLabel, const CRxArrayString& xData);

	public:

		void GetElement(const CRxString& sxLabel, unsigned& uData) const;
		void GetElement(const CRxString& sxLabel, double& dData) const;
		void GetElement(const CRxString& sxLabel, CRxString& sxData) const;
		void GetElement(const CRxString& sxLabel, CRxArrayUInt& xData) const;
		void GetElement(const CRxString& sxLabel, CRxArrayDouble& xData) const;
		void GetElement(const CRxString& sxLabel, CRxArrayString& xData) const;

	private:

		CKeyValueMap<CRxString, CRxString>* m_pxMap;
	};

	/// @}
}

#pragma make_public(Rx::CRxMetaData)
