//===========================================================================//
// File:	lattice.hpp                                                         //
// Project: MUNGA           Brick: Lattice Manager	                          //
// Contents: 																					  //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 12/20/94  ECH  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc.                //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#if !defined(LATTICE_HPP)
#	define LATTICE_HPP

#	if !defined(NODE_HPP)
#		include <node.hpp>
#	endif

#	if !defined(BNDGBOX_HPP)
#		include <bndgbox.hpp>
#	endif

#	if !defined(ENVIRNMT_HPP)
#		include <envirnmt.hpp>
#	endif

#	if !defined(NETWORK_HPP)
#		include <network.hpp>
#	endif

#	if !defined(SLOT_HPP)
#		include <slot.hpp>
#	endif

	class BoundingBoxTree;

	//##########################################################################
	//########    Support types for InterestOrigin & InterestManager    ########
	//##########################################################################

	enum InterestType
	{
		VisualInterestType,
		AudioInterestType,
      GaugeInterestType,
      CollisionInterestType
	};

	typedef int InterestDepth;

	const InterestDepth DefaultInterestDepth = 1;

	enum InterestPriority
	{
		LowInterestPriority = 0,
		HighInterestPriority
	};

	//##########################################################################
	//###########################    LatticeZone    ############################
	//##########################################################################

   class ExtentBox;

   //
   // HACK - Lattice zones support being connected to each in variously
   // interesting ways.  For now there is only one.
   //

   class LatticeZone:
   	public Plug
   {
	public:
   	LatticeZone(const ExtentBox &extents);
      ~LatticeZone();

	private:
   	TaggedBoundingBoxOf<LatticeZone>
      	boundingBox;
   };

	//##########################################################################
	//#########################    EnvironmentZone    ##########################
	//##########################################################################

   class EnvironmentZone:
   	public LatticeZone
   {
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructor, Destructor, and Testing
	//
	public:
   	EnvironmentZone(
      	const ExtentBox &extents,
         const Environment &environment
      );
      ~EnvironmentZone();

		Logical
			TestInstance() const;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// HACK - Accessors
	//
	public:
      Environment*
      	GetEnvironment()
         	{return &environment;}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Private data
	//
   private:
      Environment
      	environment;
   };

	//##########################################################################
	//###########################    InterestZone    ###########################
	//##########################################################################

   class BoxedSolidTree;
   class CollisionOrigin;

   //
   // HACK - Right now the interest zone holds data that would normally
   // be within its own zone, i.e., environment zones, collision zones,
   // audio zones, etc...,  The interest zone should hold sockets to
   // zones which are included in its interesting "domain"
   //

   class InterestZone:
   	public LatticeZone
   {
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructor, Destructor, and Testing
	//
	public:
   	InterestZone(
       	const ExtentBox &extents,
      	InterestZoneID interest_zone_id,
			BoxedSolidTree *collision_root,
			EnvironmentZone *environment_zone,
			BoundingBoxTree *existance_root
		);
		~InterestZone();

		Logical
			TestInstance() const;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// HACK - Accessors
	//
	public:
		InterestZoneID
			GetInterestZoneID();
		BoxedSolidTree*
			GetCollisionRoot();
		Environment*
			GetEnvironment();
		BoundingBoxTree*
			GetExistanceRoot();

		void
			AdoptCollisionOrigin(CollisionOrigin *collision_origin);
		CollisionOrigin*
			GetCollisionOrigin();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Private data
	//
	private:
		InterestZoneID
			interestZoneID;
		BoxedSolidTree
			*collisionRoot;
		EnvironmentZone
			*environmentZone;
		CollisionOrigin
			*collisionOrigin;
		BoundingBoxTree
			*existanceRoot;
	};

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~ InterestZone inlines ~~~~~~~~~~~~~~~~~~~~~~~~~

	inline InterestZoneID
		InterestZone::GetInterestZoneID()
	{
		Check(this);
      return interestZoneID;
   }

   inline BoxedSolidTree*
      InterestZone::GetCollisionRoot()
   {
   	Check(this);
      return collisionRoot;
	}

	inline Environment*
		InterestZone::GetEnvironment()
	{
		Check(this);
		Check(environmentZone);
		return environmentZone->GetEnvironment();
	}

	inline BoundingBoxTree*
		InterestZone::GetExistanceRoot()
	{
		Check(this);
		return existanceRoot;
	}

	inline void
		InterestZone::AdoptCollisionOrigin(CollisionOrigin *collision_origin)
	{
		Check(this);
		Verify(collisionOrigin == NULL);
		Check_Pointer(collision_origin);
		collisionOrigin = collision_origin;
	}

	inline CollisionOrigin*
      InterestZone::GetCollisionOrigin()
   {
   	Check(this);
      return collisionOrigin;
   }

	//##########################################################################
	//###########################    InterestArena    ##########################
	//##########################################################################

   //
   // HACK - The interest arena maintains sets of interest zones.  Since
   // we only have one interest zone at present the interest arena has
   // only the capability to reference one interest zone
   //

   class InterestArena:
   	public Node
   {
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructor, Destructor, and Testing
	//
	public:
		InterestArena(InterestZone *interest_zone);
      ~InterestArena();

		Logical
			TestInstance() const;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// HACK - Accessors
	//
	public:
      InterestZoneID
      	GetInterestZoneID();
      BoxedSolidTree*
      	GetCollisionRoot();
      Environment*
      	GetEnvironment();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Interest Zone and Entity support
	//
	public:
		//
		//--------------------------------------------------------------
		// Boolean IncludesInterestZone(InterestArena, InterestZoneID)
		//
		// Description:
		// Does the interest arena include the interest zone?
		//
		// Parameters:
		// InterestArena - reference to the interest arena.
		// InterestZoneID - id of the interest zone.
		//
		// Returns:
		// True if it does, otherwise False
		//--------------------------------------------------------------
		//

		//
		//--------------------------------------------------------------
		// Boolean IncludesPosition(InterestArena, 3DPosition)
		//
		// Description:
		// Does the interest arena include the spatial position?
		//
		// Parameters:
		// InterestArena - reference to the interest arena.
		// 3DPosition- the spatial position.
		//
		// Returns:
		// True if it does, otherwise False
		//--------------------------------------------------------------
		//

		//
		//--------------------------------------------------------------
		// ArenaEntityList GetArenaList(InterestArena)
		//
		// Description:
		// Returns a list of resident entities and associated attributes
		// based on interest zone connectivity.  The actual return will
		// probably by a safe iterator, meaning that it is resilient to
		// changes in the underlying data structures.
		//
		// Parameters:
		// Reference to the interest arena.
		//
		// Return:
		// ArenaEntityList - a list of resident entities and extracted
		// data from interest zone connectivity.
		//--------------------------------------------------------------
		//

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Private data
	//
   private:
   	SlotOf<InterestZone*>
      	interestZoneSocket;
   };

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~ InterestArena inlines ~~~~~~~~~~~~~~~~~~~~~~~~

   inline InterestZoneID
      InterestArena::GetInterestZoneID()
   {
      Check(&interestZoneSocket);
      Check(interestZoneSocket.GetCurrent());
      return interestZoneSocket.GetCurrent()->GetInterestZoneID();
   }

   inline BoxedSolidTree*
      InterestArena::GetCollisionRoot()
   {
      Check(&interestZoneSocket);
      Check(interestZoneSocket.GetCurrent());
      return interestZoneSocket.GetCurrent()->GetCollisionRoot();
   }

   inline Environment*
      InterestArena::GetEnvironment()
   {
      Check(&interestZoneSocket);
      Check(interestZoneSocket.GetCurrent());
      return interestZoneSocket.GetCurrent()->GetEnvironment();
   }

	//##########################################################################
	//###########################    LatticeManager    #########################
	//##########################################################################

   //
   // HACK - The lattice manager managers connected lattices of zones
   // of a particular type
   //

   class LatticeManager:
   	public Node
   {
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructor, Destructor, and Testing
	//
	public:
   	LatticeManager();
      ~LatticeManager();
   };

	//##########################################################################
	//#######################    InterestLatticeManager    #####################
	//##########################################################################

   class EntityID;
   class ResourceFile;

   //
   // HACK - the interest lattice manager manages the lattice of interest
   // zones.  Right now, is stubbed out for one interest zone.
   //

	class InterestLatticeManager:
		public LatticeManager
	{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructor, Destructor, and Testing
	//
	public:
		InterestLatticeManager();
		~InterestLatticeManager();

		Logical
			TestInstance() const;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Interest arena and entity support
	//
	public:
		//
		//--------------------------------------------------------------
		// InterestArena
		//		MakeInterestArena(OriginInterestZoneID, Type, DepthCalibration)
		//
		// Description:
		// Establishes an interest arena the locus of which is an interest
		// zone,  The arena is established with a type and depth
		// specification (see interest manager).
		//
		// Parameters:
		// OriginInterestZoneID- id of the interest zone.
		// Type - a type of interest.
		// DepthCalibration - a specification of the "depth" or "cost" associated
		// with extent of the arena.
		//
		// Return:
		// InterestArena - a reference to the created interest arena.
		//--------------------------------------------------------------
		//
      InterestArena*
      	MakeInterestArena(
         	InterestZoneID,
            InterestType,
            InterestDepth
         );

      #if 0
		//
		//--------------------------------------------------------------
		// DestroyInterestArena(InterestArena)
		//
		// Description:
		// Destroys the interest arena.
		//
		// Parameters:
		// InterestArena - Reference to the interest arena.
		// UpdateInterestArena(InterestArena, DepthCalibration)
		//
		// Description:
		// Updates the interest arenas internal data structures.  This method
		// is called by the interest manager.
		//
		// Parameters:
		// InterestArena - Reference to the interest arena.
		// DepthCalibration - new depth of arena extent.
		//--------------------------------------------------------------
		//
      void
      	DestroyInterestArena(InterestArena*);
      #endif

		//
		//--------------------------------------------------------------
		// InterestZoneID
		//		SearchForEntityInterestZone(OriginInterestZoneID, EntityID)
		//
		// Description:
		// If an entity has changed interest zones (its current location
		// is not within the bounding volume of it interest zone) then
		// this method searches prior adjacent interest zones for the entity.
		//
		// Parameters:
		// OriginInterestZoneID - id of the interest zone to begin the
		// search from.
		// EntityID - id of the entity.
		//
		// Return:
		// A reference to the interest zone if found, otherwise NULL.
		//--------------------------------------------------------------
		//
		InterestZoneID
			SearchForEntityInterestZone(
				InterestZoneID old_interest_zone_ID,
				const EntityID &entityID
			);

		//
		//--------------------------------------------------------------
		// InterestZoneID
		//--------------------------------------------------------------
		//
		InterestZone*
			GetInterestZone(InterestZoneID interest_zone_ID);

		//
		//--------------------------------------------------------------
		// HACK ******************
		//--------------------------------------------------------------
		//
      static void
         CreateZoneResources(
            ResourceFile *resource_file,
            NotationFile *zone_notation_file
         );

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Private data
	//
   private:
   	SlotOf<InterestZone*>
      	interestZoneSocket;
	};

#endif

