/*
COPYRIGHT
dieser Code unterliegt dem Copyright der Kap Dion - Gesellschaft für Bankensoftware GmbH, Wien.
Sie dürfen ihn unter Beibehaltung dieses Copyright-Hinweises frei verwenden, anpassen und weiterentwickeln,
wenn Sie an geeigneter Stelle Ihrer Homepage auf unsere Webseite www.kapdion.com verlinken.



NUMERIC FORMAT PACKAGE
handles numeric formats in correspondence with the formats used on the server

function formatLocalization(decimalSeparator,groupingSeparator,subpatternBoundary,percentageSymbol,
				permilleSymbol,minusSign,digitAbsent,digit,currency) 
			
	This function is for creating javascipt formatLocalization objects, which hold all the
	information, which symbols are locally used for displaying numbers.
	To use the other functions of this package you will need to invoke at least one formatLocalization.
	
function numericFormat(decimalFormatPattern,local) 
	The numericFormat function is used to generate numericFormat Objects in Javascript.
	A numericFormat object is closely related to the java class DecimalFormat in the text-package.
	Like the java class it will interpret a decimalFormatPattern like "\u00a4 #.###.##0,00;(\u00a4 #.###.##0,00)",
	but with the following restrictions:
		- scientific formats are not supported
		- ' is not supported to mask 0 or # in prefix or suffix
		- isDecimalSeperator always shown
		- there are no set and get methods, variables of the object are referred directly by "." symbol
	Instances of the numericFormat are used to translate javascript numeric variables into
	locally formatted string expressions.

function toNumericFormat(value,numericFormat,local)
	this funcion translates the numeric javascript variable value into a string, formatted on basis
	of the numericFormat and the localization local.

function parseToJavascriptVariable(inputString,numericFormat,local)
	transforms a string type input to a javascript variable of double or integer type
	using the multiplier of the numericFormat object: % = 100, permille = 1000 other 1	
	
*/

function formatLocalization(decimalSeparator,groupingSeparator,subpatternBoundary,percentageSymbol,permilleSymbol,minusSign,digitAbsent,digit,currency) {
	this.decimalSeparator = decimalSeparator;
	this.groupingSeparator = groupingSeparator;
	this.subpatternBoundary = subpatternBoundary;
	this.percentageSymbol = percentageSymbol;
	this.permilleSymbol = permilleSymbol;
	this.minusSign = minusSign;
	this.digitAbsent = digitAbsent;
	this.digit = digit;
	this.currency = currency;
}

