#pragma once

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

namespace Adept {

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

	class ShapeComponent:
		public VideoComponent
	{
		friend class VideoRenderer;

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

		typedef VideoComponent BaseClass;

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

		static Element* ReadShape(MemoryStream *stream, bool *unique);

		void SkipStreamData(MemoryStream *stream);

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

		void CleanDamage();
		void ApplyDamage(
			const Stuff::LinearMatrix4D &damage_spot,
			Stuff::Scalar radius
		);
		void ApplyDamageDecal(
			const Stuff::LinearMatrix4D &damage_spot,
			Stuff::Scalar radius,
			MidLevelRenderer::MLRTexture *texture
		);

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

	protected:
		static MidLevelRenderer::MLRShape* Cache_Shape(
			Stuff::MemoryStream *stream,
			int version,
			int length
		);

		bool m_unique;

		static ResourceID s_Erf_Resource;
		static Stuff::HashOf<MidLevelRenderer::MLRShape*, ResourceID> *s_shapeHash;

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

}

