// CONSTANTS

var ACCENTS_TRANSLATE_MAP = { 
				"\u0386" : "\u0391", // Á
				"\u03ac" : "\u03b1", // á
				"\u0388" : "\u0395", // Å
				"\u03ad" : "\u03b5", // å
				"\u0389" : "\u0397", // Ç
				"\u03ae" : "\u03b7", // ç
				"\u038a" : "\u0399", "\u03aa" : "\u0399", // É
				"\u03af" : "\u03b9", "\u03ca" : "\u03b9", "\u0390" : "\u03b9", // é
				"\u038c" : "\u039f", // Ï
				"\u03cc" : "\u03bf", // ï
				"\u038e" : "\u03a5", "\u03ab" : "\u03a5", // Õ
				"\u03cd" : "\u03c5", "\u03cb" : "\u03c5", "\u03b0" : "\u03c5", // õ
				"\u038f" : "\u03a9", // Ù
				"\u03ce" : "\u03c9" // ù
			  };

var EURO = '\u20ac'; // euro sign
var NBSP = '\u00a0'; // nbsp

var MINUS_SIGN = '-';
var PERCENT_SIGN = '%';
var CURRENCY_SYMBOL = EURO;
var ISODATE_FORMAT = 'yy-mm-dd';

// MONTH_NAMES, SHORTMONTH_NAMES, DAY_NAMES, SHORTDAY_NAMES defined in [locale]/constants
var MONTHS = MONTH_NAMES.split(',');
var SHORT_MONTHS = SHORTMONTH_NAMES.split(',');
var DAYS = DAY_NAMES.split(',');
var SHORT_DAYS = SHORTDAY_NAMES.split(',');

function startsWith(str1, str2) {
	if(str1 && str2 && str2.length > 0 && str2.length <= str1.length && str1.substr(0, str2.length) == str2)
		return true;
	return false;
}

function endsWith(str1, str2) {
	if(str1 && str2 && str2.length > 0 && str2.length <= str1.length && str1.substr(str1.length - str2.length) == str2)
		return true;
	return false;
}

function substringBefore(str, sep) {
	if(str.indexOf(sep) != -1)
		return str.substr(0, str.indexOf(sep));
	else
		'';
}

function substringAfter(str, sep) {
	if(str.indexOf(sep) != -1)
		return str.substr(str.indexOf(sep) = 1);
	else
		'';
}

function trim(str) {
	var s, e;
	for(s = 0; s < str.length && str.charAt(s) == ' '; s++);
	for(e = str.length - 1; e > s && str.charAt(e) == ' '; e--);
	return (s == e) ? '' : str.substr(s, e - s);
}

function leftPad(str, length, padChar) {
	while(str.length < length)
		str = padChar + str;
	return str;
}

function rightPad(str, length, padChar) {
	while(str.length < length)
		str = str + padChar;
	return str;
}

function strip(input, chars) {  // strip all characters in 'chars' from input
	var output = "";  // initialise output string
	for (var i=0; i < input.length; i++)
		if (chars.indexOf(input.charAt(i)) == -1)
			output += input.charAt(i);
	return output;
}

function separate(input, separator) {  // format input using 'separator' to mark 000's
	input = "" + input;
	var output = "";  // initialise output string
	for (var i=0; i < input.length; i++) {
		if (i != 0 && (input.length - i) % 3 == 0) output += separator;
			output += input.charAt(i);
	}
	return output;
}

function removeAccent(str) {
	var newstr = '';
	for(var i = 0; i < str.length; i++)
		if(ACCENTS_TRANSLATE_MAP[str.charAt(i)])
			newstr += ACCENTS_TRANSLATE_MAP[str.charAt(i)];
		else
			newstr += str.charAt(i);
	return newstr;
}

