#pragma once

#include "ElementProxies.hpp"

namespace ElementProxies {

	class ElementPolygonMeshProxy;

	//
	//#########################################################################
	//########################    MLRVertexProxy    ##############################
	//#########################################################################
	//
	class MLRVertexProxy:
		public Proxies::VertexProxy
	{
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

		static ClassData
			*DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructors
	//
	public:
		static MLRVertexProxy*
			MakeProxy(
				ElementPolygonMeshProxy *polygon,
				int primitive_index,
				int vertex_index
			)
				{return new MLRVertexProxy(polygon, primitive_index, vertex_index);}

		void
			Destroy();

		void*
			operator new(size_t)
				{return AllocatedMemory->New();}
		void
			operator delete(void *where)
				{AllocatedMemory->Delete(where);}

	protected:
		MLRVertexProxy(
			ElementPolygonMeshProxy *mesh,
			unsigned primitive_index,
			unsigned vertex_index
		);

		~MLRVertexProxy();

		static Stuff::MemoryBlock
			*AllocatedMemory;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Testing
	//
	public:
		void
			TestInstance() const;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Vertex management functions
	//
	public:
		//
		// Copies the elements of a polygon into this polygon
		//
		ElementPolygonMeshProxy*
			GetPolygonMeshProxy()
				{
					Check_Object(this);
					return Cast_Pointer(ElementPolygonMeshProxy*, polygonMeshProxy);
				}

		Proxies::VertexProxy*
			UseNextVertexProxy();
		Proxies::VertexProxy*
			UsePreviousVertexProxy();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Vertex functions
	//
	public:
		//
		// position functions
		//
		void
			GetPosition(Stuff::Point3D *point);
		void
			SetPosition(const Stuff::Point3D &point);

		//
		// color functions
		//
		bool
			GetColor(Stuff::RGBAColor *color);
		void
			SetColor(const Stuff::RGBAColor& color);

		//
		// normal functions
		//
		bool
			GetNormal(Stuff::Normal3D *normal);
		void
			SetNormal(const Stuff::Normal3D &normal);

		//
		// UV functions
		//
		bool
			GetUVs(Stuff::DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > *vector);
		void
			SetUVs(Stuff::DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > &vector);

	protected:
		unsigned
			primitiveIndex,
			vertexIndex;
	};

}
