
/* 2008 Matthew Ainge & LlamaLAN */
/* Countdown v2.0 build begun 04 February 2008 13:10 */

// Countdown
// The countdown duration is not calculated on the client.  The server stores the difference from now till then and used by
// the countdown functions.  We also cannot depend on the interval being exact if based on client time.
// This is so erroneous time or date settings on the client PC do not affect the actual countdown time.
// Client timestamps are only used to determine how much closer we are since the page loaded.
//
// To use this function, alter the <body> html tag to include the OnLoad attribute e.g. <body onLoad="commenceCountdown()">


/* Variables set by YOU! */
//
var usingLocalTimezone 	= false;		// For now, this code assumes the PHP server is in the UK.
						// If we want the countdown to hit 0 at midnight in the client's country, set this to true.
						// If the event is specific to the UK, it's more accurate to set this to false.
var usingPlurals 	= false;				// If true, taps an 's' on the end of the label for each time unit, if required (i.e. if not 1 left)
var updateFrequencyinMS = 200;			// Number of milliseconds between updates.  If every second, 1000.
						// NOTE - because of how the numbers are rounded it would look better to use more frequent
						// 		updates.  Otherwise, the seconds seem to freeze and jump occasionally.

var showMilliseconds = false;			// If you want a more dramatic flurry of milliseconds set to true.
var dayAnnounceText = ""			// What appears when we have arrived at the event's date and time.  If blank, time will just stay at 00.

// Strings used for each time unit.  Do not make it plural.
// These could simply be colons (:) with the usingPlurals flag set to false to give it a digital style
// Use your imagination.  Go wild.
var weekLabel 	= ":";		// Weeks
var dayLabel 	= ":";		// Days
var hourLabel 	= ":";		// Hours
var minuteLabel	= ":";		// Minutes
var secondLabel	= "";		// Seconds

/* Variables NOT set by YOU! */
//
var serverTimeAtLoad;			// serverTimeAtLoad is the PHP timestamp (seconds since UNIX epoch) according to the server at the time of render.
var clientTimeAtLoad;			// Collects the timestamp according to the client's PC, stored when the page runs once only
var clientTimeCurrently;		// Gets the current timestamp according to the client PC every second.
var wp, dp, hp, mp, sp;			// set up other necessary variables
var el = "";				// element we're interested in, changes during code.
var cdID = "";				// Passed in by template to target specific countdown

// Let us begin
if (usingPlurals)
	{
	// prepare the pluralisation!
	var theLetterS = "s";
	}

function commenceCountdown(cdID)
	{
	// Can pass a specific ID to match a collection of fields which are identified by a common string appended to each field name.
	// This is in case we have multiple countdowns.
	// If undefined, leave it blank.
	if (cdID == null)
		{
		cdID = "";
		}
		
	// commenceCountdown kicks the whole thing off
	if (usingLocalTimezone)
		{
		el = 'cdTZ'; 		// Highly unlikely we'll have multiple of these on the page, would be silly
		if(document.getElementById(el) != null)
			{		
			var visitortime = new Date();	// We can nab the client's local Timezone
			if(visitortime)
				{
				var visTZ = visitortime.getTimezoneOffset()/60;		// Get the offset in hours
				if(visTZ != 0)
					{
					if(visTZ < 0)
						{
						visTZ = visTZ * -1;
						}


					document.getElementById(el).innerHTML = "(Adjusted for your timezone)";
					}
				}
			}
		}

	// PHP code has written the server's NOW timestamp into countServerTime div
	el = 'cdServerTime';
	if(document.getElementById(el) != null)
		{		
		serverTimeAtLoad = parseInt(document.getElementById(el).innerHTML);
		
		// If using client timezone, add the offset to the NOW timestamp.
		// e.g. in the UK, the event day is 2008-10-08 00:00:00, and the time on the server is 2008-10-07 22:00:00.
		//        in the UK, there are 2 hours to go.  In Spain, there are 3 hours to go till the next day.
		if (usingLocalTimezone)
			{
			serverTimeAtLoad += visTZ * 3600;
			}

		serverTimeAtLoad *= 1000; 	// Gets it to the same precision as JS (to milliseconds)

		d=new Date();
		clientTimeAtLoad = d.getTime();	// Assign the current client's javascript timestamp to clientTimeAtLoad.
						// This is not changed until page refresh.
		
		
		// Shift the check of day into the function.
		// dont' forget to include clearInterval when the dayAnnounce string is displayed.
		
		if(cdID.length == 0)
			{
			// Do an initial run immediately
			cdUpdate();
			
			// Run the update() function at the interval set by updateFrequencyInMS
			cdIntervalID = window.setInterval("cdUpdate()", updateFrequencyinMS);
			}
		else
			{
			for (var i=0; i<arguments.length; i++)
				{
				// Do an initial run immediately
				cdUpdate(arguments[i]);

				// Run the update() function at the interval set by updateFrequencyInMS
				window['cdIntervalID' + arguments[i]] = window.setInterval("cdUpdate('" + arguments[i] + "')", updateFrequencyinMS);
				}
			}
		}
	}

