/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016 Raytrix GmbH. All rights reserved.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once

#include "DllInterface.h"
#include "Rx.Interop.Runtime30/IMemory.h"

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// namespace: Rx
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace Rx
{
	// Forward declaration to private class
	template<class T> class CRxArrayBase;

	/**
	\addtogroup RxCore_Tools
	**/

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	An array of unsigned integers.
	/// </summary>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	class RXCOREEX_API CRxArrayUInt : public Interop::Runtime30::IMemory
	{
	public:

		/// <summary> Defines an alias representing the type of the elements in this array. </summary>
		typedef unsigned TValue;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Default constructor. Creates an empty array.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArrayUInt();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Constructor. Creates a new array with the given number of uninitialized elements.
		/// </summary>
		///
		/// <param name="nElementCount"> The number of elements. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArrayUInt(size_t nElementCount);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Constructor. Creates a new array with the given number of initialized elements.
		/// </summary>
		///
		/// <param name="nElementCount"> The number of elements. </param>
		/// <param name="tInitValue">    The initial value of each element in this array. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArrayUInt(size_t nElementCount, const TValue& tInitValue);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Copy constructor. Creates a copy of the given array.
		/// </summary>
		///
		/// <param name="xArray"> The array to copy. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArrayUInt(const CRxArrayUInt& xArray);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Destructor. Removes all elements from this array.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual ~CRxArrayUInt();

	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Assignment operator.
		/// </summary>
		///
		/// <param name="xArray"> The array to copy. </param>
		///
		/// <returns> This array. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArrayUInt& operator=(const CRxArrayUInt& xArray);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Array indexer operator.
		/// </summary>
		///
		/// <param name="nIdx"> The index. </param>
		///
		/// <returns> The indexed value. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		TValue& operator[](size_t nIdx);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Array indexer operator.
		/// </summary>
		///
		/// <param name="nIdx"> The index. </param>
		///
		/// <returns> The indexed value. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		const TValue& operator[](size_t nIdx) const;

	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the pointer to the internal data.
		/// </summary>
		///
		/// <returns> The pointer. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		TValue* GetDataPtr();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the pointer to the internal data.
		/// </summary>
		///
		/// <returns> The pointer. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		const TValue* GetDataPtr() const;

	public:

		/************************************************************************/
		/* Rx::Interop::Runtime30::IMemory                                      */
		/************************************************************************/

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the size of a single value in this array.
		/// </summary>
		///
		/// <returns> The element size. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual size_t GetElementSize() const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the number of elements in this array.
		/// </summary>
		///
		/// <returns> The length. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual size_t Length() const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Query if this object is valid. Returns always true.
		/// </summary>
		///
		/// <returns> True if valid, false if not. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual bool IsValid() const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Set the size of this array to the given number of elements.
		/// </summary>
		///
		/// <param name="nElementCount"> Number of elements. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void New(size_t nElementCount);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Set the size of this array to the given number of elements.
		/// </summary>
		///
		/// <param name="nElementCount"> Number of elements. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void Resize(size_t nElementCount);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Clears the array.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void Delete();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Sets the internal memory to zeros.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void Reset();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Copies the content of the given source memory into this array. Sets the size of this array to the size of the memory.
		/// </summary>
		///
		/// <param name="pxSrcMemory"> The source memory. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void CopyFrom(const IMemoryAccess* pxSrcMemory);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the pointer to the internal data.
		/// </summary>
		///
		/// <returns> The pointer. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual const void* GetPointer() const
		{
			return GetDataPtr();
		}

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the pointer to the internal data.
		/// </summary>
		///
		/// <returns> The pointer. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void* GetPointer()
		{
			return GetDataPtr();
		}

	protected:

		/// <summary> The internal data. </summary>
		CRxArrayBase<TValue>* m_pxData;
	};

	/// @}
}

#pragma make_public(Rx::CRxArrayUInt)
