//===========================================================================//
// File:	door.hh                                                         //
// Project:  	RP                                                     //
// Contents: 	A terrain subsystem for management of door operation        	  //
// 							                                                     //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
//                                                                           //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. All Rights reserved //
//                   	PROPRIETARY AND CONFIDENTIAL                         //
//===========================================================================//

#if !defined (DOOR_HPP)
#	define	DOOR_HPP

#	if !defined(SUBSYSTM_HPP)
#		include <subsystm.hpp>
#	endif

#	if !defined(BOXSOLID_HPP)
#		include <boxsolid.hpp>
#	endif

	class	DoorFrame;

	//##########################################################################
	//#####################    Door::SubsystemResource    ###################
	//##########################################################################

	struct Door__SubsystemResource:
		public Subsystem::SubsystemResource
	{
		Vector3D motionExtent;
		Scalar
			travelTime,
			deadTime;
		ResourceDescription::ResourceID
			collisionID;
	};

	//##########################################################################
	//#####################    Chute::UpdateRecord         #####################
	//##########################################################################

	struct Door__UpdateRecord :
		public Subsystem::UpdateRecord
	{
		Scalar
			percentOpen;
	};

	//##########################################################################
	//#########################     CLASS    Door       ########################
	//##########################################################################

	class Door :
		public Subsystem
	{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Messaging Support
	//

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Shared Data Support
	//
	public:
		static Derivation ClassDerivations;
		static SharedData DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Attribute Support
	//
	public:
		enum {
			PercentOpenAttributeID	=	Subsystem::NextAttributeID,
			CurrentPositionAttributeID,
			VideoResourceAttributeID,
			CurrentVelocityAttributeID,
			NextAttributeID
		};

	private:

		static const IndexEntry AttributePointers[];

	protected:

		static AttributeIndexSet	AttributeIndex;

	public:

		Scalar percentOpen;
		ResourceDescription::ResourceID videoResource;
		Point3D currentPosition;
		Vector3D currentVelocity;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Model Support
	//
	public:
		enum {
			Opening = Subsystem::StateCount,
			Opened,
			Closing,
			Closed,
			StateCount
		};

		typedef void
			(Door::*Performance)(Scalar time_slice);
		typedef Door__UpdateRecord UpdateRecord;

		void
			SetPerformance(Performance performance)
			{
				Check(this);
				activePerformance = (Simulation::Performance)performance;
			}

		void
			SlideDoor(Scalar time_slice);

		void
			MoveCollisionVolume(Scalar open_percent);
		BoxedSolid*
			GetFirstBoxedSolid()
				{Check(this); return collisionVolumes;}

	protected:
		void
			WriteUpdateRecord(Simulation::UpdateRecord *message, int update_model);
		void
			ReadUpdateRecord(Simulation::UpdateRecord *message);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Construction and Destruction
	//

	public:
		typedef Door__SubsystemResource SubsystemResource;

		Door(
			DoorFrame *entity,
			int subsystem_ID,
			SubsystemResource	*subsystem_resource
		);
		~Door();

		Logical
      	TestInstance() const;

		static Logical
			CreateStreamedSubsystem(
				NotationFile					*model_file,
            const char						*model_name,
				const char						*subsystem_name,
            SubsystemResource *subsystem_resource,
				NotationFile					*subsystem_file,
				const ResourceDirectories	*directories,
				ResourceFile					*res_file
			);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Local Support
	//
	private:
		Point3D
			localExtent,
			worldExtent;

		Scalar
			phaseTimeRemaining,
			travelTime,
			deadTime;

		int collisionVolumeCount;

		BoxedSolid
			*collisionTemplates,
			*collisionVolumes;
	};

#endif