function formatNumber(number, format) {  // use: formatNumber(number, "format")

	number = changeDecimalSeparator(number, DECIMAL_SEPARATOR, '.');

	if (number - 0 != number) return null;  // if number is NaN return null

	var useSeparator = format.indexOf(THOUSANDS_SEPARATOR) != -1;  // use separators in number
	var usePercent = format.indexOf(PERCENT_SIGN) != -1;  // convert output to percentage
	var useCurrency = format.indexOf(CURRENCY_SYMBOL) != -1;  // use currency format
	var isNegative = (number < 0);
	
	number = Math.abs(number);
	if (usePercent) number *= 100;
	format = strip(format, THOUSANDS_SEPARATOR + PERCENT_SIGN + CURRENCY_SYMBOL);  // remove key characters
	number = "" + number;  // convert number input to string

	// split input value into LHS and RHS using DECIMAL_SEPARATOR as divider
	var dec = number.indexOf('.') != -1;
	var nleftEnd = (dec) ? number.substring(0, number.indexOf(".")) : number;
	var nrightEnd = (dec) ? number.substring(number.indexOf(".") + 1) : "";

	// split format string into LHS and RHS using DECIMAL_SEPARATOR as divider
	dec = format.indexOf(DECIMAL_SEPARATOR) != -1;
	var sleftEnd = (dec) ? format.substring(0, format.indexOf(DECIMAL_SEPARATOR)) : format;
	var srightEnd = (dec) ? format.substring(format.indexOf(DECIMAL_SEPARATOR) + 1) : "";

	// adjust decimal places by cropping or adding zeros to LHS of number
	if (srightEnd.length < nrightEnd.length) {
		var nextChar = nrightEnd.charAt(srightEnd.length) - 0;
		nrightEnd = nrightEnd.substring(0, srightEnd.length);
		if (nextChar >= 5) nrightEnd = "" + ((nrightEnd - 0) + 1);  // round up

		while (srightEnd.length > nrightEnd.length) {
			nrightEnd = "0" + nrightEnd;
		}

		if (srightEnd.length < nrightEnd.length) {
			nrightEnd = nrightEnd.substring(1);
			nleftEnd = (nleftEnd - 0) + 1;
		}
	} else {
		for (var i=nrightEnd.length; srightEnd.length > nrightEnd.length; i++) {
			if (srightEnd.charAt(i) == "0") nrightEnd += "0";  // append zero to RHS of number
			else break;
		}
	}

	// adjust leading zeros
	sleftEnd = strip(sleftEnd, "#");  // remove hashes from LHS of format
	while (sleftEnd.length > nleftEnd.length) {
		nleftEnd = "0" + nleftEnd;  // prepend zero to LHS of number
	}

	if (useSeparator) nleftEnd = separate(nleftEnd, THOUSANDS_SEPARATOR);  // add separator
	var output = nleftEnd + ((nrightEnd != "") ? DECIMAL_SEPARATOR + nrightEnd : "");  // combine parts
	output = ((useCurrency) ? CURRENCY_SYMBOL : "") + output + ((usePercent) ? PERCENT_SIGN : "");
	if (isNegative) {
		// patch suggested by Tom Denn 25/4/2001
		output = (useCurrency) ? "(" + output + ")" : "-" + output;
	}
	return output;
}

function unFormatNumber(number) {
	number = "" + number;  // convert number input to string
	number = strip(number, THOUSANDS_SEPARATOR + PERCENT_SIGN + CURRENCY_SYMBOL);
	return number;
}

function changeDecimalSeparator(number, separator1, separator2) {
	number = "" + number;  // convert number input to string
	if(separator1 != separator2) {
		var dec = number.indexOf(separator1);  // use separators in number
		if(dec != -1) {
			number = number.substring(0, dec) + separator2 +  number.substring(dec + 1);
		}
	}
	return number;
}

function numberValue(number) {
	return changeDecimalSeparator(unFormatNumber(number), DECIMAL_SEPARATOR, '.');
}

//**************************************************************************************
//    Function: isDate
//              
// Description: checks if date passed is valid
//              will accept dates in following format:
//              isDate(dd,mm,ccyy), or
//              isDate(dd,mm) - which defaults to the current year, or
//              isDate(dd) - which defaults to the current month and year.
//              Note, if passed the month must be between 1 and 12, and the
//              year in ccyy format.
//  Parameters: day - required - number 1-31 that represents the day of month
//              month - optional - number 1-12 that represents the month of year
//              year - optional - 
//**************************************************************************************

function isDate (day, month, year) {

    var today = new Date();
    year = ((!year) ? today.getFullYear():year);
    month = ((!month) ? today.getMonth():month-1);
    if (!day) return false;
    var test = new Date(year,month,day);
    if ( (year == test.getFullYear()) &&
         (month == test.getMonth()) &&
         (day == test.getDate()) )
        return true;
    else
        return false
}

//**************************************************************************************
// Function   : formatDate
//              
// Description: Formats a date using a format string. 
//              d or dd represents the day of the month (eg 1 or 01)
//              m or mm represents the month as a number (eg 1 or 01)
//              mmm or mmmm represents the month as a string (eg Jan or January)
//              y or yy represents the year (eg 99 or 1999)
//              w or ww represents the day of the week (eg Mon or Monday)
//              example: formatDate(myDate, "mm/dd/yy") might look like 01/01/2000
//  Parameters: strFullDate - required - the date to display (a date object)
//              strFormatString - required - a format string
//              
//**************************************************************************************
function formatDate(strFullDate, strFormatString) {

	var day   = strFullDate.getDate();
	var month = strFullDate.getMonth();
	var year  = strFullDate.getFullYear();
	var wday  = strFullDate.getDay();

	if (strFormatString.indexOf("dd") > -1) {
		strFormatString = strFormatString.replace("dd", (day < 10) ? '0' + day : day);
	}
	else {
		if (strFormatString.indexOf("d") > -1) {
			strFormatString = strFormatString.replace("d", day);
		}
	}

	if (strFormatString.indexOf("mmmm") > -1) {
		strFormatString = strFormatString.replace("mmmm", MPNTHS[month]);
	}
	else {
		if (strFormatString.indexOf("mmm") > -1) {
			strFormatString = strFormatString.replace("mmm", SHORT_MONTHS[month]);
		}
		else {
			month++;
			if (strFormatString.indexOf("mm") > -1) {
				strFormatString = strFormatString.replace("mm", (month < 10) ? '0' + month : month);
			}
			else {
				if (strFormatString.indexOf("m") > -1) {
					strFormatString = strFormatString.replace("m", month);
				}
			}
		}
	}

	if (strFormatString.indexOf("yy") > -1) {
		strFormatString = strFormatString.replace("yy", year);
	}
	else {
		if (strFormatString.indexOf("y") > -1) {
			strFormatString = strFormatString.replace("y", year.toString().substr(2,2));
		}
	}

	if (strFormatString.indexOf("ww") > -1) {
		strFormatString = strFormatString.replace("ww", DAYS[wday]);
	}
	else {
		if (strFormatString.indexOf("w") > -1) {
			strFormatString = strFormatString.replace("w", SHORT_DAYS[wday]);
		}
	}

	return strFormatString;
}

