#pragma once

#include "ElementRenderer.hpp"
#include "ListElement.hpp"

//#########################################################################
//#########################  MultiLODElement  ###############################
//#########################################################################

namespace ElementRenderer {

	class GroupElement;

	class MultiLODElement:
		public ListElement
	{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Initialization
	//
	public:
		static void InitializeClass();
		static void TerminateClass();
		static ClassData *DefaultData;

		typedef ListElement BaseClass;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructors/Destructors
	//
	protected:
		MultiLODElement(
			Stuff::MemoryStream *stream,
			int version,
			ShapeHolder shapes
		);

	public:
		MultiLODElement();
		~MultiLODElement();

		static MultiLODElement* Make(
			Stuff::MemoryStream *stream,
			int version,
			ShapeHolder shapes=NULL
		);

		void Save(Stuff::MemoryStream *stream);

		static HGOSHEAP s_Heap;

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

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Hierarchy
	//
	public:
		struct Entry
		{
			Stuff::Scalar
				m_nearSquared,
				m_fadeInSquared,
				m_fadeOutSquared,
				m_farSquared;
		};

		void AttachLOD(
			WORD index,
			Element *element,
			const Entry &entry
		);

		int AttachLODFirstAvailableSlot(
			Element *element,
			const Entry &entry
		);

	    void SetSize(WORD total_cells);

	protected:
		void DetachChild(Element *child);

		Stuff::DynamicArrayOf<Entry> m_LODs;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Drawing
	//
	protected:
		void SetDrawState();

		static DrawMethod DrawMethods[DrawStateCount];

		void InheritDrawMethod(
			CameraElement *camera,
			const StateChange *inherited_state,
			int clipping_state
		);
		void OverrideDrawMethod(
			CameraElement *camera,
			const StateChange *inherited_state,
			int clipping_state
		);
	};

}
