#pragma once

#include "MW4.hpp"

#include <Adept\Entity.hpp>

namespace Adept
{
	class Effect;
}

namespace MechWarrior4
{
	class Adept::Effect;

  class EffectGenerator__CreateMessage : public Adept::Entity__CreateMessage 
  {
	public:
    typedef Adept::Entity__CreateMessage BaseClass;
	Adept::ResourceID
			effectResourceID;
		Stuff::Scalar
			timeDelay;
		bool
			m_nightOnly;
		bool
			m_randomizeTime;

	EffectGenerator__CreateMessage(
		size_t length,
		int priority,
		int message_flags,
		Stuff::RegisteredClass::ClassID class_id,
		int replicator_flags,
		const ResourceID& data_list_id,
		const Stuff::LinearMatrix4D &local_to_parent,
		Stuff::Scalar age,
		int execution_state,
		ObjectID name_id,
		int entity_alignment,
		const Adept::ResourceID& effect_id
	):
		Entity__CreateMessage(
			length, 
			priority, 
			message_flags, 
			class_id,
			replicator_flags,
		  data_list_id,
		  local_to_parent,
		  age,
		  execution_state,
		  name_id,
		  entity_alignment
  		),
		effectResourceID(effect_id)
    {}
	static void
		ConstructCreateMessage(Script *script);


  };

	//##########################################################################
	//###########################   EffectGenerator::GameModel    ##############
	//##########################################################################

	class EffectGenerator__GameModel:
		public Adept::Entity::GameModel
	{
	public:

		
		enum {
			NextAttributeID = Entity__GameModel::NextAttributeID,
		};

		static bool
			ReadAndVerify(
				EffectGenerator__GameModel *model,
				ModelAttributeEntry *attribute_entry, 
				const char *data,
				char **error,
				int error_buffer = 128
			);

		static void
			ConstructGameModel(Script *script);
	};

	//##########################################################################
	//##########################    EffectGenerator    #########################
	//##########################################################################

	class EffectGenerator:
		public Adept::Entity
	{
	public:
	 typedef Entity                          BaseClass;
 
		static void
			InitializeClass();
		static void
			TerminateClass();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Run-time Construction and Destruction Support
	//
	public:
		typedef EffectGenerator__CreateMessage				CreateMessage;
		typedef EffectGenerator__GameModel					GameModel;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Run-time Construction and Destruction Support
	//
		Adept::ResourceID
			effectResourceID;
	
		Stuff::Scalar
			timeDelay,nextDelay;
		bool
			m_nightOnly;
		bool
			m_randomizeTime;
		bool
			replay;

	public:
		static EffectGenerator* 
			Make(
				CreateMessage *message,
				ReplicatorID *base_id
			);

		~EffectGenerator();

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

		void
			ClearAllEffects();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Class Data support
	//
	public:
		void
			PreCollisionExecute(Stuff::Time till);
		void
			PostCollisionExecute(Stuff::Time till);
		void
			CreateEffect();
		void
			PlayEffect();
		void
			KillEffect();
		int
			GetTableArray()
				{Check_Object(this); return Adept::NameTable::EffectGeneratorArray;}

		void
			SaveInstanceText(Stuff::Page *page);

		bool
			shouldCreateEffect;

		Stuff::ChainOf<Adept::Effect *>
			effectChain;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Class Data & Game Model Support
	//
	public:
		
		const GameModel*
			GetGameModel()
				{return Cast_Pointer(const GameModel*, gameModelResource.GetPointer());}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Class Data support
	//
	public:
		static ClassData
			*DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Test Support
	//
	public:
		void
      		TestInstance() const;
	};

}