function localeDate(str) {
	var year = str.substr(0, 4);
	var month = str.substr(5, 2);
	var day = str.substr(8, 2);
	return day + '/' + month + '/' + year;
}

function isoDate(str) {
	var parts = str.split('/', 3);
	if(parts.length != 3)
		return '';
	return rightPad(parts[2], 4, '0') + '-' + leftPad(parts[1], 2, '0') + '-' + leftPad(parts[0], 2, '0');
}

function str2Date(str) {
	var dateSeparator;
	if(str.indexOf('/') > 0)
		dateSeparator = '/';
	else if(str.indexOf('-') > 0)
		dateSeparator = '-';
	else if(str.indexOf('.') > 0)
		dateSeparator = '.';
	else
		return null;
	
	var parts = str.split(dateSeparator, 3);
	if(!parts || parts.length != 3)
		return null;
	
	var year, month, day;
	for(var i = 0; i < parts.length; i++) {
		if(!day && parts[i] > 0 && parts[i] <= 31) {
			day = parts[i];
		} else if(!month && parts[i] > 0 && parts[i] <= 12) {
			month = parts[i];
		} else {
			if(parts[i] < 100) {
				var today = new Date();
				var century = today.getFullYear() - (today.getFullYear() % 100);
				if(century + parseInt(parts[i]) <= today.getFullYear())
					year = century + parseInt(parts[i]);
				else
					year = (century - 100) + parseInt(parts[i]);
			} else {
				year = parts[i];
			}
		}
	}
	if(!day || !month || !year)
		return null;
	if(!isDate(day, month, year))
		return null;

	return new Date(year, month-1, day);
}


/**********************************************************************
	IN:
		NUM - the number to format
		decimalNum - the number of decimal places to format the number to
		bolLeadingZero - true / false - display a leading zero for
										numbers between -1 and 1
		bolParens - true / false - use parenthesis around negative numbers
		bolCommas - put commas as number separators.
 
	RETVAL:
		The formatted number!
 **********************************************************************/

function vbFormatNumber(num, decimalNum, bolLeadingZero, bolParens, bolCommas)
{ 
	if (isNaN(parseInt(num))) return "NaN";

	var tmpNum = num;
	var iSign = num < 0 ? -1 : 1;		// Get sign of number
	
	// Adjust number so only the specified number of numbers after
	// the decimal point are shown.
	tmpNum *= Math.pow(10,decimalNum);
	tmpNum = Math.round(Math.abs(tmpNum))
	tmpNum /= Math.pow(10,decimalNum);
	tmpNum *= iSign;					// Readjust for sign
	
	// Create a string object to do our formatting on
	var tmpNumStr = new String(tmpNum);

	// See if we need to strip out the leading zero or not.
	if (!bolLeadingZero && num < 1 && num > -1 && num != 0)
		if (num > 0)
			tmpNumStr = tmpNumStr.substring(1,tmpNumStr.length);
		else
			tmpNumStr = "-" + tmpNumStr.substring(2,tmpNumStr.length);
		
	// See if we need to put in the commas
	if (bolCommas && (num >= 1000 || num <= -1000)) {
		var iStart = tmpNumStr.indexOf(".");
		if (iStart < 0)
			iStart = tmpNumStr.length;

		iStart -= 3;
		while (iStart >= 1) {
			tmpNumStr = tmpNumStr.substring(0,iStart) + THOUSANDS_SEPARATOR + tmpNumStr.substring(iStart,tmpNumStr.length)
			iStart -= 3;
		}		
	}

	// See if we need to use parenthesis
	if (bolParens && num < 0)
		tmpNumStr = "(" + tmpNumStr.substring(1,tmpNumStr.length) + ")";

	return tmpNumStr;		// Return our formatted string!
}


