/*
 *	COPYRIGHT (c) 2008 LAGAN TECHNOLOGIES LIMITED. ALL RIGHTS RESERVED.
 *
 *	This material is a product of Lagan Technologies Limited. This material contains trade
 *	secrets and proprietary information and may not be used, modified, copied, licensed to
 *	a third party, disclosed, or distributed except pursuant to a licence from Lagan
 *	Technologies Limited. Use of copyright notice does not imply publication or disclosure.
 *
 *	MODULE:	$HeadURL: http://prod-build-1/svn/lagancentre/branches/v7-0/deploy/web/javascript/LaganCurrency.js $
 *	ID:		$Id: LaganCurrency.js 21260 2008-09-02 15:28:52Z michael_benson $
 */

/*
 * Returns a fully-formatted copy of rawValue using the given currency attributes.
 * 
 * rawValue must not contain a currency symbol or grouping separators.
 * It must contain the decimal separator and hundredths digits (if applicable for 
 * the currency), and a leading minus if the value is negative.
 * 
 * Example calls:
 * 		formatRawCurrencyValue('1234.56', '£', '', '-£', '', ',', '.', true)
 * 		formatRawCurrencyValue('-1234.56', '$', '', '($', ')', ',', '.', true)
 */
function formatRawCurrencyValue(rawValue,
								positivePrefix, positiveSuffix,
								negativePrefix, negativeSuffix,
								groupingSeparator, decimalSeparator,
								useDecimalSeparator)
{
	var value = rawValue;

	// If necessary, substitute a decimal point for the given decimal separator.
	if (useDecimalSeparator && (decimalSeparator != "."))
	{
		var decimalSeparatorIndex = value.indexOf(decimalSeparator);
		
		value = value.substring(0, decimalSeparatorIndex) + "." + 
				value.substring(decimalSeparatorIndex + 1, value.length);
	}
	
	// Negative value processing. 
	// Note that an input value of -0 will be formatted as a positive number.
	var prefix = positivePrefix;
	var suffix = positiveSuffix;
	
	if (value < 0)
	{
		value = Math.abs(value);
		prefix = negativePrefix;
		suffix = negativeSuffix;
	}
	else if (value == 0 && startsWith(value, '-'))
	{
		value = value.substring(1, value.length);
	}

	// Separate value into integer and decimal parts.
	var integerPart = value;
	var decimalPart = '';
	
	if (useDecimalSeparator)
	{
		var hundredths = Math.floor((value * 100 + 0.5) % 100);
		integerPart = Math.floor((value * 100 + 0.5) / 100).toString();
	
		if (hundredths < 10)
		{
			hundredths = '0' + hundredths;
		}
		
		decimalPart = decimalSeparator + hundredths;
	}
 	
	// This toString conversion is required so that integerPart.length is calculated as the
	// length of the string rather than the number of digits in the number.
	integerPart = integerPart.toString();
	
	// Add the grouping separator.
	for (i = 0; i < Math.floor((integerPart.length - (1 + i)) / 3); i++)
	{
		integerPart = integerPart.substring(0, integerPart.length - (4 * i + 3))
													+ groupingSeparator
													+ integerPart.substring(integerPart.length - (4 * i + 3));
	}
	
	return prefix + integerPart + decimalPart + suffix;
}

/*
 * Parses inputValue using the given currency attributes and returns a fully-formatted value.
 * 
 * inputValue can be completely unformatted, completely formatted, or anywhere in between.
 * 
 * Example calls:
 * 		parseCurrencyValue('123456', '£', '', '-£', '', ',', '.', true)
 * 		parseCurrencyValue('-1,234.56', '$', '', '($', ')', ',', '.', true)
 */
function parseCurrencyValue(inputValue, 
							positivePrefix, positiveSuffix,
							negativePrefix, negativeSuffix,
							groupingSeparator, decimalSeparator,
							useDecimalSeparator)
{
	// Remove white space and grouping separator.
	var value = inputValue.replace(new RegExp('\\s|\\' + groupingSeparator, 'g'), '');

	// Deal with special case: empty value.
	if (value.length == 0)
	{
		value = '0';
		
		if (useDecimalSeparator)
		{
			value = '0' + decimalSeparator + '00';
		}
	} 
    else
	{
		// Remove spaces from prefix and suffix strings.
		var spaceRegExp = /\s/g;
		var trimmedPositivePrefix = positivePrefix.replace(spaceRegExp, '');
		var trimmedPositiveSuffix = positiveSuffix.replace(spaceRegExp, '');
		var trimmedNegativePrefix = negativePrefix.replace(spaceRegExp, '');
		var trimmedNegativeSuffix = negativeSuffix.replace(spaceRegExp, '');
		
		var isNegative = false;
		var checkPositive = true;

		// Negative check: we have to check for the official prefix+suffix OR a leading minus. Either is valid.
		if (startsWith(value, trimmedNegativePrefix) && endsWith(value, trimmedNegativeSuffix))
		{
			isNegative = true;
			checkPositive = false;
		    value = value.substring(trimmedNegativePrefix.length, value.length - trimmedNegativeSuffix.length);
		}
		else if (startsWith(value, '-'))
		{
			isNegative = true;
			value = value.substring(1, value.length);
		}
		
		// Don't check for positive formatting if we already found the official negative formatting.
		if (checkPositive)
		{
			if ((trimmedPositivePrefix.length > 0) && startsWith(value, trimmedPositivePrefix))
			{
				value = value.substring(trimmedPositivePrefix.length, value.length);
			}	
			
			if ((trimmedPositiveSuffix.length > 0) && endsWith(value, trimmedPositiveSuffix))
			{
				value = value.substring(0, value.length - trimmedPositiveSuffix.length);
			}
		}
		
		// Check that we have a valid number.
		// Valid means 0 or more digits, an optional decimal separator, then 0 or more digits.
		var numberRegExp = new RegExp('^[0-9]*\\' + decimalSeparator + '?[0-9]*$');

		if (numberRegExp.test(value) == false)
		{
			alert("Currency value " + value + " is not valid");
			return inputValue;
		}
		
		var decimalSeparatorIndex = value.indexOf(decimalSeparator);
		
		if (decimalSeparatorIndex == -1)
		{
			if (useDecimalSeparator)
			{
				value = value + decimalSeparator + '00';
			}
		}
		else // Decimal separator was entered
		{
			if (useDecimalSeparator)
			{
				var charsAfterDecimalSeparator = value.length - decimalSeparatorIndex - 1;
	
				if (charsAfterDecimalSeparator == 0)
				{
					value = value + '00';
				}
				else if (charsAfterDecimalSeparator == 1)
				{
					value = value + '0';
				}
				else if (charsAfterDecimalSeparator > 2)
				{
					// Drop the excess digits.
					value = value.substring(0, decimalSeparatorIndex + 3);
				}
			}
			else
			{
				// Drop the separator and any following digits.
				value = value.substring(0, decimalSeparatorIndex);
			}
		}
		
		// Strip leading zeros.
		value = value.replace(new RegExp('^0+([1-9]*[0-9]\\' + decimalSeparator + '?)'), '$1');
			
		if (isNegative)
		{
			value = "-" + value;
		}
	}

	return formatRawCurrencyValue(value, positivePrefix, positiveSuffix, negativePrefix, negativeSuffix,
								  groupingSeparator, decimalSeparator, useDecimalSeparator);
}

function startsWith(aString, aPrefix)
{
	return aString.substr(0, aPrefix.length) == aPrefix;
}

function endsWith(aString, aSuffix)
{
	return aString.substring(aString.length - aSuffix.length, aString.length) == aSuffix;
}