/**********************************************************************************************************************************************
///////////////////////////////////////       Class to  manage the profil time and stats of the scene   //////////////////////////////////////
***********************************************************************************************************************************************/

#include	"ZooProfile.h"

ZProfile::ZProfile(int newNbStats)
{
	nbStats = newNbStats;
	bench.resize(nbStats);

	for(int i=0; i<nbStats; i++)
	{
		bench[i].counter	 = 0;
		bench[i].counterTick = 0;
		for(int k=0; k<64; k++)		bench[i].time[k] = 0;
		for(k=0; k<64; k++)			bench[i].tick[k] = 0;
	}
}



void ZProfile::BeginProfile(int nb)
{
	GetTimePassed(&bench[nb].baseTime);
}

void ZProfile::BeginProfileCYCLE(int nb)
{
	DWORD	*val = &bench[nb].baseTick;
	__asm {
			rdtsc
			mov         ebx, val
			mov         [ebx], eax
	}
}



void ZProfile::EndProfile(int nb)
{
	bench[nb].time[bench[nb].counter] = GetTimePassed(&bench[nb].baseTime);
	bench[nb].counter++;
	bench[nb].counter &= 64;
}

void ZProfile::EndProfileCYCLE(int nb)
{
	DWORD	*val = &bench[nb].baseTick;
	__asm {
			rdtsc
			mov         ebx, val
			sub         eax, [ebx]
			mov         [ebx], eax
	}
	bench[nb].tick[bench[nb].counterTick] = *val;
	bench[nb].counterTick++;
	bench[nb].counterTick &= 64;
}



float ZProfile::GetAverageTime(int nb)
{
	float	average = 0;
	for(int i=0; i<64; i++)		average += bench[nb].time[i];
	return average/64.0f;
}

DWORD ZProfile::GetAverageCYCLE(int nb)
{
	DWORD	average = 0;
	int		i;
	for(i=0; i<64; i++)		average += bench[nb].tick[i];
	return average/64;
}





void ZProfile::AddProfile(int nb)
{
	bench[nb].time[bench[nb].counter] += GetTimePassed(&bench[nb].baseTime);
}

void ZProfile::AddProfileCYCLE(int nb)
{
	DWORD	*val = &bench[nb].baseTick;
	__asm {
			rdtsc
			mov         ebx, val
			sub         eax, [ebx]
			mov         [ebx], eax
	}
	
	bench[nb].tick[bench[nb].counterTick] += *val;
	
	__asm {
			rdtsc
			mov         ebx, val
			sub         eax, [ebx]
			mov         [ebx], eax
	}
}

void ZProfile::InitProfile(int nb)
{
	bench[nb].time[bench[nb].counter] = 0;
}

void ZProfile::InitProfileCYCLE(int nb)
{
	bench[nb].tick[bench[nb].counterTick] = 0;
}


void ZProfile::NextProfile(int nb)
{
	bench[nb].counter++;
	bench[nb].counter &= 64;
}

void ZProfile::NextProfileCYCLE(int nb)
{
	bench[nb].counterTick++;
	bench[nb].counterTick &= 64;
}


///////////////////////////////////////////////////////////////////////////////////////////////
/// GetTimePassed()																			///
///																							///
///		This function will return the time passed in milliseconds since the					///
///		last update. It returns a decimal number, like 0.03 for 30 milliseconds.			///
///		We need a decimal number so we can multiply other numbers with it.					///
///																							///
///////////////////////////////////////////////////////////////////////////////////////////////

float GetTimePassed(DWORD *lastTime)
{
	// if the game just started, set lasttime to the 
	// current time this prevents the game from 
	// thinking that several hours have passed from 
	// the last frame.
	if (*lastTime == 0)		*lastTime = timeGetTime();

	// get the current time
	DWORD curTime = timeGetTime();
	
	// calculate the offset
	float	timeoffset = (float)(curTime - *lastTime);
	
	// put the current time in the lasttime variable
	*lastTime = curTime;

	// return the time offset as a decimal
	return (timeoffset / 1000.0f);
}

