var Counters = new Array(); // global

/** The Counter object constructor.
* All parameters are optional
*    pParent: existing HTML element such as a div.  If none, then body is assumed parent
*
*  If used, the following parameters must be included together:
*    pValue: initial value of the counter
*    pGrowthRate: growth rate per second
*    pDelay: intial value of counter delay between updates, in milliseconds (1000 = 1 sec)
*/
Counter = function (pParent, pId, pValue, pGrowthRate) {

	// private variables
	var _id = '';
	var _value = 0;
	var _growthRate = 0; // growth rate per second
	var _loadingString = '';
	var _currencyPosition = 'L';
	var _decimalPlaces = 2;
	var _separatorSymbol = ',';
	var _decimalSymbol = '.';
	var _currency = 'DOLLAR';
	var _currencySymbol = new Array();
	_currencySymbol["POUND"] = unescape('%A3');
	_currencySymbol["DOLLAR"] = '$';
	_currencySymbol["EURO"] = unescape('%u20AC');
	_currencySymbol["YEN"] = unescape('%A5');

	var me = this; // internal refernece to object; for use in timer routines
	var _timeoutId = 0;
	var _delay = -1; // use rand

	// HTML elements
	var _f = null; // span for string display

  // Public Methods
  this.getId = getId;
  this.setId = setId;
  this.getDelay = getDelay;
  this.setDelay = setDelay;
  this.setGrowthRate = setGrowthRate;
  this.getGrowthRate = getGrowthRate;
  this.getValue = getValue;
  this.setValue = setValue;
  this.dumpProps = dumpProps;
  this.getCrrencyPosition = getCurrencyPosition;
  this.setCurrencyPosition = setCurrencyPosition;
  this.getDecimalPlaces = getDecimalPlaces;
  this.setDecimalPlaces = setDecimalPlaces;
  this.getCurrency = getCurrency;
  this.setCurrency = setCurrency;
  this.getLoadingString = getLoadingString;
  this.setLoadingString = setLoadingString;
  this.setSeparatorSymbol = setSeparatorSymbol;
  this.getSeparatorSymbol = getSeparatorSymbol;
  this.setDecimalSymbol = setDecimalSymbol;
  this.getDecimalSymbol = getDecimalSymbol;
  this.displayValue = displayValue;
  this.start = start;
  this.stop = stop;
  this.running = running;

	var _dMin = 200; // min rand delay range
	var _dMax = 1100;  // max rand delay range
  // one-time initialization
  _initializeCounter(pParent, pId, pValue, pGrowthRate);

  function setId(id) {	_id = id;  }
  function getId() {	return _id;  }
  function setGrowthRate(x) {_growthRate = x; }
  function getGrowthRate() {	return _growthRate; }
  function setValue(v) { _value = v;  }
  function getValue() {	return _value;  }
  function setCurrencyPosition(x) {_currencyPosition = x}
  function getCurrencyPosition() {return _currencyPosition}
  function setDecimalPlaces(x) { _decimalPlaces = x}
  function getDecimalPlaces() { return _decimalPlaces }
  function setCurrency(x) { _currency = x}
  function getCurrency() { return _currency}
  function setDecimalSymbol(x) {_decimalSymbol = x}
  function getDecimalSymbol() {return _decimalSymbol}
  function setSeparatorSymbol(x) {_separatorSymbol = x;}
  function getSeparatorSymbol() {return _separatorSymbol}

  function setLoadingString(s) { 
	_loadingString = s;
	if (_f) {
	  _f.innerHTML = _loadingString;
	}
  }
  function getLoadingString() { return _loadingString}

  function setDelay(x) {
	var d = -1;
	if (x < 0) {
	  while (d < _dMin || d > _dMax) {
		d = Math.random() * 10000;
	  }
	  _delay = d; 
	}
	else {
	  _delay = x;
	}
  }
  function getDelay() {	return _delay;  }

  function dumpProps(loc){
	var s = "";
	if (loc) { s = loc + " | " };
	s = s + "id: " + getId()
	  +  " | value: " + getValue()
	  +  ' | growthRate: ' + getGrowthRate()	  
	  +  ' | delay: ' + getDelay()	  
	  +  ' | currency: ' + _currency
	  +  ' | currencySymbol: ' + _currencySymbol[_currency]
	  +  ' | decimalSymbol: ' + _decimalSymbol
	  +  ' | separatorSymbol: ' + _separatorSymbol
	  +  ' | loadingString: ' + _loadingString
	  + '<p>';
	  return s;
  }

	// formatSeparators
	// The value to be formatted shouldn't have any formatting already.
	//
	// s - A number or number as a string
	// inD - Input decimal (string value). Example: '.'
	// outD - Output decimal (string value). Example: '.'
	// sep - Output separator (string value). Example: ','
	function formatSeparators(s, inD, outD, sep) {
	  s += '';
	  var dpos = s.indexOf(inD);
	  var sEnd = '';
	  if (dpos != -1) {
		sEnd = outD + s.substring(dpos + 1, s.length);
		s = s.substring(0, dpos);
	  }
	  var rgx = /(\d+)(\d{3})/;
	  while (rgx.test(s)) {
		s = s.replace(rgx, '$1' + sep + '$2');
	  }
	  return s + sEnd;
	}

   function displayValue() {
	 //limit to two decimal places and convert to String
	 s = (Math.round(_value * 100) / 100).toFixed(_decimalPlaces)
	 s = formatSeparators(s,'.',_decimalSymbol,(_separatorSymbol == " " ? "&nbsp;" : _separatorSymbol));
	 s = (_currencyPosition == "L") ? _currencySymbol[_currency] + "&nbsp;" + s : s + "&nbsp;" + _currencySymbol[_currency];
	 return s;
   }

	 function _timer() {
	   _value  += _growthRate * (_delay / 1000);
	   //_f.innerHTML = _delay + "   " + _t + "    " + me.displayValue();
	   _f.innerHTML = me.displayValue();
	   _timeoutId = window.setTimeout(_timer, _delay);
	 }
	 
	 function running() {
	   return _timeoutId != 0;
	 }
	 
	 function start(value, growthRate) {
	   if (running())
	   	 return true;
	   if (value) { setValue(value) }
	   if (growthRate) { setGrowthRate(growthRate) }
	   _timeoutId = window.setTimeout(_timer, _delay);
	   return false;
	 }
	 
	 function stop() {
	   if (running()) {
		 window.clearTimeout(_timeoutId);
		 _timeoutId = 0;
		 return false;
	   }
	   return true;
	 }
	 
   function _initializeCounter(parent, id, value, growthRate) {
	 var d1 = null;
	 var d2 = null;

	 setId(id);

	 if (parent != null) {
		if (typeof parent == "string")
			d1 = document.getElementById(parent);
		if (!d1) {
			alert("Counter:\n  Parent specified but can't find element.");
			return false;
		}
	 }
	 else 
	   d1 = document.getElementsByTagName("body")[0];

	 _f = document.createElement("span");
	 if (typeof parent != "undefined") {
	   d1.appendChild(_f);
	 }
	 _f.className = "jpc";
	 _f.id = id;
	 _f.innerHTML = _loadingString;

	 setDelay(-1); // init rand delay

     if (value && growthRate) {
	   start(value, growthRate);
	 }

	 //Add to counter list.  Note: must use "me", not "this".
	 Counters[id] = me;
   }

}


