//===========================================================================//
// File:	caminst.hh                                                          //
// Project: Munga			                                                     //
// Contents: CameraInstance Interface 		 								           //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 08/08/95  JM  Initial coding.                                             //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#if !defined(CAMINST_HPP)
#	define CAMINST_HPP

#	if !defined (PLUG_HPP)
#		include <plug.hpp>
#	endif

#	if !defined (ORIGIN_HPP)
#		include <origin.hpp>
#	endif

#	if !defined (ROTATION_HPP)
#		include <rotation.hpp>
#	endif

#	if !defined(LINMTRX_HPP)
#		include <linmtrx.hpp>
#	endif

	class NotationFile;

	struct CameraInstance__StreamedInstance
	{
		size_t instanceSize;
		int
			cameraType,
			cameraID;
		Origin
			localOrigin;
		Radian
			clampValues[4];
	};

	//##########################################################################
	//#############################    CameraInstance    #######################
	//##########################################################################

	class CameraInstance :
		public Plug
	{
		friend class CameraInstanceManager;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//	local member data
	//
		public:

			enum {
				ErrorCameraType,
				DefaultCameraType,
				AlwaysSeesCameraType,
				CameraTypeCount,
			};

			Radian
				clampValues[4];

		protected:
			Origin
				localOrigin;
			LinearMatrix
				cameraToWorld;

			static int
				FindCameraType(const char *camera_data_type);

			void
				GetCameraTypeString(char *camera_type_string);

			Enumeration
				cameraDataType;

			int
				cameraID;

			char
				cameraName[128];

			void
				CalculateCameraRotation(
					YawPitchRoll *result,
					const Point3D &world
				);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//  public member data access functions
	//
		public:
			int
				GetCameraID()
					{Check(this); return cameraID;}

			const char*
				GetCameraName()
					{Check(this); return cameraName;}
			void
				SetCameraName(const char* camera_name)
					{Str_Copy(cameraName, camera_name, sizeof(cameraName));}

			const Enumeration
				GetCameraType()
					{Check(this); return cameraDataType;}

			const Origin&
				GetLocalOrigin()
					{Check(this); return localOrigin;}
			void
				SetLocalOrigin(const Origin &new_origin);
			const Point3D&
				GetPosition()
					{Check(this); return localOrigin.linearPosition;}

			void
				LookAt(
					Origin *result,
					const Point3D &world_point
				);
			void
				AllowLookingAt(const Point3D &world);

			virtual Logical
				CanCameraSee(const Point3D &world_point);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// 	Test Class Support
	//
		public:
			Logical
				TestInstance() const;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//	Contruction and Destruction Support
	//
		public:
			typedef CameraInstance__StreamedInstance StreamedInstance;

			CameraInstance(
				int	camera_ID,
				const Origin &camera_origin,
				Enumeration	camera_type = DefaultCameraType
			);
			CameraInstance(StreamedInstance *model);
			CameraInstance(
				NotationFile *cam_file,
				const char *camera_page_name
			);

			~CameraInstance();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//	Tool Support
	//
		public:
			void
				WriteNotationPage(NotationFile *camera_stream);
			static Logical
				CreateStreamedInstance(
					StreamedInstance *model,
					NotationFile *cam_file,
					const char *camera_page_name
				);
	};

	//##########################################################################
	//#############################    CameraInstance    #######################
	//##########################################################################

	class AlwaysSeesCameraInstance :
		public CameraInstance
	{
	public:
		AlwaysSeesCameraInstance(
			int	camera_ID,
			const Origin &camera_origin,
			Enumeration	camera_type = DefaultCameraType
		);
		AlwaysSeesCameraInstance(StreamedInstance *model);
		AlwaysSeesCameraInstance(
			NotationFile *cam_file,
			const char *camera_page_name
		);

		Logical
			CanCameraSee(const Point3D &world_point);
	};

#endif