function numericFormat(decimalFormatPattern,local,multiplier) {
	// numeric Format has some similarities to the java class DecimalFormat but with exceptions
	// in example scientific formats are not supported.
	// numericFormat analyzes a given pattern at construction and derives some values, which describe the format.
	// Later these values can be accessed and used to format or interpret (parse) numbers
	
	// analyze if a negative Pattern is given
	//alert(decimalFormatPattern);
	var splitPattern = decimalFormatPattern.split(local.subpatternBoundary);
	var positivePattern = "";
	var negativePattern = "";
	if (splitPattern.length > 1) {
		negativePattern = splitPattern[1];
		positivePattern = splitPattern[0];
	} else {
		// no negative pattern
		positivePattern = decimalFormatPattern;
	}
	
	/*** search for number in positive or negative pattern  ***/
	
	// drill for start of number
	var helpstring = positivePattern;
	var i=0;
	
	while ((i<helpstring.length)&&(!((helpstring.charAt(i)==local.digit)||(helpstring.charAt(i)==local.digitAbsent) || (helpstring.charAt(i)==local.groupingSeparator) || (helpstring.charAt(i)==local.decimalSeparator)))) {
		i++;
	}
	var startPosNumber = i;
	// drill until end of number
	while ((i<helpstring.length)&&((helpstring.charAt(i)==local.digit)||(helpstring.charAt(i)==local.digitAbsent) || (helpstring.charAt(i)==local.groupingSeparator) || (helpstring.charAt(i)==local.decimalSeparator))) {
		i++;
	}
	this.positivePrefix = helpstring.slice(0,startPosNumber);
	var number = helpstring.slice(startPosNumber,i);
	this.positiveSuffix = helpstring.slice(i); 

	if (negativePattern.length>0) {
		// drill for start of number
		helpstring = negativePattern;
		i=0;
		while ((i<helpstring.length)&&(!((helpstring.charAt(i)==local.digit)||(helpstring.charAt(i)==local.digitAbsent) || (helpstring.charAt(i)==local.groupingSeparator) || (helpstring.charAt(i)==local.decimalSeparator)))) {
			i++;
		}
		startPosNumber = i;
		// drill until end of number
		while ((i<helpstring.length)&&((helpstring.charAt(i)==local.digit)||(helpstring.charAt(i)==local.digitAbsent) || (helpstring.charAt(i)==local.groupingSeparator) || (helpstring.charAt(i)==local.decimalSeparator))) {
			i++;
		}
		this.negativePrefix = helpstring.slice(0,startPosNumber);
		this.negativeSuffix = helpstring.slice(i); 	
	} else {
		// if negative case is not given explicitly, use local minus sign for negative values
		this.negativePrefix = local.minusSign;
		this.negativeSuffix = "";
	}		
	//alert("positivePrefix="+this.positivePrefix+", number ="+number+", positiveSuffix="+this.positiveSuffix+", negativePrefix="+this.negativePrefix+", negativeSuffix="+this.negativeSuffix);

	// look for percentage or permille symbols
	this.multiplier = multiplier;
	//alert("positivePattern.indexOf("+local.percentageSymbol+")="+positivePattern.indexOf(local.percentageSymbol));
	/*if (positivePattern.indexOf(local.percentageSymbol) != -1) {
		this.multiplier = 100;
	} else {
		if ((type.toLowerCase()=="permille")||(positivePattern.indexOf(local.permilleSymbol) != -1)) {	
		 	this.multiplier = 1000;
		}
	}*/
	//alert(this.multiplier);	

	/*** integer and fraction part of number ***/
	splitPattern = number.split(local.decimalSeparator);
	var integerPart = "";
	var fractionPart = "";
	if (splitPattern.length > 1) {
		fractionPart = splitPattern[1];
		integerPart = splitPattern[0];
	} else {
		// no negative pattern
		integerPart = number;
	}
	//alert("integerPart="+integerPart+" fractionPart="+fractionPart);

	/*** calculate formatting relations ***/
	
	// analyze integer part for grouping size, min and max number of digits:
	// grouping size: distance of last groupingSeparator to decimalSeperator
	
	i=0;
	var last=0 ,groupingSymNum = 0;
	this.groupingSize=0;
	this.minimumIntegerDigits=0;
	this.maximumIntegerDigits=0;
	while (i<integerPart.length) {
		if (integerPart.charAt(i)==local.groupingSeparator) { 
			last=i; 
			groupingSymNum++; 
		}
		if (integerPart.charAt(i)==local.digit) { 
			this.minimumIntegerDigits++;
		}
		if ((integerPart.charAt(i)==local.digit)||(integerPart.charAt(i)==local.digitAbsent)) { 
			this.maximumIntegerDigits++;
		}
		i++;
	}
	if (groupingSymNum>0) { 
		this.groupingSize = integerPart.length - 1 - last;
	}
	//alert("groupingSize="+this.groupingSize+", min int digit="+this.minimumIntegerDigits+", max int digits="+ this.maximumIntegerDigits );
	
	// analyze fraction part for min max number of digits
	i=0;
	this.minimumFractionDigits= 0;
    	this.maximumFractionDigits = 0;
    	while (i<fractionPart.length) {
    		if (fractionPart.charAt(i)==local.digit) { 
			this.minimumFractionDigits++;
		}
		if ((fractionPart.charAt(i)==local.digit)||(fractionPart.charAt(i)==local.digitAbsent)) { 
			this.maximumFractionDigits++;
		}
		i++;
	}	
    //alert("min frac digit="+this.minimumFractionDigits+", max frac digits="+ this.maximumFractionDigits );
	
  }