Counter.setup = function (params) {
	function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };

	param_default("id",                 null); // required
	param_default("parent",             null);
	param_default("growthrate",          0);
	param_default("value",              0); 
	param_default("delay",              -1); 
	param_default("decimalPlaces",      2);
	param_default("decimalSymbol",      '.');
	param_default("separatorSymbol",    ',');
	param_default("currency",           'DOLLAR');
	param_default("currencyPosition",   'L');
	param_default("autostart",          false);
	param_default("loadingString",      "Updating...");

	params.currency.toUpperCase();
	if (params.currency != 'DOLLAR' && params.currency != 'EURO' && params.currency != 'POUND' && params.currency != 'YEN') {
		  params.currency = 'DOLLAR';
	}

	params.currencyPosition.toUpperCase();
	params.currencyPosition = params.currencyPosition == 'L' ? 'L' : 'R';


	var ctr = new Counter(params.parent, params.id);
	ctr.setCurrencyPosition(params.currencyPosition);
	ctr.setCurrency(params.currency);
	ctr.setDecimalPlaces(params.decimalPlaces);
	ctr.setDecimalSymbol(params.decimalSymbol);
	ctr.setSeparatorSymbol(params.separatorSymbol);
	ctr.setValue(params.value);
	ctr.setDelay(params.delay);
	ctr.setGrowthRate(params.growthRate);
	ctr.setLoadingString(params.loadingString);

	if (params.autostart) {
	  ctr.start();
	}
	return ctr;

}



