/*
 * Counter class
 * - increments a counter with images as digits
 * - given a start date, start value, and increment steps/second
 * - the counter calculates the estimated count, and starts incrementing from this point
 * @author Umair Kayani
 * 
 *  @param id - id of counter container
 * Config options:
 *	startValue 		- value to start counter at
 *	startDate		- the date which the startValue was set format (datestring ie. 'October 13, 1975 11:13:00')
 *	incrementRate 	- the amount of steps/second to increment by ie.  5
 *	numOrder		- direction in which digits should be output to container		
 */
 
function Counter( id, configs){
	
	this.id = id; // element id of counter container
	this.configs = configs;
	
	this.currentValue = this.configs.startValue || 0;
	this.startDate = (this.configs.startDate)? new Date(this.configs.startDate): new Date();
	this.incrementRate = this.configs.incrementRate || 0.5; // defaults to one/ 2 second
	
	// order in which numbers are outputted, 0 is normal, 1 is reversed
	this.numOrder = this.configs.numOrder || 0;
	
	var parentObject = this; // reference to this, for use within function defs
	//counter container
	this.counterContainer = document.getElementById(id);
	//initialization code starts here
	
		// calculate approximate currentValue based on current date
	var currentDate = new Date();
	// number of seconds since start date
	var dateDifference =  currentDate.getTime()/1000 - this.startDate.getTime()/1000;
	// increment currentValue by calculated amount
	this.currentValue += Math.round(dateDifference * this.incrementRate);

	
	this.counterContainer.innerHTML = number2HTML(addCommas(this.currentValue));
	
	// end of initialization
	
	// private var, interval id - used to stop timer
	var intervalId;
	
	
	
	/* Priviledged methods */
	
	// start increment, set incrementCount to be called on a set interval
	this.startIncrement = function(){
		/* issue with setInterval - uses window as scope, rather than current object's method.
		 * fix: call the method inside of a function, to stay in current scope
		*/
		intervalId = setInterval(function(){incrementCounter();}, 1000);
	}		
	
	// stop increment
	this.stopIncrement = function(){
		clearInterval(intervalId);
	}
	
	/* Private Methods */
	
	// increment counter, and update container to show changes
	function incrementCounter(){

		parentObject.currentValue += parentObject.incrementRate;
		parentObject.counterContainer.innerHTML = number2HTML(addCommas(Math.round(parentObject.currentValue)));
	}
	
	// private method to format digits
	// note comma's are denoted as the letter 'c'
	// possibly allow someone to override formatter for custom formatting.
	function digitFormatter(digit){
		var html = "";
		var d = (digit == ',') ? 'c': digit;
		html += "<span class='d" + d + "'><b>";
		
		html += digit + "</b></span>";
		return html;
	}
	
	// private method, converts formatted number to html
	function number2HTML(strNum){
		var html = "";
		var numLength;
		
		// determine direction in which to output
		if(parentObject.numOrder){
			numLength = strNum.length;
			while(numLength){
				html += digitFormatter(strNum.charAt(numLength - 1));
				numLength--;
			}
		}
		else {
			numLength = 0;
			while(numLength < strNum.length){
				html += digitFormatter(strNum.charAt(numLength));
				numLength++;
			}
		}
		
		return html;
	}
	
	// private method, adds commas to number
	function addCommas(numStr)
	{
		numStr += '';
		var rgx = /(\d+)(\d{3})/;
		while (rgx.test(numStr)) {
			numStr = numStr.replace(rgx, '$1' + ',' + '$2');
		}
		return numStr;
	}

}