function toNumericFormat(value,numericFormat,local) {
  
	// function converts javascript variable of type integer or double 
	// into a string which complies with java format settings.
  	//alert("value="+value+", numericFormat="+numericFormat+", local="+local);
	value = value * numericFormat.multiplier;
	var inputString = value.toString();
	var dividedByColon = inputString.split(".");
	var fractionPart = "";
		
	if (dividedByColon.length > 1) {
		fractionPart = dividedByColon[1];
	}
	var integerPart = dividedByColon[0];
	
	// format fraction
	//alert("fractionPart.length="+fractionPart.length+", minimumFractionDigits="+numericFormat.minimumFractionDigits+", naximumFractionDigits="+numericFormat.maximumFractionDigits);
	if (fractionPart.length > numericFormat.maximumFractionDigits) {
		// too many fraction digits
		if (numericFormat.maximumFractionDigits > 0 ) {
			// rounding in fraction part
			fractionPart= fractionPart.slice(0,numericFormat.maximumFractionDigits)+"."+fractionPart.slice(numericFormat.maximumFractionDigits,fractionPart.length);
			fractionPart = Math.round(fractionPart).toString();
			//alert("fractionPart ="+fractionPart);
		} else {
			// rounding affects integer part
			fractionPart = "";
			integerPart = Math.round(value).toString();
		}
		
	} else {
		while (fractionPart.length < numericFormat.minimumFractionDigits) {
			//alert("fractionPart.length="+fractionPart.length+" numericFormat.minimumFractionDigits="+numericFormat.minimumFractionDigits);
			fractionPart = fractionPart.concat("0");
		}
	}
	//alert("1. while passiert");
	// format integer part of number
	var isNegative = false;
	if (integerPart.charAt(0) == "-") { 
		isNegative = true;
		integerPart = integerPart.slice(1);
	}
	var separatedInteger = "";
	
	// minimum digits displayed
	while (integerPart.length < numericFormat.minimumIntegerDigits) {
		//alert("integerPart.length="+integerPart.length+", numericFormat.minimumIntegerDigits="+numericFormat.minimumIntegerDigits);
		integerPart = "0" + integerPart;
	} 
	
	// grouping 
	
	while ((integerPart.length > numericFormat.groupingSize)&&(numericFormat.groupingSize>0)) {
		//alert("integerPart.length="+integerPart.length+", numericFormat.groupingSize="+numericFormat.groupingSize+", separatedInteger ="+separatedInteger);
		separatedInteger =  integerPart.slice((integerPart.length - numericFormat.groupingSize))  + separatedInteger;
		integerPart = integerPart.slice(0,(integerPart.length - numericFormat.groupingSize));
		if (integerPart.length > 0 ) { separatedInteger = local.groupingSeparator + separatedInteger; }
	}
	integerPart = integerPart + separatedInteger;
	
	// replace unicode symbol for currency-symbol /u00a4 with local currency-string
	var negativePrefix = numericFormat.negativePrefix.replace(/\u00a4/g,local.currency);
	var negativeSuffix = numericFormat.negativeSuffix.replace(/\u00a4/g,local.currency);
	var positivePrefix = numericFormat.positivePrefix.replace(/\u00a4/g,local.currency);
	var positiveSuffix = numericFormat.positiveSuffix.replace(/\u00a4/g,local.currency);
	
	// add pre- and suffix to number
	var result = integerPart;
	if ( fractionPart.length > 0 ) { 
		result += local.decimalSeparator + fractionPart;
	}
	
	if (isNegative) { 
		result = negativePrefix + result + negativeSuffix;
	} else {
		result = positivePrefix + result + positiveSuffix;
	}
	return result;
}



function parseToJavascriptVariable(inputString,numericFormat,local) {

	// transforms a string type input to 
	// a javascript variable of double or integer type
	// using the multiplier of the numericFormat object
	
	// find indication for negative value
	var isNegative = false;
	if ( inputString.search(/-/)== -1) { isNegative=false;} else { isNegative=true; }
	//alert("inputString ="+inputString);
	
	inputString = inputString.replace(/\s/g,"");  // delete all white spaces
	//alert("inputString,without white spaces ="+inputString);
	var durchKommaGetrennt = inputString.split(local.decimalSeparator);
	var vorkommastellen = "";
	var nachkommastellen = "";
	//alert("durchKommaGetrennt=("+durchKommaGetrennt+"), length="+durchKommaGetrennt.length);
	if (durchKommaGetrennt.length > 1) {
		// interpretiere rechten Abschnitt als Nachkommazahlen, rest als Vorkommazahlen
		nachkommastellen = durchKommaGetrennt[durchKommaGetrennt.length-1];
		// füge Rest zusammen
		for(var i = 0; i < (durchKommaGetrennt.length-1); i++) {
			vorkommastellen = vorkommastellen.concat(durchKommaGetrennt[i]);
		}
	
	} else {
		// keine Nachkommastellen
		vorkommastellen = inputString;
	}
	// waschen
	vorkommastellen = vorkommastellen.replace(/\D/g,"");  // alles was nicht ziffer ist
	nachkommastellen = nachkommastellen.replace(/\D/g,"");
	//alert("is negativ="+isNegative+" Vorkomma="+vorkommastellen+", Nachkomma="+nachkommastellen);

	// extract number
	var vorkommaValue = parseInt( vorkommastellen,10);
	if((isNaN(vorkommaValue))||(vorkommastellen.length == 0)) {
		vorkommaValue = 0;
	}
	var nachkommaValue = parseInt( nachkommastellen,10);
	if((isNaN(nachkommaValue))||(nachkommastellen.length == 0)) {
	nachkommaValue = 0;
	}
	while (nachkommaValue > 100) {
		nachkommaValue = nachkommaValue / 10;
	} 
	nachkommaValue = Math.round(nachkommaValue);

	var interpretation = vorkommaValue;
	if (nachkommaValue < 10) { 
		interpretation = interpretation + nachkommaValue / 10; 
	} else {
		interpretation = interpretation + nachkommaValue / 100;
	}
	if (isNegative) { interpretation = interpretation * (-1); }
	
	// in case of percentage or permille 
	//alert(interpretation);
	interpretation = interpretation / numericFormat.multiplier;
	//alert("Result="+interpretation);	
	return interpretation;

}	


