//===========================================================================//
// File:	renderer.cc                                                         //
// Project: MUNGA           Brick: Renderer Manager	                       //
// Contents: Interface specification Renderer and Renderer Manager			  // 
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 11/21/94  ECH  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc.                //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#include "AdeptHeaders.hpp"

#include "RendererManager.hpp"
#include "Map.hpp"
#include "Player.hpp"
#include "Map.hpp"
#include "Application.hpp"
#include "AudioRenderer.hpp"

//#############################################################################
//#########################    RendererManager    #############################
//#############################################################################

//
// Shared Data Support
//
RendererManager::ClassData*
	RendererManager::DefaultData = NULL;

RendererManager*
	RendererManager::Instance = NULL;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	RendererManager::InitializeClass()
{
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			RendererManagerClassID,
			"Adept::RendererManager",
			Receiver::DefaultData,
			0,
			NULL
		);
	Register_Object(DefaultData);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	RendererManager::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	RendererManager::TestInstance()
{
	Verify(IsDerivedFrom(DefaultData));
	Check_Object(&adoptedRenderers);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	RendererManager::AdoptRenderer(Renderer *renderer)
{
	Check_Object(this);

	adoptedRenderers.AddValue(renderer, renderer->rendererType);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	RendererManager::FindRendererType(const char *renderer_name)
{
	Check_Object(this);
	if (!_stricmp(renderer_name, "VideoRenderer"))
		return VideoRendererType;
	else if (!_stricmp(renderer_name, "AudioRenderer"))
		return AudioRendererType;
	else
		return ReservedForGameModelRendererType;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	RendererManager::EntityIsInteresting(
		Entity *entity,
		bool render_me
	)
{
	Check_Object(this);
	Check_Object(entity);

	SortedChainIteratorOf<Renderer*, int>
		renderers_iterator(&adoptedRenderers);
	Renderer *renderer;
	while ((renderer = renderers_iterator.ReadAndNext()) != NULL)
	{
		Check_Object(renderer);
		renderer->EntityIsInteresting(entity, render_me);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	RendererManager::EntityIsUninteresting(Entity *entity)
{
	Check_Object(this);
	Check_Object(entity);

	SortedChainIteratorOf<Renderer*, int>
		renderers_iterator(&adoptedRenderers);
	Renderer *renderer;
	while ((renderer = renderers_iterator.ReadAndNext()) != NULL)
	{
		Check_Object(renderer);
		renderer->EntityIsUninteresting(entity);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	RendererManager::Execute(Time target_render_time)
{
	Check_Object(this);

	//
	//-------------------------------
	// Now, execute all the renderers
	//-------------------------------
	//
	SortedChainIteratorOf<Renderer*, int> renderers_iterator(&adoptedRenderers);
	Renderer *renderer;
	while ((renderer = renderers_iterator.ReadAndNext()) != NULL)
	{
		Check_Object(renderer);
		renderer->Execute(target_render_time);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	RendererManager::ActivateRenderers()
{
	Check_Object(this);

	Renderer
		*renderer;
	SortedChainIteratorOf<Renderer*, int>
		renderers_iterator(&adoptedRenderers);

	while ((renderer = renderers_iterator.ReadAndNext()) != NULL)
	{
		Check_Object(renderer);
		Verify(renderer->rendererStatus != Renderer::ActiveRendererStatus);
		renderer->SetRendererStatus(Renderer::ActiveRendererStatus);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	RendererManager::DeactivateRenderers()
{
	Check_Object(this);

	Renderer
		*renderer;
	SortedChainIteratorOf<Renderer*, int>
		renderers_iterator(&adoptedRenderers);

	while ((renderer = renderers_iterator.ReadAndNext()) != NULL)
	{
		Check_Object(renderer);
		renderer->SetRendererStatus(Renderer::InactiveRendererStatus);
	}
}
