//===========================================================================//
// File:	Map.hpp                                                   //
// Project: MUNGA           Brick: Interest Manager	                       //
// Contents: Interface specifications for interest manager						  //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  -----------------------------------------------------------//
// 11/04/94  ECH  Initial coding.                                            //
// 11/29/94  JMA  Changed Identities to IDs                                  //
// 02/10/95  CPB  Added GaugeInterestType                                    //
// 08/25/97  ECH  Infrastructure changes.                                    //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc.                //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#pragma once

#include "Adept.hpp"
#include "Entity.hpp"
#include <ElementRenderer\GroupElement.hpp>

namespace ElementRenderer {class GridElement;}

namespace Adept {

	class Map;
	class Zone;
	class Tile;

	const Stuff::Scalar c_ZoneSize=1280.0f;
	const Stuff::Scalar c_TileSize=160.0f;
	enum {e_TilesPerZone=8};

	class Zone__ResourceData
	{
	public:
		ResourceID
			m_geometryResourceID,
			m_bspResourceID,
			m_materialResourceID;

		void
			TestInstance() const
				{}
	};

	//########################################################################
	//###########################    Zone    #################################
	//########################################################################

	class Zone:
		public ElementRenderer::GroupElement
	{
		friend class Map;
		friend class Entity;

	public:
		typedef Zone__ResourceData ResourceData;

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

		void
			TestInstance();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructors/Destructors
	//
	protected:
		Zone();
		~Zone();

		void
			Save(Stuff::MemoryStream *stream);

		void
			CreateTileGrid(
				Stuff::Scalar row,
				Stuff::Scalar column
			);

		unsigned
			m_flags;
		BYTE
			m_row,
			m_column;
		Stuff::ChainOf<Entity*>
			m_executors,
			m_dormant,
			m_simulated,
			m_rendered;
		Stuff::ChainOf<ElementRenderer::Element*>
			m_tiledEntities;
		ElementRenderer::GridElement
			*m_tileGrid;
		Resource
			m_bspResource,
			m_materialResource;
		BYTE
			*m_materialArray;

	public:
		const Stuff::Plane
			*m_planes;
		WORD
			m_planeCount;

		Entity::InterestLevel
			GetInterestLevel()
				{Check_Object(this); return static_cast<Entity::InterestLevel>(m_flags&Entity::InterestLevelMask);}
		void
			SetInterestLevel(Entity::InterestLevel type)
				{Check_Object(this); m_flags &= ~Entity::InterestLevelMask; m_flags |= type;}
		void
			SetInterestLevel(Entity* entity, Entity::InterestLevel type);

		void
			TestInstance() const;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Ownership
	//
	protected:
		void
			AttachChild(ElementRenderer::Element *child);
		void
			DetachChild(ElementRenderer::Element *child);

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

		void
			Draw(
				ElementRenderer::CameraElement *camera,
				const ElementRenderer::StateChange *inherited_state,
				int clipping_state
			);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Execution Control
	//
	protected:
		void
			EnableExecution();
		void
			ActivateZone();
		void
			EnableRendering();

		void
			DisableExecution();
		void
			DeactivateZone();
		void
			DisableRendering();

		void
			AddExecutor(Entity *entity);
		void
			RemoveExecutor(Entity *entity);

		void
			HookUpCollision(Entity *entity);
		void
			UnhookCollision(Entity *entity);

		void
			PreCollisionExecute(Stuff::Time till);
		void
			SyncMatrices(bool update_locator);

	public:
		BYTE
			GetMaterial(Stuff::Point3D& point);
	};
}
