#include "rpl4.h"
#pragma hdrstop

#include "rpl4grnd.h"
#include "..\munga_l4\l4lamp.h"
#include "..\munga\terrain.h"
#include "..\rp\demopack.h"
#include "rpl4gaug.h"
#include "rpl4mssn.h"
#include "..\munga\app.h"
#include <iostream>

// #define LOCAL_TEST

#if defined(LOCAL_TEST)
#	define Test_Tell(n) std::cout << n << std::flush
#else
#	define Test_Tell(n)
#endif

//
//#############################################################################
// RPL4MethodDescription list
//#############################################################################
//
//STUBBED: UNKNOWN RB 1/15/07
extern
	MethodDescription
		*L4MethodDescription[];

MethodDescription
	RPL4ChainToPrevious = METHOD_DESCRIPTION_CHAIN(L4MethodDescription);

MethodDescription
	*RPL4MethodDescription[] =
		{
			&Compass::methodDescription,
			&ThreatIndicator::methodDescription,
			&NavDisplay::methodDescription,
			&GPS::methodDescription,
			&Ranking::methodDescription,
			&ConfigMap::methodDescription,
			&MessageBoard::methodDescription,
			&RPL4ChainToPrevious
		};

//
//#############################################################################
// RPL4GaugeRenderer
//#############################################################################
//
RPL4GaugeRenderer::RPL4GaugeRenderer(bool windowed, int *secondaryIndex, int *aux1Gauge, int *aux2Gauge)
:
	L4GaugeRenderer(windowed, secondaryIndex, aux1Gauge, aux2Gauge)
{
	Check_Pointer(this);

	static unsigned char
		mask_list[] =
			{ 0xFF, 0xBF, 0x7F, 0x3F };

	//----------------------------------------
	// Create lamp manager
	//----------------------------------------
	Check(application);
	LBE4ControlsManager
		*controls_manager = (LBE4ControlsManager*)
			(application->GetControlsManager());
	Check(controls_manager);

	lampManager = new L4LampManager(controls_manager);
	Register_Object(lampManager);
	//----------------------------------------
	// create warehouse
	//----------------------------------------
	warehousePointer = new L4Warehouse();
	Register_Object(warehousePointer);
	//----------------------------------------
	// Initialize interpreter
	//----------------------------------------
	BuildConfigurationFile(
		"gauge\\l4gauge.cfg",
		RPL4MethodDescription
	);
	//----------------------------------------
	// Enable secondary palette flashing
	//----------------------------------------
	((SVGA16 *) graphicsDisplay)->FlashPalette(
		SVGA16::SecondaryPalette,
		2.0,		// two cycles (8 changes) per second
		mask_list
	);

	Check_Fpu();
}

//
//#############################################################################
// ~RPL4GaugeRenderer
//#############################################################################
//
RPL4GaugeRenderer::~RPL4GaugeRenderer()
{
	Check(this);
	//----------------------------------------
	// Make sure all gauges removed BEFORE
	// we destroy the warehouse!!
	//----------------------------------------
	Remove(0);
	//----------------------------------------
	// destroy warehouse
	//----------------------------------------
	Check(warehousePointer);
	Unregister_Object(warehousePointer);
	delete warehousePointer;
	warehousePointer = NULL;

	Check_Fpu();
}

//
//#############################################################################
// TestInstance
//#############################################################################
//
Logical
	RPL4GaugeRenderer::TestInstance() const
{
	return GaugeRenderer::TestInstance();
}

//
//#############################################################################
// NotifyOfNewInterestingEntity
//#############################################################################
//
void
	RPL4GaugeRenderer::NotifyOfNewInterestingEntity(Entity *entity)
{
	Test_Tell("RPL4GaugeRenderer::NotifyOfNewInterestingEntity\n");
	Check(this);
	Check(entity);

	//------------------------------------------------------
	// If the entity has no gauge representation, discard it
	//------------------------------------------------------
	Check(application);
	Check(application->GetResourceFile());

	ResourceDescription
		*resource_description =
			application->GetResourceFile()->SearchList(
				entity->GetResourceID(),
				ResourceDescription::GaugeImageStreamResourceType
		);
	Test_Tell("resource_description = " << resource_description << "\n");

	if (resource_description != NULL)
	{
		//
		//---------------------------------------------------------
		// Place object in either moving list or static array
		//---------------------------------------------------------
		//
		if (entity->IsDerivedFrom(*Mover::GetClassDerivations()))
		{
			movingEntities.Add(entity);
		}
		else if (entity->IsDerivedFrom(*Terrain::GetClassDerivations()))
		{
			staticEntities.Add(entity);
		}
	}

	//------------------------------------------------------
	// Chain to "ancestor" method
	//------------------------------------------------------
	L4GaugeRenderer::NotifyOfNewInterestingEntity(entity);
	Check_Fpu();
}

//
//#############################################################################
// StartImplementation
//#############################################################################
//
void
	RPL4GaugeRenderer::LoadMissionImplementation(Mission *mission)
{
	Check(this);
#	if defined (LOCAL_TEST)
		Tell("RPL4GaugeRenderer::LoadMissionImplementation()\n");
#	endif

	//------------------------------------------------------
	// Chain to "ancestor" method
	//------------------------------------------------------
	L4GaugeRenderer::LoadMissionImplementation(mission);
	Check_Fpu();
}

//
//#############################################################################
// StopImplementation
//#############################################################################
//
void
	RPL4GaugeRenderer::ShutdownImplementation()
{
	Check(this);
#	if defined (LOCAL_TEST)
		Tell("RPL4GaugeRenderer::ShutdownImplementation()\n");
#	endif
	//------------------------------------------------------
	// Chain to "ancestor" method
	//------------------------------------------------------
	L4GaugeRenderer::ShutdownImplementation();
	Check_Fpu();
}

//
//#############################################################################
// NotifyOfNewUninterestingEntity
//#############################################################################
//
void
	RPL4GaugeRenderer::NotifyOfBecomingUninterestingEntity(Entity *entity)
{
	Test_Tell("RPL4GaugeRenderer::NotifyOfBecomingUninterestingEntity\n");
	Check(this);
	Check(entity);
	//------------------------------------------------------
	// If the entity has no gauge representation, discard it
	//------------------------------------------------------
	Check(application);
	Check(application->GetResourceFile());

	ResourceDescription
		*resource_description =
			application->GetResourceFile()->SearchList(
				entity->GetResourceID(),
				ResourceDescription::GaugeImageStreamResourceType
		);
	Test_Tell("resource_description = " << resource_description << "\n");

	if (resource_description != NULL)
	{
		//---------------------------------------------------------
		// Place entity from either moving list or static array
		//---------------------------------------------------------
		if (entity->IsDerivedFrom(*Mover::GetClassDerivations()))
		{
			movingEntities.Remove(entity);
		}
		else if (entity->IsDerivedFrom(*DemolitionPack::GetClassDerivations()))
		{
			movingEntities.Remove(entity);
		}
		else if (entity->IsDerivedFrom(*Terrain::GetClassDerivations()))
		{
			staticEntities.Remove(entity);
		}
	}

	//------------------------------------------------------
	// Chain to "ancestor" method
	//------------------------------------------------------
	L4GaugeRenderer::NotifyOfBecomingUninterestingEntity(entity);
	Check_Fpu();
}
