// Game Clock Object version 2.0  - initial version by WIP
// This is a function that will create a game clock object.
// Just use the function clock.getTimeArray() and it will
// return an object with seconds, minutes and hours
// Note: You must start the clock before it will give
// the correct time


// Copy the original GetTime() function into a GetTime_() function (both now do the same)
// Now we can modify the original GetTime() function to stop ticking!
if (typeof GetTime_ == 'undefined')
        GetTime_ = GetTime;

/**
 * Clock constructor
 * @constructor
 * @param {Boolean} redefineGetTime Make GetTime() "stop ticking" while the clock is paused. False by default
 * @param {Boolean} integer Seconds are integer. True by default. Set to false for floating point seconds.
 * Example: 
 *   var GameClock = new Clock();
 * 
 */
function Clock(redefineGetTime,integer)
{
	if(this instanceof Clock == false) 
		return new Clock(redefineGetTime,integer);

	this.sphereStart = GetTime_(); // Holds the time from when Sphere started 
	this.started = 0; // Holds the time when the clock started
	this.countdown = 0; // Holds the time we need to countdown. 
	this.split = 0; // Split time, used to pause the clock. Zero when the clock is running.
	this.delay = 0; // Holds the amount of milliseconds paused
	this.totalplay = 0; // always holds the value of: this.started + this.delay + this.previousPlayTime;
	this.GetTime = Function("", "return 0");  // Internal GetTime, will stop ticking if paused

	this.redefineGetTime = redefineGetTime === undefined ? false : redefineGetTime; // Also pause the function GetTime(). Funky!
	this.integer = integer=== undefined ? true : integer; // Seconds are integer or float

	// old gametime. Original WIP Object used this.seconds, this.minutes and this.hours
	// Gametime is the time how long the game has been running including the paused time
	this.previousGameTime = 0;

	// Playtime is the time how long the game has been running excluding the paused time
	this.previousPlayTime = 0;

	// Current hour/minutes/seconds time after using this.calc() are stored here
	this.hh= 0;
	this.mm= 0;
	this.ss= 0;
}


/**
 * Start the Clock
 * Example: 
 *   var GameClock = new Clock();
 *   GameClock.start();
 * note: You may also use unpause() to start the clock.
 */
Clock.prototype.start = function()
{
	this.GetTime = GetTime_;
	this.started = GetTime_();
	this.totalplay = this.started - this.previousPlayTime;
	this.startCountDown(this.started);
	return this;
}

Clock.prototype.startCountDown = function(start)
{
	this.stoptime = (start || this.GetTime()) + this.countdown;
}

Clock.prototype.setCountDownTimeHMS = function(hh, mm, ss)
{
	 hh = parseInt(hh, 10);
	 mm = parseInt(mm, 10);
	 ss = parseInt(ss, 10);
	 this.countdown = 1000*(hh*3600 + mm*60 + ss);
	 return this;
}

/**
 * Sets the gametime running from the previous time you played this game
 * @param {number/string} hh Hours
 * @param {number/string} mm Minutes
 * @param {number/string} ss Seconds
 * note: You could save the values from getTimeArray() to a file and read them back.
 */
Clock.prototype.setPreviousGameTimeHMS = function(hh, mm, ss)
{
	hh = parseInt(hh, 10);
	mm = parseInt(mm, 10);
	ss = parseInt(ss, 10);
	this.previousGameTime = 1000*(hh*3600 + mm*60 + ss);
	return this;
}

/**
 * Sets the playtime running from the previous time you played this game
 * @param {number/string} hh Hours
 * @param {number/string} mm Minutes
 * @param {number/string} ss Seconds
 * note: You could save the values from getTimeArray() to a file and read them back.
 */
Clock.prototype.setPreviousPlayTimeHMS = function(hh, mm, ss)
{
	hh = parseInt(hh, 10);
	mm = parseInt(mm, 10);
	ss = parseInt(ss, 10);
	this.previousPlayTime = 1000*(hh*3600 + mm*60 + ss);
	this.totalplay = this.started - this.previousPlayTime;
	return this;
}

Clock.prototype.setCountDownTimeMS = function(ms)
{
	var time = this.calcHMS(ms);
	this.setCountDownTimeHMS(time[0], time[1], time[2]);
	return this;
}

/**
 * Sets the gametime or gametime running from the previous time you played this game
 * @param {integer} ms Milliseconds
 * Example:
 *   var GameClock = new Clock();
 *
 *   //Somewhere we first saved:
 *   var savefile = OpenFile("slot1.dat");
 *   savefile.write('gametime', GameClock.getTotalGameTime() );
 *   savefile.close();
 *   
 *   //Now we set the time:
 *   var loadfile = OpenFile("slot1.dat");
 *   GameClock.setPreviousGameTimeMS( loadfile.read('gametime',0) );
 *   loadfile.close();
 */
Clock.prototype.setPreviousGameTimeMS = function(ms)
{
	var time = this.calcHMS(ms);
	this.setPreviousGameTimeHMS(time[0], time[1], time[2]);
	return this;
}

/**
 * Sets the playtime or playtime running from the previous time you played this game
 * @param {integer} ms Milliseconds
 * Example:
 *   var GameClock = new Clock();
 *
 *   //Somewhere we first saved:
 *   var savefile = OpenFile("slot1.dat");
 *   savefile.write('playtime', GameClock.getTotalPlayTime() );
 *   savefile.close();
 *   
 *   //Now we set the time:
 *   var loadfile = OpenFile("slot1.dat");
 *   GameClock.setPreviousGameTimeMS( loadfile.read('playtime',0) );
 *   loadfile.close();
 */
