#pragma once

#include "MAXProxies.hpp"

namespace MAXProxies {
	//
	//#########################################################################
	//##########################    MAXVertex    ###############################
	//#########################################################################
	//
	class MAXVertex:
		public Proxies::VertexProxy
	{
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

		static ClassData
			*DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructors
	//
	public:
		static MAXVertex*
			MakeProxy(
				MAXPolygonMesh *mesh,
				int index,
				int texture_index,
				Point3 *vertex,
				int face_index
			)
				{return new MAXVertex(mesh, index, texture_index, vertex, face_index);}

		void
			Destroy();

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

	protected:
		MAXVertex(
			MAXPolygonMesh *mesh,
			int index,
			int texture_index,
			Point3 *vertex,
			int face_index
		);
		~MAXVertex();

		static Stuff::MemoryBlock
			*AllocatedMemory;

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

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

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// 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(const Stuff::DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > &vector);


	protected:
		Point3
			proxiedVertex;
		int
			vertexIndex;

		int
			vertexTextureIndex;

		int 
			faceIndex;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// helper functions
	//
	public:
		static Point3*
			AllocateRecord();
		Point3
			GetProxiedVertex()
				{Check_Object(this); return proxiedVertex;}

		int GetVertexIndex()
			{Check_Object(this); return vertexIndex;}
	};
}
