#pragma once

#include "Adept.hpp"
#include "VideoRenderer.hpp"
#include "VideoComponent.hpp"

namespace ElementRenderer {class gosFXElement;}

namespace Adept {

	class AttributeEntry;
	class Entity__ClassData;

	//#########################################################################
	//##########################  BeamComponent  ##############################
	//#########################################################################
	//
	// When instantiating this class, the following methods must be explicitly
	// defined:
	//
	//   void InitializeClass();
	//   void ReadGeometryFromResource(...)
	//   BeamComponent<C,G,B>* Make(...)
	//	  Derivation* CreateFactoryRequest(...)
	//
	// The methods having templates in this header file should work fine, but
	// explicitly define whatever you need.
	//

	class BeamComponent:
		public VideoComponent
	{
	public:
		typedef VideoComponent BaseClass;

		static void
			InitializeClass();
		static void
			TerminateClass();
		static ClassData
			*DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructor/Destructor
	//
	protected:
		BeamComponent(
			ClassData *class_data,
			MemoryStream *stream,
			VideoComponentWeb *owning_web
		);

		static ElementRenderer::gosFXElement*
			ReadFX(
				MemoryStream *stream,
				VideoComponentWeb *owning_web
			);

		void
			SkipStreamData(MemoryStream *stream);

	public:
		static BeamComponent*
			Create(
				MemoryStream *stream,
				VideoComponentWeb *owning_web
			);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Component support
	//
	public:
		ElementRenderer::gosFXElement*
			GetElement()
				{
					Check_Object(this);
					return
						Cast_Pointer(
							ElementRenderer::gosFXElement*,
							componentElement
						);
				}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Component execution
	//
	public:
		void
			ChannelChanged(Channel *channel);
		void
			Execute();

	protected:
		Entity
			*owningEntity;
		AttributeEntry
			*statusPointer;
		AttributeEntry
			*endPointer;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Accessors
	//
	public:
		void
			TestInstance();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Tool-related Functions
	//
	public:
		static ClassData*
			CreateFactoryRequest(
				FactoryRequestParameters *parameters,
				Entity__ClassData *class_data
			);
	};

}

