// http://stackoverflow.com/questions/149055/how-can-i-format-numbers-as-money-in-javascript
Number.prototype.formatMoney = function(c, d, t) {
	var n = this,
		c = isNaN(c = Math.abs(c)) ? 2 : c,
		d = d == undefined ? "," : d,
		t = t == undefined ? "." : t,
		s = n < 0 ? "-" : "",
		i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
		j = (j = i.length) > 3 ? j % 3 : 0;

	return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t)
			+ (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
};

/**
 * Removes all options from a list, and optionally adds a default set of options to the list. It
 * tries to set the selected option to the previous value or to a certain value if specified.
 *
 * The function returns the value of the list option which was selected before.
 *
 * selectId:	The id of the HTML <select ...> element to manipulate.
 * defaultOptions:	The array of objects used to add the default select options. Each object in
 *		the array has to contain a value and a text property to fill in the HTML <option>
 *		element's value and text, respectively.
 * 		e.g.
 * 		var optionArray = [ { value:'-1', text:'Please choose' } ];
 * defaultValue:	The default value to set after resetting the select list.
 */
function resetList(selectId, defaultOptions, defaultValue) {
	var selectedValue = dwr.util.getValue(selectId);
	dwr.util.removeAllOptions(selectId);
	
	if (defaultOptions && defaultOptions != null) {
		dwr.util.addOptions(selectId, defaultOptions, "value", "text");
		
		if (defaultValue) {
			dwr.util.setValue(selectId, defaultValue);
		} else {
			dwr.util.setValue(selectId, selectedValue);
		}
	}
	
	return selectedValue;
}

function enable() {
	for (var i = 0; i < arguments.length; i++) {
		var e = document.getElementById(arguments[i]);
		if (e != null) {
			e.removeAttribute('disabled');
		} else {
			// radio buttons
			e = document.getElementsByName(arguments[i]);
			for (var j = 0; j < e.length; j++) {
				e[j].removeAttribute('disabled');
			}
		}
	}
}

function disable() {
	for (var i = 0; i < arguments.length; i++) {
		var e = document.getElementById(arguments[i]);
		if (e != null) {
			e.setAttribute('disabled', 'disabled');
		} else {
			// radio buttons
			e = document.getElementsByName(arguments[i]);
			for (var j = 0; j < e.length; j++) {
				e[j].setAttribute('disabled', 'disabled');
			}
		}
	}
}

function show() {
	for (var i = 0; i < arguments.length; i++) {
		var element = document.getElementById(arguments[i]);
		if (element != null) {
			element.style.display = '';
		}
	}
}

function hide() {
	for (var i = 0; i < arguments.length; i++) {
		var element = document.getElementById(arguments[i]);
		if (element != null) {
			element.style.display = 'none';
		}
	}
}

/**
 * Returns the caret position in a text input field.
 */
function getCaretPos(textInput) {
	if (document.selection) {
		// IE
		// To get cursor position, get empty selection range
		var range = document.selection.createRange();
		
		// Move selection start to 0 position
		range.moveStart('character', -textInput.value.length);
		
		// The caret position is selection length
		return range.text.length;
	} else if (textInput.selectionStart || textInput.selectionStart == '0') {
		// Gecko
		return textInput.selectionStart;
	} else {
		// we don't know
		return -1;
	}
}

/**
 * Allows entering only a date in a text input. The date format is yyyy.MM.dd.
 *
 * The function has to be added to an input element as the keypress event handler via Javascript.
 * Failing to do so will prevent the event handling mechanism to work. 
 *
 * document.getElementById('xxx').onkeypress = dateMask;
 */
function dateMask(e) {
	// enter in IE
	if (!e && event.keyCode == 13) return true;

	var code = e ? e.charCode : event.keyCode;
	// non-printable character
	if (code == 0) return true;

	var v = this.value;
	if (v.length == 10) return false;

	var c = String.fromCharCode(code);
	// allow 19yy.mm.dd - 20yy.mm.dd only
	switch (getCaretPos(this)) {
		// year
		case 0:
			if (c != '1' && c != '2') return false;
			break;
		case 1:
			if (v.charAt(0) == '1' && c != '9') return false;
			if (v.charAt(0) == '2' && c != '0') return false;
			break;
		case 2:
		case 3:
			if (c < '0' || c > '9') return false;
			break;
		case 4:
			if (c != '.') return false;
			break;
		// month
		case 5:
			if (c != '0' && c != '1') return false;
			break;
		case 6:
			if (v.charAt(5) == '0' && (c < '1' || c > '9')) return false;
			if (v.charAt(5) == '1' && (c < '0' || c > '2')) return false;
			break;
		case 7:
			if (c != '.') return false;
			break;
		// day
		case 8:
			if (c < '0' || c > '3') return false;
			break;
		case 9:
			if (v.charAt(8) == '3' && (c < '0' || c > '1')) return false;
			if (c < '0' || c > '9') return false;
			break;
		default:
			return false;
			break;
	}
	
	return true;
}

function canonicalString(s) {
	var s = s.toLowerCase();

	s = s.replace(/[âãäåàáāăą]/g, 'a');
	s = s.replace(/[èéêëēĕėęě]/g, 'e');
	s = s.replace(/[çćĉċč]/g, 'c');
	s = s.replace(/[ðďđ]/g, 'd');
	s = s.replace(/[ĝğġģ]/g, 'g');
	s = s.replace(/[ĥħ]/g, 'h');
	s = s.replace(/[ìíîïĩīĭįı]/g, 'i');
	s = s.replace(/[ĵ]/g, 'j');
	s = s.replace(/[ķ]/g, 'k');
	s = s.replace(/[ñńņňŉ]/g, 'n');
	s = s.replace(/[òóôõöōŏő]/g, 'o');
	s = s.replace(/[ŕŗř]/g, 'r');
	s = s.replace(/[śŝşš]/g, 's');
	s = s.replace(/[ţť]/g, 't');
	s = s.replace(/[ùúûüũūŭůűų]/g, 'u');
	s = s.replace(/[ŵ]/g, 'w');
	s = s.replace(/[ýÿŷ]/g, 'y');
	s = s.replace(/[źżž]/g, 'z');
	
    s = s.replace(/[!\"\'#$%&()*+,.\/:;<=>?@^_`|~]/g, '');
    s = s.replace(/[ß]/g, 'ss');
    s = s.replace(/[ŋ]/g, 'ng');
    s = s.replace(/\s+/g, '-');

	return s;
}

function uniqueArray(ar) {
	if (ar.length && typeof ar!=='string') {
		var sorter = {};
		for (var i=0,j=ar.length; i<j; i++){
			sorter[ar[i] + typeof ar[i]] = ar[i];
		}
		ar = [];
		for (var i in sorter){
			ar.push(sorter[i]);
		}
	}
	return ar;
}

// max days for months, with 1-based index
var maxDays = [ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

function setDayOptions(yearId, monthId, dayId) {
	var year = dwr.util.getValue(yearId);
	var month = dwr.util.getValue(monthId);
	
	// calculate last day
	var lastDay = maxDays[month];
	if (month == 2 && isLeapYear(year)) {
		lastDay += 1;
	}
	
	var days = new Array();
	for (var i = 1; i <= lastDay; i++) {
		days[i - 1] = i;
	}
	
	// update day options
	var value = dwr.util.getValue(dayId);
	if (value > lastDay) value = lastDay;
	dwr.util.removeAllOptions(dayId);
	dwr.util.addOptions(dayId, days);
	dwr.util.setValue(dayId, value);
}
