//===========================================================================//
// File:	evtstat.cpp                                                         //
// Project: MUNGA           Brick: Event Manager                             //
// Contents: interface specification of event manager                        //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 05/15/96  ECH  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc.                //
//                      PROPRIETARY AND CONFIDENTIAL                         //
//===========================================================================//

#include "AdeptHeaders.hpp"

#include "EventStatistics.hpp"
#include "Application.hpp"

//#############################################################################
//##########################    EventStatistics    ############################
//#############################################################################

//
//#############################################################################
//#############################################################################
//
EventStatistics::EventStatistics(
	ClassID class_id,
	Receiver::MessageID message_ID
):
	Plug(DefaultData),
	classID(class_id),
	messageID(message_ID),
	eventCount(0)
{
}

//#############################################################################
//########################    EventStatisticsManager    #######################
//#############################################################################

EventStatisticsManager*
	EventStatisticsManager::Instance = NULL;
EventStatisticsManager::ClassData*
	EventStatisticsManager::DefaultData = NULL;

void
	EventStatisticsManager::InitializeClass()
{
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			EventStatisticsManagerClassID,
			"Adept::EventStatisticsManager",
			Plug::DefaultData
		);
	Register_Object(DefaultData);
}

void
	EventStatisticsManager::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

//
//#############################################################################
//#############################################################################
//
EventStatisticsManager::EventStatisticsManager():
	Plug(DefaultData),
	eventStatisticsSocket(NULL, true)
{
	printedReport = false;
}

//
//#############################################################################
//#############################################################################
//
void
	EventStatisticsManager::Maintain(Event *event)
{
	Check_Object(this);
	Check_Object(event);
	
	//
	// If the application is not running then it is not time to collect
	// statistics yet
	//
	Check_Object(Application::GetInstance());
	if (
		Application::GetInstance()->GetApplicationState()
		 != ApplicationStateEngine::RunningGameState
	)
	{
		return;
	}

	//
	// Add statistics for this event
	//
	ClassID 
		class_ID;
	Receiver::MessageID 
		message_ID;
	long 
		index_value;
	EventStatistics 
		*event_statistics;
	
	message_ID = event->messageToSend->messageID;
	class_ID = event->targetReceiver.GetCurrent()->GetClassID();
	index_value = class_ID * 1000 + message_ID; // HACK to create unique key
	if ((event_statistics = eventStatisticsSocket.Find(index_value)) == NULL)
	{
		event_statistics = new EventStatistics(class_ID, message_ID);
		Register_Object(event_statistics);
		eventStatisticsSocket.AddValue(event_statistics, index_value);
	}
	Check_Object(event_statistics);
	event_statistics->eventCount++;
}

//
//#############################################################################
//#############################################################################
//
void
	EventStatisticsManager::Report()
{
	Check_Object(this);
	
	//
	// Print Report
	//
	TableIteratorOf<EventStatistics*, long>
		iterator(&eventStatisticsSocket);
	EventStatistics
		*event_statistics;

	SPEW((
		GROUP_ADEPT_EVENT,
		"EventStatisticsManager::Report - event_count=%d",
		iterator.GetSize()
	));
	while ((event_statistics = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(event_statistics);
		
		SPEW((
			GROUP_ADEPT_EVENT,
			"EventStatisticsManager::Report - %7d %7d %7d+",
			event_statistics->classID,
			event_statistics->messageID,
			event_statistics->eventCount
		));

		Receiver::ClassData* class_data =
			Cast_Pointer(
				Receiver::ClassData*,
				FindClassData(event_statistics->classID)
			);
		Check_Object(class_data);
		const Receiver::MessageEntry *entry =
			class_data->GetMessageEntry(event_statistics->messageID);

		if (entry)
		{
			Check_Pointer(entry);
			Check_Pointer(entry->messageName);
			SPEW((
				GROUP_ADEPT_EVENT,
				"%s::%s",
				class_data->GetClassName(),
				entry->messageName
			));
		}
		else
		{
			Warn(entry == NULL);
			SPEW((GROUP_ADEPT_EVENT, ""));
		}
	}
	eventStatisticsSocket.DeletePlugs();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	EventStatisticsManager::TestInstance()
{
	Verify(IsDerivedFrom(DefaultData));
}
