#pragma once

#include "ElementRenderer.hpp"

namespace ElementRenderer {

	//#########################################################################
	//#########################  ScreenQuadsElement  ################################
	//#########################################################################

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

		typedef Element BaseClass;

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

	public:
		ScreenQuadsElement(unsigned count);
		~ScreenQuadsElement();

		static ScreenQuadsElement* Make(
			Stuff::MemoryStream *stream,
			int version,
			ShapeHolder shapes
		);

		void Save(Stuff::MemoryStream *stream);

		static HGOSHEAP s_Heap;

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

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Hierarchy
	//
	public:
		void GetQuadData(
			unsigned quad,
			Stuff::Vector4D **corners,
			Stuff::RGBAColor **colors,
			Stuff::Vector2DOf<Stuff::Scalar> **uvs,
			bool **status
		);
		
		void SetQuadStatus(
			unsigned quad,
			bool status
		)
			{Check_Object(this); m_status[quad] = status;}

	protected:
		void AttachChild(Element *child);
		void DetachChild(Element *child);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Sync support
	//
	protected:
		virtual void SetSyncState();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Culling
	//
	protected:
		virtual void SetCullState();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Collision
	//
	protected:
		bool CastCulledRay(CollisionQuery *query);
		Element* FindSmallestElementContainingCulled(SphereTest *test);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// 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
		);

		int CountTriangles();

		Stuff::DynamicArrayOf<Stuff::Vector4D> m_corners;
		Stuff::DynamicArrayOf<Stuff::RGBAColor> m_colors;
		Stuff::DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > m_UVs;
		Stuff::DynamicArrayOf<bool> m_status;
	};

}
