/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


		#include "core/clock.h"
		#include "platform.h"

		using namespace GS::Core;


//------------------------------------------------------------------------------
float				Clock::Getf() const
{	return (float)gtick / Platform::Get().GetClockFrequency();	}
float				Clock::GetDeltaf() const
{	return (float)dt_clock / Platform::Get().GetClockFrequency();	}
void				Clock::SetScalef(float k)
{	SetScale((int)(k * 1000.f));	}
float				Clock::GetScalef() const
{	return (float)GetScale() / 1000.f;	}
void				Clock::SetFixedDeltaFramef(float dt)
{	fixed_delta = (dt >= 0.0) ? int(dt * Platform::Get().GetClockFrequency()) : -1;	}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void				Clock::Pause(bool _pause)
{	pause = _pause;	}
void				Clock::Reset()
{
	_gtick = Platform::Get().GetClock();					// CU
	dt_clock_filter.Reset();
}
void				Clock::Update()
{
	// Clock can run up to 49 days before looping.
	if	(pause)
	{
		_gtick = 0;
		dt_clock = 0;
	}
	else
	{
		int tmp = Platform::Get().GetClock();				// CU
		int raw_dt = tmp - _gtick;						// CU
		int dt = (raw_dt * clock_scale) / 1000;			// CU

		// Fixed delta clock.
		if	(fixed_delta > 0)
			dt = (fixed_delta * clock_scale) / 1000;	// CU

		// Update tick.
		if	(_gtick != 0)
		{
			gtick += dt;
			dt_clock = dt;
		}
		else
			dt_clock = 0;

		_gtick = tmp;
		if	(dt_clock < 0)
			dt_clock = 0;

		// Filter dt_clock.
		dt_clock_filter.LogValue(dt_clock);
		int filtered_dt_clock = dt_clock_filter.GetMedian();

		dt_error += dt_clock - filtered_dt_clock;
		int dt_error_correction = dt_error >> 2;
		dt_error -= dt_error_correction;

		dt_clock = filtered_dt_clock + dt_error_correction;
	}
}
void				Clock::EatDeltaClock()
{	_gtick = Platform::Get().GetClock();	}

Clock::Clock()
{
	pause = false;

	_gtick = 0;
	gtick = 0;

	dt_clock = 0;
	dt_error = 0;
	clock_scale = 1000;

	fixed_delta = -1;
}
//------------------------------------------------------------------------------
