//===========================================================================//
// File:	videorenderer.hpp                                                   //
// Project: MUNGA           Brick: Video Renderer 	                          //
// Contents: Abstracted Base Video Renderer									        //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 03/04/97  JTR  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (B) 1997, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#pragma once

#include "Adept.hpp"
#include "Renderer.hpp"

namespace ElementRenderer
{
	class GroupElement;
}

namespace Adept {

	class Map;
	class CameraComponent;
	class VideoComponentWeb;
	class Replicator__FactoryRequestParameters;
	class Entity__ClassData;

	//##########################################################################
	//###########################    VideoRenderer    ##########################
	//##########################################################################

	class VideoRenderer:
		public Renderer
	{
	public:
		static void
			InitializeClass(Stuff::NotationFile *startup_ini);
		static void
			TerminateClass(Stuff::NotationFile *startup_ini);

		static ClassData
			*DefaultData;

		static HGOSHEAP
			s_Heap;

		static int
			s_MipBias;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Destruction, and Testing
	//
	public:
		~VideoRenderer();
		VideoRenderer(ClassData *default_data = DefaultData);

		static VideoRenderer
			*Instance;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Control and processing
	//
	public:
		void
			SetRendererStatus(RendererStatus status);

	protected:
		void
			ExecuteImplementation(Stuff::Time target_time);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Component management
	//
	public:
		enum
		{
			EnableLocatorCommandID = Renderer::RendererCommandIDCount,
			DisableLocatorCommandID,
			RendererCommandIDCount
		};

		Component*
			CreateComponent(
				ClassID component_class,
				Stuff::MemoryStream *stream,
				RendererComponentWeb *web,
				Entity *entity
			);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Interest Manager support
	//
	public:
		void
			EntityIsInteresting(
				Entity *entity,
				bool render_me
			);
		void
			EntityIsUninteresting(Entity *entity);
		void
			AttachWebToLightingZone(VideoComponentWeb *web);
		void
			DetachWebFromLightingZone(VideoComponentWeb *web);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Hierarchy
	//
	public:
		void
			SetSceneRoot(ElementRenderer::Element *element);
		ElementRenderer::Element*
			GetSceneRoot()
				{Check_Object(this); return sceneRoot;}

		CameraComponent*
			GetSceneCamera()
				{Check_Object(this); return sceneCamera;}
		virtual void
			SetCamera(CameraComponent *camera);
		void
			AddSecondaryCamera(CameraComponent *camera);
		CameraComponent*
			GetSecondaryCamera(int camera_id);

	protected:
		ElementRenderer::Element
			*sceneRoot;
		CameraComponent
			*sceneCamera;
		Stuff::SortedChainOf<CameraComponent *, int>
			secondaryCameras;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Collision stuff
	//
	public:
		void
			ProjectMouseCursorIntoCameras();
		bool
			ProjectPointOnScreen(
				Stuff::Vector2DOf<Stuff::Scalar> *cursor,
				const Stuff::Point3D &location
			);
		void
			ComputeEyeLine(
				const Stuff::Vector2DOf<Stuff::Scalar> &cursor,
				Stuff::Line3D *world_line
			);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Test functions
	//
	public:
		void
			TestInstance();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Tool functions
	//
	public:
		static Component__ClassData*
			CreateFactoryRequest(
				const char* component_type,
				Component__FactoryRequestParameters *parameters,
				Entity__ClassData *class_data
			);

		static void
			CreateRendererData(
				ResourceID				*stream_resource,
				Entity__ClassData		*class_data,
				Stuff::NotationFile		*renderer_file
			);

		static int
			CommandEncoder(const char* command_name);
	};

}

#if 1
#define VIDEO_LOAD(string) LOAD_LOGIC("Video::" string)
#else
#define VIDEO_LOAD(string)
#endif

#if 1
#define VIDEOCOMPONENT_LOAD(string) VIDEO_LOAD("Component::" string)
#else
#define VIDEOCOMPONENT_LOAD(string)
#endif