Clock.prototype.setPreviousPlayTimeMS = function(ms)
{
	var time = this.calcHMS(ms);
	this.setPreviousPlayTimeHMS(time[0], time[1], time[2]);
	return this;
}

/**
 * Given a time in millisecs, return an array with Hour, minutes and seconds
 * @param {integer} ms Milliseconds
 * @type Array
 * @returns an array containing 3 numbers: Hour, minutes and seconds
 */
Clock.prototype.calcHMS = function(ms)
{
	ms /=  1000;
	if(this.integer)
		ms = parseInt(ms);
	return [
		Math.floor(ms/3600) % 60,
		Math.floor(ms/60) % 60,
		ms % 60 ];
}

Clock.prototype.calcMS = function(H, M, S)
{
	return 1000 * (H*3600 + M*60 + S);
}


/**
 * Internal function. Sets internal hh, mm and ss when given millisecs
 */
Clock.prototype.calcTime = function(ms)
{
	ms /=  1000;
	if(this.integer)
		ms = parseInt(ms);
	this.hh = Math.floor(ms/3600) % 60;
	this.mm = Math.floor(ms/60) % 60;
	this.ss = ms % 60;
}

/**
 * Returns the clock time as a string
 * @type String
 * @returns the time in a string
 * Example:
 *   font.drawText( 10, 10, GameClock.getTimeString() );
 */
Clock.prototype.getTimeString = function(time)
{
	this.calcTime(time||this.getTotalPlayTime());
	return (this.hh<100 ? '0':'') + (this.hh<10 ? '0':'') + this.hh
		+ ":"
		+ (this.mm<10 ? '0':'') + this.mm
		+ ":"
		+ (this.ss<10 ? '0':'') + this.ss;
}

/**
 * For backward compatibility:
 * // Example:
 * // font.drawText(10, 10, clock.getTime());
 * //
 * // Every time you want to start keeping track of time,
 * // start the clock. If you are loading a game, you should
 * // load the time into the clock object. That way, it can keep
 * // correct time with a loaded game.
 * //
 * // clock.getTime(true) returns the time in an array
 * // Example:
 * // var time = clock.getTime(true);
 * // font.drawText(10, 10, time[0]); // Hours
 * // font.drawText(10, 20, time[1]); // Minutes
 * // font.drawText(10, 30, time[2]); // Seconds
 */
Clock.prototype.getTime = function(asArray)
{
	return asArray? this.getTimeArray() : this.getTimeString();
}

/**
 * Returns the clock time as an array
 * @param {Boolean} asNumbers When set to true it will return an array of numbers, else an array of strings. False by default.
 * @type Array
 * @returns the time in an array
 * Example:
 *   var time = GameClock.getTimeArray();
 *   font.drawText(10, 10, time[0]);
 *   font.drawText(10, 20, time[1]);
 *   font.drawText(10, 30, time[2]);
 */
Clock.prototype.getTimeArray = function(asNumbers,time)
{
	this.calcTime(time||this.getTotalPlayTime());
	if(asNumbers)
		return [ this.hh, this.mm, this.ss ];
	return [
		(this.hh<100 ? '0':'') + (this.hh<10 ? '0':'') + this.hh,
		(this.mm<10 ? '0':'') + this.mm,
		(this.ss<10 ? '0':'') + this.ss ];
}

Clock.prototype.getCountDown= function()
{
	return this.stoptime - this.GetTime();
}


/**
 * Get the millisecs the game has been running during this game session
 * @type integer
 */
Clock.prototype.getCurrentGameTime = function()
{
	return GetTime_() - this.started;
}

/**
 * Get the millisecs the game has been played during this game session
 * @type integer
 */
Clock.prototype.getCurrentPlayTime = function()
{
	return this.GetTime() - this.started;
}

/**
 * Get the millisecs the game has been running during all game sessions
 * @type integer
 */
Clock.prototype.getTotalGameTime = function()
{
	return this.getCurrentGameTime() + this.previousGameTime;
}

/**
 * Get the millisecs the game has been played during all game sessions
 * @type integer
 */
Clock.prototype.getTotalPlayTime = function()
{
	return this.GetTime() - this.totalplay;
}

/**
 * Get the millisecs the Sphere engine has been running during this session 
 * @type integer
 */
Clock.prototype.getSphereTime = function()
{
	return GetTime_() - this.sphereStart;
}

Clock.prototype.pause = function(redefineGetTime) {
	this.split = GetTime_();
	this.GetTime = Function("", "return "+ (GetTime_()-this.delay) );
	if(redefineGetTime === undefined) redefineGetTime = this.redefineGetTime;
	if(redefineGetTime)
		GetTime = this.GetTime;
	return this;
}

Clock.prototype.unpause = function(redefineGetTime) {
	if(!this.started)
		this.start();
	else
		this.delay += GetTime_() - this.split;
	this.split = 0;
	this.GetTime = Function("", "return GetTime_()-"+ this.delay );
	if(redefineGetTime === undefined) redefineGetTime = this.redefineGetTime;
	if(this.redefineGetTime)
		GetTime = this.GetTime;
	return this;
}


/**
 * Tells if the clock is running or not
 * @type Boolean
 * @returns true if the clock is paused, false if its running
 * Example:
 *   while ( GameClock.isPaused ) { AnimatePauseThingy(); CheckForUnpause(); }
 */
Clock.prototype.isPaused = function()
{
	return (this.split || !this.started);
}
