#pragma once

#include "MW4.hpp"
#include "aiutils.hpp"

#include <Adept\Entity.hpp>
#pragma warning (push)
#include <vector>
#pragma warning (pop)

namespace MechWarrior4
{

	//##########################################################################
	//##################    Path::CreateMessage    #############################
	//##########################################################################

	class Path__CreateMessage : public Adept::Entity__CreateMessage
	{
	public:

		Adept::ResourceID pathPointsResourceID;

		Path__CreateMessage(
			size_t length,
			int priority,
			int message_flags,
			Stuff::RegisteredClass::ClassID class_id,
			int replicator_flags,
			const Adept::ResourceID& instance_id,
			const Stuff::LinearMatrix4D &creation_matrix,
			Stuff::Scalar age,
			int execution_state,
			int name_id,
			int entity_alignment,
			Adept::ResourceID path_points
		):
			Adept::Entity__CreateMessage(
				length,
				priority,
				message_flags,
				class_id,
				replicator_flags,
				instance_id,
				creation_matrix,
				age,
				execution_state,
				name_id,
				entity_alignment
			),
				pathPointsResourceID(path_points)
				{}

		static void ConstructCreateMessage(Script *script);
	};
	
	//##########################################################################
	//###########################   Path    ####################################
	//##########################################################################

	typedef Adept::Entity__ClassData						Path__ClassData;
	typedef Adept::Entity__Message							Path__Message;
	typedef Adept::Entity__ExecutionStateEngine				Path__ExecutionStateEngine;
	typedef Adept::Entity__GameModel						Path__GameModel;
	
	class Path:
		public Adept::Entity
	{
	public:
		static void InitializeClass();
		static void TerminateClass();

	//##########################################################################
	// Inheritance support
	//
	public:
		typedef Path__ClassData							ClassData;
		typedef Path__GameModel							GameModel;
		typedef Path__Message							Message;
		typedef Path__ExecutionStateEngine				ExecutionStateEngine;
		typedef Path__CreateMessage						CreateMessage;


	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Run-time Construction and Destruction Support
	//
	public:
		static Path* Make(CreateMessage *message,Adept::ReplicatorID *base_id);
		Adept::Replicator::CreateMessage* SaveMakeMessage(Stuff::MemoryStream *stream, Adept::ResourceFile *res_file);
		void SaveInstanceText(Stuff::Page *page);

	protected:
		Path(ClassData *class_data,CreateMessage *message,Adept::ReplicatorID *base_id,ElementRenderer::Element *element);
	
		~Path();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Shared Data support
	//
	public:
		static ClassData *DefaultData;
		
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Simulation Support
	//
	public:
		int
			GetTableArray()
			{Check_Object(this); return Adept::NameTable::PathArray;}
		stlport::vector<Stuff::Point3D> pathPoints;
		Adept::ResourceID pathPointsResourceID;

		Stuff::Point3D GetNearestPoint (const Stuff::Point3D& pt);
		int GetNearestIndex (const Stuff::Point3D& pt);
		void ErasePoint	(int index)
		{
			stlport::vector<Stuff::Point3D>::iterator iter;

			Verify (index>=0);
			Verify (index < pathPoints.size());
			iter = pathPoints.begin ();
			while ((index) && (iter != pathPoints.end ()))
			{
				iter++;
				index--;
			}
			Verify (iter != pathPoints.end ());
			pathPoints.erase (iter);
		}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Test Support
	//
	public:

		void TestInstance() const;
	public: // jcem
		void SaveAs2DPoly(Stuff::DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> >& Poly) const;
	};
}