function cdUpdate(cdID)
	{
	var eventTime;		// eventTime is the PHP timestamp (seconds since UNIX epoch) of the significant day	
	
	if (cdID == null)
		{
		cdID = "";
		}
		
	// PHP code has written the server's event timestamp into countServerEventTime div
	el = 'cdEventTime' + cdID;
	
	if(document.getElementById(el) != null)
		{
		eventTime = parseInt(document.getElementById(el).innerHTML);	
		eventTime *= 1000; 	// Gets it to the same precision as JS (to milliseconds)

		d2=new Date();						// Every update, find the new client timestamp
		clientTimeCurrently = d2.getTime();		// Get the clients timestamp

		// Find the difference between this moment and the time when the page was loaded.
		vTimeDiff = Math.round(clientTimeCurrently - clientTimeAtLoad);

		// Now, we can use this time difference to build on the actual time and date as reported
		// by the server.  We do NOT rely on the client's PC for our actual date and time.

		// Find out how far along we are from the server's time since the page was loaded.
		serverTimeCurrently = serverTimeAtLoad+vTimeDiff;

		// If this time is greater than the server's event timestamp, display the message
		if(serverTimeCurrently > eventTime && dayAnnounceText.length>0)
			{
			el = 'theDay' + cdID;
			document.getElementById(el).innerHTML = dayAnnounceText;
			window.clearInterval(window['cdIntervalID' + cdID]);		// Stop the regular update
			}
		else
			{
			// If there's no set message, make sure we hit 0 and then stop updates after the countdown reads zero.
			if(serverTimeCurrently >= eventTime)
				{
				serverTimeCurrently = eventTime;
				window.clearInterval(window['cdIntervalID' + cdID]);		// Stop the regular update
				}		
			// Otherwise, we continue to count down

			// Time left is the server's event timestamp minus the time passed since page load.
			// Exciting stuff.
			millisecondsUntilEvent = eventTime - serverTimeCurrently;

			// The next block works out how much time is left in each unit of measurement
			weeks = Math.floor(millisecondsUntilEvent/604800000);
			millisecondsUntilEvent -= weeks * 604800000;
			days = Math.floor(millisecondsUntilEvent/86400000);
			millisecondsUntilEvent -= days * 86400000;
			hours = Math.floor(millisecondsUntilEvent/3600000);
			millisecondsUntilEvent -= hours * 3600000;
			minutes = Math.floor(millisecondsUntilEvent/60000);
			millisecondsUntilEvent -= minutes * 60000;
			seconds = millisecondsUntilEvent/1000;

			// Want to kill off any pluralisation of these strings, in case the last update added an S.
			sp = secondLabel;
			mp = minuteLabel;
			hp = hourLabel;
			dp = dayLabel;
			wp = weekLabel;

			// If the update is less than a second, let's display the milliseconds
			if(showMilliseconds)
				{
				seconds = seconds.toFixed(3);
				}
			else
				{
				seconds = Math.floor(seconds);
				}

			// If using plurals, lets add them if needed.
			if(usingPlurals)
				{
				if (seconds != 1) sp += theLetterS;
				if (minutes != 1) mp += theLetterS;
				if (hours != 1) hp += theLetterS;
				if (days != 1) dp += theLetterS;
				if (weeks != 1) wp += theLetterS;
				}

			// If any measurement is less than 10, pad out the result to look nice.
			if(seconds < 10) seconds = "0" + seconds;
			if(minutes < 10) minutes = "0" + minutes;
			if(hours < 10) hours = "0" + hours;
			if(days < 10) days = "0" + days;
			if(weeks < 10) weeks = "0" + weeks;

			// Now place the formatted unit count strings into the proper elements in the countdown block.
			if(document.getElementById('cdS' + cdID) != null)
				{
				document.getElementById('cdS' + cdID).innerHTML = seconds;
				document.getElementById('cdM' + cdID).innerHTML = minutes;
				document.getElementById('cdH' + cdID).innerHTML = hours;
				document.getElementById('cdD' + cdID).innerHTML = days;
				document.getElementById('cdW' + cdID).innerHTML = weeks;

				// Now place the formatted labels into the proper elements				
				document.getElementById('cdSlabel' + cdID).innerHTML = sp;
				document.getElementById('cdMlabel' + cdID).innerHTML = mp;
				document.getElementById('cdHlabel' + cdID).innerHTML = hp;
				document.getElementById('cdDlabel' + cdID).innerHTML = dp;
				document.getElementById('cdWlabel' + cdID).innerHTML = wp;

				if(document.getElementById('tz' + cdID) != null)
					{
					// Keep the timezone area cleared
					document.getElementById('tz' + cdID).innerHTML = "";
					}
				}
			}
		}
	}
