package com.brilliance.mda.runtime.mda.util;

import com.brilliance.mda.runtime.mda.impl.Argument;

import java.math.BigDecimal;

import static com.brilliance.mda.runtime.mda.Constants.NO_ERROR;
import static com.brilliance.mda.runtime.mda.Constants.NULLSTR;

/**
 * SYSAMT - Amount in word conversion module
 */
public class Sysamt {

	/**
	 *   source:sysamt.0000.script
	 */
	public static String tableEN(Argument<BigDecimal> wahl) {
		String eng = NULLSTR;
		switch( wahl.value.intValue() ) {
			case 0:
				eng = "zero";
				break;
			case 1:
				eng = "one";
				break;
			case 2:
				eng = "two";
				break;
			case 3:
				eng = "three";
				break;
			case 4:
				eng = "four";
				break;
			case 5:
				eng = "five";
				break;
			case 6:
				eng = "six";
				break;
			case 7:
				eng = "seven";
				break;
			case 8:
				eng = "eight";
				break;
			case 9:
				eng = "nine";
				break;
			case 10:
				eng = "ten";
				break;
			case 11:
				eng = "eleven";
				break;
			case 12:
				eng = "twelve";
				break;
			case 13:
				eng = "thirteen";
				break;
			case 14:
				eng = "fourteen";
				break;
			case 15:
				eng = "fifteen";
				break;
			case 16:
				eng = "sixteen";
				break;
			case 17:
				eng = "seventeen";
				break;
			case 18:
				eng = "eighteen";
				break;
			case 19:
				eng = "nineteen";
				break;
			case 20:
				eng = "twenty";
				break;
			case 21:
				eng = "thirty";
				break;
			case 22:
				eng = "forty";
				break;
			case 23:
				eng = "fifty";
				break;
			case 24:
				eng = "sixty";
				break;
			case 25:
				eng = "seventy";
				break;
			case 26:
				eng = "eighty";
				break;
			case 27:
				eng = "ninety";
				break;
			case 28:
				eng = "hundred";
				break;
			case 29:
				eng = "thousand";
				break;
			case 30:
				eng = "million";
				break;
			case 31:
				eng = "billion";
				break;
			case 32:
				eng = "trillion";
				break;
			case 33:
				eng = "and";
				break;
			case 34:
				eng = "-";
				break;
		}
		return eng;
	}

	/**
	 *   source:sysamt.0001.script
	 */
	public static String tableDE(Argument<BigDecimal> wahl) {
		String germ = NULLSTR;
		switch(wahl.value.intValue()) {
			case 0:
				germ = "null";
				break;
			case 1:
				germ = "ein";
				break;
			case 2:
				germ = "zwei";
				break;
			case 3:
				germ = "drei";
				break;
			case 4:
				germ = "vier";
				break;
			case 5:
				germ = "fünf";
				break;
			case 6:
				germ = "sechs";
				break;
			case 7:
				germ = "sieben";
				break;
			case 8:
				germ = "acht";
				break;
			case 9:
				germ = "neun";
				break;
			case 10:
				germ = "zehn";
				break;
			case 11:
				germ = "elf";
				break;
			case 12:
				germ = "zwölf";
				break;
			case 13:
				germ = "dreizehn";
				break;
			case 14:
				germ = "vierzehn";
				break;
			case 15:
				germ = "fünfzehn";
				break;
			case 16:
				germ = "sechzehn";
				break;
			case 17:
				germ = "siebzehn";
				break;
			case 18:
				germ = "achtzehn";
				break;
			case 19:
				germ = "neunzehn";
				break;
			case 20:
				germ = "zwanzig";
				break;
			case 21:
				germ = "dreißig";
				break;
			case 22:
				germ = "vierzig";
				break;
			case 23:
				germ = "fünfzig";
				break;
			case 24:
				germ = "sechzig";
				break;
			case 25:
				germ = "siebzig";
				break;
			case 26:
				germ = "achtzig";
				break;
			case 27:
				germ = "neunzig";
				break;
			case 28:
				germ = "eins";
				break;
			case 29:
				germ = "und";
				break;
			case 30:
				germ = "hundert";
				break;
			case 31:
				germ = "tausend";
				break;
			case 32:
				germ = "millionen";
				break;
			case 33:
				germ = "milliarden";
				break;
			case 34:
				germ = "billionen";
				break;
			case 35:
				germ = "eine";
				break;
			case 36:
				germ = "million";
				break;
			case 37:
				germ = "milliarde";
				break;
			case 38:
				germ = "billion";
				break;
			case 39:
				germ = "Hundert";
				break;
			case 40:
				germ = "Tausend";
				break;
			case 41:
				germ = "Millionen";
				break;
			case 42:
				germ = "Milliarden";
				break;
			case 43:
				germ = "Billionen";
				break;
			case 44:
				germ = "Million";
				break;
			case 45:
				germ = "Milliarde";
				break;
			case 46:
				germ = "Billion";
				break;
		}
		return germ;
	}

	/**
	 *   source:sysamt.0002.script
	 */
	public static String groupEN(BigDecimal sign,Argument<String> grp) {
		// this function converts the group-number into group-text
		// and returns the group-text
		BigDecimal number = new BigDecimal("1");
		String res = "";
		String space = " ";
		//cut the leading zeros
		while( MdaUtils.compareTo(Strings.mid(grp.value,number.intValue(),1),"0") == 0 ) {
			grp.value = Strings.mid(grp.value,Decimals.add(number,1).intValue(),Strings.len(grp.value) - 1);
		}
		int len = Strings.len(grp.value);
		number = Strings.parseDecimal(grp.value);
		//assign of the numbers between 1 and 9
		BigDecimal valOne = null;
		if( len == 1 && MdaUtils.compareTo(number,0)>0 ) {
			valOne = number;
			Argument<BigDecimal> valOneBox = new Argument<BigDecimal>("",valOne);
			res = res + tableEN( valOneBox );
			valOne = valOneBox.value;
		}
		//assign of the numbers between 10 and 19
		String textTen = NULLSTR;
		BigDecimal valTen = null;
		String wpartTen = NULLSTR;
		String textOne = NULLSTR;
		String wpartOne = NULLSTR;
		if( len == 2 && MdaUtils.compareTo(number,20)<0 ) {
			valOne = number;
			Argument<BigDecimal> valOneBox1 = new Argument<BigDecimal>("",valOne);
			res = res + tableEN( valOneBox1 );
			valOne = valOneBox1.value;
			//assign of the numbers between 20 and 99
		} else {
			if( len == 2 && MdaUtils.compareTo(number,19)>0 ) {
				textTen = Strings.mid(grp.value,1,1);
				valTen = Decimals.add(Strings.parseDecimal(textTen),18);
				Argument<BigDecimal> valTenBox = new Argument<BigDecimal>("",valTen);
				wpartTen = tableEN( valTenBox );

				valTen = valTenBox.value;

				res = res + wpartTen;
				textOne = Strings.mid(grp.value,2,1);
				valOne = Strings.parseDecimal(textOne);
				if( MdaUtils.compareTo(valOne,0) != 0 ) {
					valTen = new BigDecimal("34");
					Argument<BigDecimal> valTenBox1 = new Argument<BigDecimal>("",valTen);
					wpartTen = tableEN( valTenBox1 );

					valTen = valTenBox1.value;

					res = res + wpartTen;
					Argument<BigDecimal> valOneBox2 = new Argument<BigDecimal>("",valOne);
					wpartOne = tableEN( valOneBox2 );

					valOne = valOneBox2.value;

					res = res + wpartOne;
				}
			}
		}
		// assign of the numbers between 100 and 999; then between 19 and 1; then
		// between 20 and 99
		String texthundred;
		BigDecimal valhundred;
		String wparthundred;
		String var;
		if( len == 3 && MdaUtils.compareTo(number,99)>0 ) {
			texthundred = Strings.mid(grp.value,1,1);
			valhundred = Strings.parseDecimal(texthundred);
			Argument<BigDecimal> valhundredBox = new Argument<BigDecimal>("",valhundred);
			wparthundred = tableEN( valhundredBox ) + space;

			valhundred = valhundredBox.value;

			res = res + wparthundred;
			valhundred = new BigDecimal("28");
			Argument<BigDecimal> valhundredBox1 = new Argument<BigDecimal>("",valhundred);
			wparthundred = tableEN( valhundredBox1 );

			valhundred = valhundredBox1.value;

			res = res + wparthundred;
			len = len - 1;
			var = Strings.mid(grp.value,2,2);
			number = Strings.parseDecimal(var);
			if( len == 2 && MdaUtils.compareTo(number,20)<0 && MdaUtils.compareTo(number,0)>0 ) {
				valOne = number;
				Argument<BigDecimal> valOneBox3 = new Argument<BigDecimal>("",valOne);
				res = res + space + tableEN( valOneBox3 );

				valOne = valOneBox3.value;

			} else {
				if( len == 2 && MdaUtils.compareTo(number,19)>0 ) {
					textTen = Strings.mid(grp.value,2,1);
					valTen = Decimals.add(Strings.parseDecimal(textTen),18);
					Argument<BigDecimal> valTenBox2 = new Argument<BigDecimal>("",valTen);
					wpartTen = tableEN( valTenBox2 );

					valTen = valTenBox2.value;

					res = res + space + wpartTen;
					textOne = Strings.mid(grp.value,3,1);
					if( MdaUtils.compareTo(textOne,"0") != 0 )
					{
						valTen = new BigDecimal("34");
						Argument<BigDecimal> valTenBox3 = new Argument<BigDecimal>("",valTen);
						wpartTen = tableEN( valTenBox3 );

						valTen = valTenBox3.value;

						res = res + wpartTen;
					}
					valOne = Strings.parseDecimal(textOne);
					if( MdaUtils.compareTo(valOne,0) != 0 )
					{
						Argument<BigDecimal> valOneBox4 = new Argument<BigDecimal>("",valOne);
						wpartOne = tableEN( valOneBox4 );

						valOne = valOneBox4.value;

						res = res + wpartOne;
					}
				}
			}
		}
		//assign of the groupsign and rule out further groupsigns, if the rest of #the number is zero
		//(-> eg. 1.000.000 one million and not one million thousand ...)
		//and setting a space beetwen the words
		if( MdaUtils.compareTo(sign,1) == 0 && MdaUtils.compareTo(grp.value,"0")>0 ) {
			valOne = new BigDecimal("29");
			Argument<BigDecimal> valOneBox5 = new Argument<BigDecimal>("",valOne);
			res = res + space + tableEN( valOneBox5 ) + space;

			valOne = valOneBox5.value;

		}
		if( MdaUtils.compareTo(sign,2) == 0 && MdaUtils.compareTo(grp.value,"0")>0 ) {
			valOne = new BigDecimal("30");
			Argument<BigDecimal> valOneBox6 = new Argument<BigDecimal>("",valOne);
			res = res + space + tableEN( valOneBox6 ) + space;

			valOne = valOneBox6.value;

		}
		if( MdaUtils.compareTo(sign,3) == 0 && MdaUtils.compareTo(grp.value,"0")>0 ) {
			valOne = new BigDecimal("31");
			Argument<BigDecimal> valOneBox7 = new Argument<BigDecimal>("",valOne);
			res = res + space + tableEN( valOneBox7 ) + space;

			valOne = valOneBox7.value;

		}
		if( MdaUtils.compareTo(sign,4) == 0 && MdaUtils.compareTo(grp.value,"0")>0 ) {
			valOne = new BigDecimal("32");
			Argument<BigDecimal> valOneBox8 = new Argument<BigDecimal>("",valOne);
			res = res + space + tableEN( valOneBox8 ) + space;

			valOne = valOneBox8.value;

		}
		return res;
	}

	/**
	 *   source:sysamt.0003.script
	 */
	public static String groupDE(BigDecimal sign,Argument<String> grp) {
		// this function converts the group-number into group-text
		// and returns the group-text
		BigDecimal number = new BigDecimal("1");
		String res = "";
		String space = " ";
		//cut the leading zeros
		while( MdaUtils.compareTo(Strings.mid(grp.value,number.intValue(),1),"0") == 0 ) {
			grp.value = Strings.mid(grp.value,Decimals.add(number,1).intValue(),Strings.len(grp.value) - 1);
		}
		int len = Strings.len(grp.value);
		number = Strings.parseDecimal(grp.value);
		//assign of the numbers between 1 and 9
		BigDecimal valOne = null;
		if( len == 1 && MdaUtils.compareTo(number,1)>0 ) {
			valOne = number;
			Argument<BigDecimal> valOneBox = new Argument<BigDecimal>("",valOne);
			res = res + tableDE( valOneBox );

			valOne = valOneBox.value;

		}
		//assign of the number "1" to the relevant group
		if( len == 1 && MdaUtils.compareTo(number,1) == 0 && MdaUtils.compareTo(sign,0) == 0 ) {
			valOne = new BigDecimal("28");
			Argument<BigDecimal> valOneBox1 = new Argument<BigDecimal>("",valOne);
			res = res + tableDE( valOneBox1 );

			valOne = valOneBox1.value;

		}
		if( len == 1 && MdaUtils.compareTo(number,1) == 0 && MdaUtils.compareTo(sign,1) == 0 ) {
			valOne = new BigDecimal("1");
			Argument<BigDecimal> valOneBox2 = new Argument<BigDecimal>("",valOne);
			res = res + tableDE( valOneBox2 );

			valOne = valOneBox2.value;

		}
		if( len == 1 && MdaUtils.compareTo(number,1) == 0 && MdaUtils.compareTo(sign,1)>0 ) {
			valOne = new BigDecimal("35");
			Argument<BigDecimal> valOneBox3 = new Argument<BigDecimal>("",valOne);
			res = res + tableDE( valOneBox3 );

			valOne = valOneBox3.value;

		}
		//assign of the numbers between 10 and 19
		String textOne = NULLSTR;
		String wpartOne = NULLSTR;
		String textTen = NULLSTR;
		BigDecimal valTen = null;
		String wpartTen = NULLSTR;
		if( len == 2 && MdaUtils.compareTo(number,20)<0 ) {
			valOne = number;
			Argument<BigDecimal> valOneBox4 = new Argument<BigDecimal>("",valOne);
			res = res + tableDE( valOneBox4 );

			valOne = valOneBox4.value;

			//assign of the numbers between 20 and 99
		} else {
			if( len == 2 && MdaUtils.compareTo(number,19)>0 ) {
				textOne = Strings.mid(grp.value,2,1);
				valOne = Strings.parseDecimal(textOne);
				if( MdaUtils.compareTo(valOne,0) != 0 ) {
					Argument<BigDecimal> valOneBox5 = new Argument<BigDecimal>("",valOne);
					wpartOne = tableDE( valOneBox5 );

					valOne = valOneBox5.value;

					valOne = new BigDecimal("29");
					Argument<BigDecimal> valOneBox6 = new Argument<BigDecimal>("",valOne);
					res = res + wpartOne + tableDE( valOneBox6 );

					valOne = valOneBox6.value;

				}
				textTen = Strings.mid(grp.value,1,1);
				valTen = Decimals.add(Strings.parseDecimal(textTen),18);
				Argument<BigDecimal> valTenBox = new Argument<BigDecimal>("",valTen);
				wpartTen = tableDE( valTenBox );

				valTen = valTenBox.value;

				res = res + wpartTen;
			}
		}
		// assign of the numbers between 100 and 999; then between 19 and 1; then
		// between 20 and 99
		String texthundred = NULLSTR;
		BigDecimal valhundred = null;
		String wparthundred = NULLSTR;
		String var = NULLSTR;
		if( len == 3 && MdaUtils.compareTo(number,99)>0 ) {
			texthundred = Strings.mid(grp.value,1,1);
			valhundred = Strings.parseDecimal(texthundred);
			Argument<BigDecimal> valhundredBox = new Argument<BigDecimal>("",valhundred);
			wparthundred = tableDE( valhundredBox );

			valhundred = valhundredBox.value;

			res = res + wparthundred;
			valhundred = new BigDecimal("30");
			Argument<BigDecimal> valhundredBox1 = new Argument<BigDecimal>("",valhundred);
			wparthundred = tableDE( valhundredBox1 );

			valhundred = valhundredBox1.value;

			res = res + wparthundred;
			len = len - 1;
			var = Strings.mid(grp.value,2,2);
			number = Strings.parseDecimal(var);
			if( len == 2 && MdaUtils.compareTo(number,20)<0 && MdaUtils.compareTo(number,0)>0 ) {
				if( MdaUtils.compareTo(number,1) == 0 ) {
					//assign singular or plural depending on groupsign
					if( MdaUtils.compareTo(sign,1) == 0 ) {
						valOne = new BigDecimal("1");
					} else {
						valOne = new BigDecimal("28");
					}
					Argument<BigDecimal> valOneBox7 = new Argument<BigDecimal>("",valOne);
					res = res + tableDE( valOneBox7 );

					valOne = valOneBox7.value;
				} else {
					Argument<BigDecimal> numberBox = new Argument<BigDecimal>("",number);
					res = res + tableDE( numberBox );

					number = numberBox.value;
				}
			} else {
				if( len == 2 && MdaUtils.compareTo(number,19)>0 ) {
					textOne = Strings.mid(grp.value,3,1);
					valOne = Strings.parseDecimal(textOne);
					if( MdaUtils.compareTo(valOne,0) != 0 ) {
						Argument<BigDecimal> valOneBox8 = new Argument<BigDecimal>("",valOne);
						wpartOne = tableDE( valOneBox8 );

						valOne = valOneBox8.value;

						valOne = new BigDecimal("29");
						Argument<BigDecimal> valOneBox9 = new Argument<BigDecimal>("",valOne);
						res = res + wpartOne + tableDE( valOneBox9 );

						valOne = valOneBox9.value;
					}
					textTen = Strings.mid(grp.value,2,1);
					valTen = Decimals.add(Strings.parseDecimal(textTen),18);
					Argument<BigDecimal> valTenBox1 = new Argument<BigDecimal>("",valTen);
					wpartTen = tableDE( valTenBox1 );

					valTen = valTenBox1.value;

					res = res + wpartTen;
				}
			}
		}
		//assign of the groupsign and rule out further groupsigns, if the rest of the number is zero
		//(-> eg. 1.000.000 one million and not one million thousand ...)
		//and assign of plural or singular to the output depending on  number=1 or greater 1
		//and setting a space beetween number and Billion, Millarde...
		if( MdaUtils.compareTo(sign,1) == 0 && MdaUtils.compareTo(grp.value,"0")>0 ) {
			valOne = new BigDecimal("31");
			Argument<BigDecimal> valOneBox10 = new Argument<BigDecimal>("",valOne);
			res = res + tableDE( valOneBox10 );

			valOne = valOneBox10.value;

		}
		if( MdaUtils.compareTo(sign,2) == 0 && MdaUtils.compareTo(grp.value,"0")>0 ) {
			//assign singular or plural depending on groupsign
			if( MdaUtils.compareTo(number,1) == 0 && MdaUtils.compareTo(grp.value,"1") == 0 ) {
				valOne = new BigDecimal("44");
				Argument<BigDecimal> valOneBox11 = new Argument<BigDecimal>("",valOne);
				res = res + space + tableDE( valOneBox11 ) + space;

				valOne = valOneBox11.value;
			} else {
				valOne = new BigDecimal("41");
				Argument<BigDecimal> valOneBox12 = new Argument<BigDecimal>("",valOne);
				res = res + space + tableDE( valOneBox12 ) + space;

				valOne = valOneBox12.value;

			}
		}
		if( MdaUtils.compareTo(sign,3) == 0 && MdaUtils.compareTo(grp.value,"0")>0 ) {
			//assign singular or plural depending on groupsign
			if( MdaUtils.compareTo(number,1) == 0 && MdaUtils.compareTo(grp.value,"1") == 0 ) {
				valOne = new BigDecimal("45");
				Argument<BigDecimal> valOneBox13 = new Argument<BigDecimal>("",valOne);
				res = res + space + tableDE( valOneBox13 ) + space;

				valOne = valOneBox13.value;

			} else {
				valOne = new BigDecimal("42");
				Argument<BigDecimal> valOneBox14 = new Argument<BigDecimal>("",valOne);
				res = res + space + tableDE( valOneBox14 ) + space;

				valOne = valOneBox14.value;
			}
		}
		if( MdaUtils.compareTo(sign,4) == 0 && MdaUtils.compareTo(grp.value,"0")>0 ) {
			//assign singular or plural depending on groupsign
			if( MdaUtils.compareTo(number,1) == 0 ) {
				valOne = new BigDecimal("46");
				Argument<BigDecimal> valOneBox15 = new Argument<BigDecimal>("",valOne);
				res = res + space + tableDE( valOneBox15 ) + space;

				valOne = valOneBox15.value;
			} else {
				valOne = new BigDecimal("43");
				Argument<BigDecimal> valOneBox16 = new Argument<BigDecimal>("",valOne);
				res = res + space + tableDE( valOneBox16 ) + space;

				valOne = valOneBox16.value;
			}
		}
		return res;
	}

	/**
	 *   source:sysamt.0004.script
	 */
	public static String baseEN(BigDecimal number) {
		// this function
		// - calculates the number of groups of the input number
		// - for each TRUE group the function GroupEN/DE is called; returning the
		//   number-text of the group
		// - returns the total number-text
		BigDecimal in = number;
		BigDecimal vnumber = in;
		String tXTnumber = MdaUtils.toString(number);
		int len = Strings.len(tXTnumber);
		String res = "";
		boolean grphundred = false;
		boolean grpthousand = false;
		boolean grpmillion = false;
		boolean grpbillion = false;
		boolean grptrillion = false;
		float divide = Decimals.div(len,3).floatValue();
		if( divide > 0 ) {
			grphundred = true;
			if( divide > 1 ) {
				grpthousand = true;
				if( divide > 2 ) {
					grpmillion = true;
					if( divide > 3 ) {
						grpbillion = true;
						if( divide > 4 ) {
							grptrillion = true;
						}
					}
				}
			}
		}
		// description of the groupsign $sign
		// 0 = hundred
		// 1 = thousand
		// 2 = million
		// 3 = billion
		// 4 = trillion
		int lentri = 0;
		int midlen = 0;
		String grp = NULLSTR;
		int sign = 0;
		if( MdaUtils.compareTo(grptrillion,true) == 0 ) {
			lentri = Strings.len(tXTnumber);
			midlen = lentri - 12;
			grp = Strings.mid(tXTnumber,1,midlen);
			sign = 4;
			Argument<String> grpBox = new Argument<String>("",grp);
			res = groupEN( new BigDecimal(sign), grpBox );

			grp = grpBox.value;

			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lentri - midlen);
		}
		int lenbio = 0;
		if( MdaUtils.compareTo(grpbillion,true) == 0 ) {
			lenbio = Strings.len(tXTnumber);
			midlen = lenbio - 9;
			grp = Strings.mid(tXTnumber,1,midlen);
			sign = 3;
			Argument<String> grpBox1 = new Argument<String>("",grp);
			res = res + groupEN( new BigDecimal(sign), grpBox1 );

			grp = grpBox1.value;

			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenbio - midlen);
		}
		int lenmio = 0;
		if( MdaUtils.compareTo(grpmillion,true) == 0 ) {
			lenmio = Strings.len(tXTnumber);
			midlen = lenmio - 6;
			grp = Strings.mid(tXTnumber,1,midlen);
			sign = 2;
			Argument<String> grpBox2 = new Argument<String>("",grp);
			res = res + groupEN( new BigDecimal(sign), grpBox2 );

			grp = grpBox2.value;

			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenmio - midlen);
		}
		int lenthous = 0;
		if( MdaUtils.compareTo(grpthousand,true) == 0 ) {
			lenthous = Strings.len(tXTnumber);
			midlen = lenthous - 3;
			grp = Strings.mid(tXTnumber,1,midlen);
			sign = 1;
			Argument<String> grpBox3 = new Argument<String>("",grp);
			res = res + groupEN( new BigDecimal(sign), grpBox3 );

			grp = grpBox3.value;

			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenthous - midlen);
		}
		int lenhund = 0;
		if( MdaUtils.compareTo(grphundred,true) == 0 ) {
			lenhund = Strings.len(tXTnumber);
			grp = Strings.mid(tXTnumber,1,lenhund);
			sign = 0;
			Argument<String> grpBox4 = new Argument<String>("",grp);
			res = res + groupEN( new BigDecimal(sign), grpBox4 );

			grp = grpBox4.value;
		}
		BigDecimal valOne = null;
		if( MdaUtils.compareTo(vnumber,0) == 0 ) {
			valOne = vnumber;
			Argument<BigDecimal> valOneBox = new Argument<BigDecimal>("",valOne);
			res = tableEN( valOneBox );

			valOne = valOneBox.value;
		}
		return res;
	}

	/**
	 *   source:sysamt.0005.script
	 */
	public static String baseDE(BigDecimal number) {
		// this function
		// - calculates the number of groups of the input number
		// - for each TRUE group the function GroupEN/DE is called; returning the
		//   number-text of the group
		// - returns the total number-text
		BigDecimal in = number;
		BigDecimal vnumber = in;
		String tXTnumber = MdaUtils.toString(number);
		int len = Strings.len(tXTnumber);
		String res = "";
		boolean grphundred = false;
		boolean grpthousand = false;
		boolean grpmillion = false;
		boolean grpmilliarde = false;
		boolean grpbillion = false;
		int divide = Decimals.div(len,3).intValue();
		if( divide > 0 ) {
			grphundred = true;
			if( divide > 1 ) {
				grpthousand = true;
				if( divide > 2 ) {
					grpmillion = true;
					if( divide > 3 ) {
						grpmilliarde = true;
						if( divide > 4 ) {
							grpbillion = true;
						}
					}
				}
			}
		}
		// description of the groupsign $sign
		// 0 = hundert
		// 1 = tausend
		// 2 = million
		// 3 = millarde
		// 4 = billion
		int lenbio = 0;
		int midlen = 0;
		String grp = NULLSTR;
		int sign = 0;
		if( MdaUtils.compareTo(grpbillion,true) == 0 ) {
			lenbio = Strings.len(tXTnumber);
			midlen = lenbio - 12;
			grp = Strings.mid(tXTnumber,1,midlen);
			sign = 4;
			Argument<String> grpBox = new Argument<String>("",grp);
			res = res + groupDE( new BigDecimal(sign), grpBox );

			grp = grpBox.value;

			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenbio - midlen);
		}
		int lenmia = 0;
		if( MdaUtils.compareTo(grpmilliarde,true) == 0 ) {
			lenmia = Strings.len(tXTnumber);
			midlen = lenmia - 9;
			grp = Strings.mid(tXTnumber,1,midlen);
			sign = 3;
			Argument<String> grpBox1 = new Argument<String>("",grp);
			res = res + groupDE( new BigDecimal(sign), grpBox1 );

			grp = grpBox1.value;

			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenmia - midlen);
		}
		int lenmio = 0;
		if( MdaUtils.compareTo(grpmillion,true) == 0 ) {
			lenmio = Strings.len(tXTnumber);
			midlen = lenmio - 6;
			grp = Strings.mid(tXTnumber,1,midlen);
			sign = 2;
			Argument<String> grpBox2 = new Argument<String>("",grp);
			res = res + groupDE( new BigDecimal(sign), grpBox2 );

			grp = grpBox2.value;

			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenmio - midlen);
		}
		int lenthous = 0;
		if( MdaUtils.compareTo(grpthousand,true) == 0 ) {
			lenthous = Strings.len(tXTnumber);
			midlen = lenthous - 3;
			grp = Strings.mid(tXTnumber,1,midlen);
			sign = 1;
			Argument<String> grpBox3 = new Argument<String>("",grp);
			res = res + groupDE( new BigDecimal(sign), grpBox3 );

			grp = grpBox3.value;

			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenthous - midlen);
		}
		int lenhun = 0;
		if( MdaUtils.compareTo(grphundred,true) == 0 ) {
			lenhun = Strings.len(tXTnumber);
			grp = Strings.mid(tXTnumber,1,lenhun);
			sign = 0;
			Argument<String> grpBox4 = new Argument<String>("",grp);
			res = res + groupDE( new BigDecimal(sign), grpBox4 );

			grp = grpBox4.value;
		}
		BigDecimal valOne = null;
		if( MdaUtils.compareTo(vnumber,0) == 0 ) {
			valOne = vnumber;
			Argument<BigDecimal> valOneBox = new Argument<BigDecimal>("",valOne);
			res = tableDE( valOneBox );

			valOne = valOneBox.value;
		}
		return res;
	}

	/**
	 *   source:sysamt.0007.script
	 */
	public static String baseFR(BigDecimal number) {
		// this function
		// - calculates the number of groups of the input number
		// - for each TRUE group the function GroupFR is called; returning the
		//   number-text of the group
		// - returns the total number-text
		BigDecimal in = number;
		BigDecimal vnumber = in;
		String tXTnumber = MdaUtils.toString(number);
		int len = Strings.len(tXTnumber);
		String res = "";
		boolean grphundred = false;
		boolean grpthousand = false;
		boolean grpmillion = false;
		boolean grpbillion = false;
		boolean grptrillion = false;
		int divide = Decimals.div(len,3).intValue();
		if( divide > 0 ) {
			grphundred = true;
			if( divide > 1 ) {
				grpthousand = true;
				if( divide > 2 ) {
					grpmillion = true;
					if( divide > 3 ) {
						grpbillion = true;
						if( divide > 4 ) {
							grptrillion = true;
						}
					}
				}
			}
		}
		// description of the groupsign $sign
		// 0 = hundred
		// 1 = thousand
		// 2 = million
		// 3 = billion
		// 4 = trillion
		int lentri = 0;
		int midlen = 0;
		String grp = NULLSTR;
		if( MdaUtils.compareTo(grptrillion,true) == 0 ) {
			lentri = Strings.len(tXTnumber);
			midlen = lentri - 12;
			grp = Strings.mid(tXTnumber,1,midlen);
			res = groupFR( new BigDecimal(4), grp );
			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lentri - midlen);
		}
		int lenbio = 0;
		if( MdaUtils.compareTo(grpbillion,true) == 0 ) {
			lenbio = Strings.len(tXTnumber);
			midlen = lenbio - 9;
			grp = Strings.mid(tXTnumber,1,midlen);
			res = res + groupFR( new BigDecimal(3), grp );
			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenbio - midlen);
		}
		int lenmio = 0;
		if( MdaUtils.compareTo(grpmillion,true) == 0 ) {
			lenmio = Strings.len(tXTnumber);
			midlen = lenmio - 6;
			grp = Strings.mid(tXTnumber,1,midlen);
			res = res + groupFR( new BigDecimal(2), grp );
			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenmio - midlen);
		}
		int lenthous = 0;
		if( MdaUtils.compareTo(grpthousand,true) == 0 ) {
			lenthous = Strings.len(tXTnumber);
			midlen = lenthous - 3;
			grp = Strings.mid(tXTnumber,1,midlen);
			res = res + groupFR( new BigDecimal(1), grp );
			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenthous - midlen);
		}
		int lenhund = 0;
		if( MdaUtils.compareTo(grphundred,true) == 0 ) {
			lenhund = Strings.len(tXTnumber);
			grp = Strings.mid(tXTnumber,1,lenhund);
			res = res + groupFR( new BigDecimal(0), grp );
		}
		if( MdaUtils.compareTo(vnumber,0) == 0 ) {
			res = tableFR( new BigDecimal(0) );
		}
		return Strings.trim(res);
	}

	/**
	 *   source:sysamt.0008.script
	 */
	public static String groupFR(BigDecimal sign,String grp) {
		// this function converts the group-number into group-text
		// and returns the group-text
		int number = 1;
		String res = "";
		String space = " ";
		String paddedGrp = Strings.mid(Strings.mid("000",1,3 - Strings.len(grp)) + grp,1,3);
		BigDecimal units = Strings.parseDecimal(Strings.mid(paddedGrp,3,1));
		BigDecimal tens = Strings.parseDecimal(Strings.mid(paddedGrp,2,1));
		BigDecimal hundreds = Strings.parseDecimal(Strings.mid(paddedGrp,1,1));
		BigDecimal tensplus = Strings.parseDecimal(Strings.mid(paddedGrp,2,2));
		// hundreds
		if( MdaUtils.compareTo(hundreds,1) == 0 ) {
			res = res + "cent ";
		} else {
			if( MdaUtils.compareTo(hundreds,1)>0 ) {
				res = res + tableFR( hundreds );
				if( MdaUtils.compareTo(tensplus,0)>0 ) {
					res = res + " cent ";
				} else {
					res = res + " cents ";
				}
			}
		}
		if( MdaUtils.compareTo(paddedGrp,"001")>0 || MdaUtils.compareTo(sign,1) != 0 ) {   // to avoid `un mille`
			// part 1 - 99
			if( MdaUtils.compareTo(tensplus,0)>0 ) {
				if( MdaUtils.compareTo(tensplus,20)<=0 ) {
					res = res + tableFR( tensplus );
				} else {
					if( MdaUtils.compareTo(tensplus,71) == 0 ) {
						res = res + tableFR( tensplus );
					} else {
						if( MdaUtils.compareTo(tensplus,61)>=0 && MdaUtils.compareTo(tensplus,79)<=0 ) {
							res = res + tableFR( new BigDecimal(60) ) + "-" + tableFR( Decimals.sub(tensplus,60) );
						} else {
							if( MdaUtils.compareTo(tensplus,81)>=0 && MdaUtils.compareTo(tensplus,99)<=0 ) {
								res = res + tableFR( new BigDecimal(80) ) + "-" + tableFR( Decimals.sub(tensplus,80) );
							} else {
								res = res + tableFR( Decimals.mul(tens,10) );
								if( MdaUtils.compareTo(units,1) == 0 ) {
									res = res + " et un";
								} else {
									if( MdaUtils.compareTo(units,2)>=0 ) {
										res = res + "-" + tableFR( units );
									}
								}
							}
						}
					}
				}
				res = res + " ";
			}
		}
		//assign of the groupsign and rule out further groupsigns, if the rest of #the number is zero
		//(-> eg. 1.000.000 one million and not one million thousand ...)
		//and setting a space beetwen the words
		if( MdaUtils.compareTo(paddedGrp,"000")>0 ) {
			switch( sign.intValue() ) {
				case 1:
					res = res + "mille ";
					break;
				case 2:
					if( MdaUtils.compareTo(paddedGrp,"001") == 0 ) {
						res = res + "million ";
					} else {
						res = res + "millions ";
					}
					break;
				case 3:
					if( MdaUtils.compareTo(paddedGrp,"001") == 0 ) {
						res = res + "milliard ";
					} else {
						res = res + "milliards ";
					}
					break;
				case 4:
					res = res + "billion ";
					break;
				case 5:
					res = res + "trillion ";
					break;
			}
		}
		return res;
	}

	/**
	 *   source:sysamt.0009.script
	 */
	public static String tableFR(BigDecimal figure) {
		String eng = NULLSTR;
		switch( figure.intValue() ) {
			case 0:
				eng = "zéro";
				break;
			case 1:
				eng = "un";
				break;
			case 2:
				eng = "deux";
				break;
			case 3:
				eng = "trois";
				break;
			case 4:
				eng = "quatre";
				break;
			case 5:
				eng = "cinq";
				break;
			case 6:
				eng = "six";
				break;
			case 7:
				eng = "sept";
				break;
			case 8:
				eng = "huit";
				break;
			case 9:
				eng = "neuf";
				break;
			case 10:
				eng = "dix";
				break;
			case 11:
				eng = "onze";
				break;
			case 12:
				eng = "douze";
				break;
			case 13:
				eng = "treize";
				break;
			case 14:
				eng = "quatorze";
				break;
			case 15:
				eng = "quinze";
				break;
			case 16:
				eng = "seize";
				break;
			case 17:
				eng = "dix-sept";
				break;
			case 18:
				eng = "dix-huit";
				break;
			case 19:
				eng = "dix-neuf";
				break;
			case 20:
				eng = "vingt";
				break;
			case 30:
				eng = "trente";
				break;
			case 40:
				eng = "quarante";
				break;
			case 50:
				eng = "cinquante";
				break;
			case 60:
				eng = "soixante";
				break;
			case 71:
				eng = "soixante et onze";
				break;
			case 80:
				eng = "quatre-vingt";
				break;
			default:
				eng = "";
				break;
		}
		return eng;
	}

	/**
	 *   source:sysamt.0010.script
	 */
	public static String baseIT(BigDecimal number) {
		// this function
		// - calculates the number of groups of the input number
		// - for each TRUE group the function GroupFR is called; returning the
		//   number-text of the group
		// - returns the total number-text
		BigDecimal in = number;
		BigDecimal vnumber = in;
		String tXTnumber = MdaUtils.toString(number);
		int len = Strings.len(tXTnumber);
		String res = "";
		boolean grphundred = false;
		boolean grpthousand = false;
		boolean grpmillion = false;
		boolean grpbillion = false;
		boolean grptrillion = false;
		int divide = Decimals.div(len,3).intValue();
		if( divide > 0 ) {
			grphundred = true;
			if( divide > 1 ) {
				grpthousand = true;
				if( divide > 2 ) {
					grpmillion = true;
					if( divide > 3 ) {
						grpbillion = true;
						if( divide > 4 ) {
							grptrillion = true;
						}
					}
				}
			}
		}
		// description of the groupsign $sign
		// 0 = hundred
		// 1 = thousand
		// 2 = million
		// 3 = billion
		// 4 = trillion
		int lentri = 0;
		int midlen = 0;
		String grp = NULLSTR;
		if( MdaUtils.compareTo(grptrillion,true) == 0 ) {
			lentri = Strings.len(tXTnumber);
			midlen = lentri - 12;
			grp = Strings.mid(tXTnumber,1,midlen);
			res = groupIT( new BigDecimal(4), grp );
			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lentri - midlen);
		}
		int lenbio = 0;
		if( MdaUtils.compareTo(grpbillion,true) == 0 ) {
			lenbio = Strings.len(tXTnumber);
			midlen = lenbio - 9;
			grp = Strings.mid(tXTnumber,1,midlen);
			res = res + groupIT( new BigDecimal(3), grp );
			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenbio - midlen);
		}
		int lenmio = 0;
		if( MdaUtils.compareTo(grpmillion,true) == 0 ) {
			lenmio = Strings.len(tXTnumber);
			midlen = lenmio - 6;
			grp = Strings.mid(tXTnumber,1,midlen);
			res = res + groupIT( new BigDecimal(2), grp );
			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenmio - midlen);
		}
		int lenthous = 0;
		if( MdaUtils.compareTo(grpthousand,true) == 0 ) {
			lenthous = Strings.len(tXTnumber);
			midlen = lenthous - 3;
			grp = Strings.mid(tXTnumber,1,midlen);
			res = res + groupIT( new BigDecimal(1), grp );
			tXTnumber = Strings.mid(tXTnumber,midlen + 1,lenthous - midlen);
		}
		int lenhund = 0;
		if( MdaUtils.compareTo(grphundred,true) == 0 ) {
			lenhund = Strings.len(tXTnumber);
			grp = Strings.mid(tXTnumber,1,lenhund);
			res = res + groupIT( new BigDecimal(0), grp );
		}
		if( MdaUtils.compareTo(vnumber,0) == 0 ) {
			res = tableIT( new BigDecimal(0) );
		}
		return Strings.trim(res);
	}

	/**
	 *   source:sysamt.0011.script
	 */
	public static String tableIT(BigDecimal figure) {
		String eng = NULLSTR;
		switch( figure.intValue() ) {
			case 0:
				eng = "zero";
				break;
			case 1:
				eng = "uno";
				break;
			case 2:
				eng = "due";
				break;
			case 3:
				eng = "tre";
				break;
			case 4:
				eng = "quattro";
				break;
			case 5:
				eng = "cinque";
				break;
			case 6:
				eng = "sei";
				break;
			case 7:
				eng = "sette";
				break;
			case 8:
				eng = "otto";
				break;
			case 9:
				eng = "nove";
				break;
			case 10:
				eng = "dieci";
				break;
			case 11:
				eng = "undici";
				break;
			case 12:
				eng = "dodici";
				break;
			case 13:
				eng = "tredici";
				break;
			case 14:
				eng = "quattordici";
				break;
			case 15:
				eng = "quindici";
				break;
			case 16:
				eng = "sedici";
				break;
			case 17:
				eng = "diciasette";
				break;
			case 18:
				eng = "diciotto";
				break;
			case 19:
				eng = "diciannove";
				break;
			case 20:
				eng = "venti";
				break;
			case 30:
				eng = "trenta";
				break;
			case 40:
				eng = "quaranta";
				break;
			case 50:
				eng = "cinquanta";
				break;
			case 60:
				eng = "sessanta";
				break;
			case 70:
				eng = "settanta";
				break;
			case 80:
				eng = "ottanta";
				break;
			case 90:
				eng = "novanta";
				break;
			default:
				//throw new Exception("Internal error in AmountInWords, Language Italian, tableIT called with " + MdaUtils.toString(figure));
				return "";
		}
		return eng;
	}

	/**
	 *   source:sysamt.0012.script
	 */
	public static String groupIT(BigDecimal sign,String grp) {
		// this function converts the group-number into group-text
		// and returns the group-text
		int number = 1;
		String res = "";
		String space = " ";
		String paddedGrp = Strings.mid(Strings.mid("000",1,3 - Strings.len(grp)) + grp,1,3);
		BigDecimal units = Strings.parseDecimal(Strings.mid(paddedGrp,3,1));
		BigDecimal tens = Strings.parseDecimal(Strings.mid(paddedGrp,2,1));
		BigDecimal hundreds = Strings.parseDecimal(Strings.mid(paddedGrp,1,1));
		BigDecimal tensplus = Strings.parseDecimal(Strings.mid(paddedGrp,2,2));
		// hundreds
		if( MdaUtils.compareTo(hundreds,1) == 0 ) {
			res = res + "cento";
		} else {
			if( MdaUtils.compareTo(hundreds,1)>=0 ) {
				res = res + tableIT( hundreds );
				res = res + "cento";
				if( MdaUtils.compareTo(tensplus,0) == 0 ) {
					res = res + " ";
				}
			}
		}
		String word = NULLSTR;
		if( MdaUtils.compareTo(paddedGrp,"001") == 0 ) {
			if( MdaUtils.compareTo(sign,0) == 0 ) {
				res = res + "uno";
			} else {
				if( MdaUtils.compareTo(sign,1)>0 ) {     // to avoid `un mille`
					res = res + "un "; // `millione` mit `un` statt `uno`
				}
			}
		} else {
			// part 1 - 99
			if( MdaUtils.compareTo(tensplus,0)>0 ) {
				if( MdaUtils.compareTo(tensplus,1) == 0 ) {
					res = res + " ";
				}
				if( MdaUtils.compareTo(tensplus,3) == 0 && MdaUtils.compareTo(paddedGrp,"003") != 0 ) {
					res = res + "tré";       // with accent
				} else {
					if( MdaUtils.compareTo(tensplus,20)<=0 ) {
						res = res + tableIT( tensplus );
					} else {
						word = tableIT( Decimals.mul(tens,10) );
						if( MdaUtils.compareTo(units,1) == 0 || MdaUtils.compareTo(units,8) == 0 ) {
							word = Strings.mid(word,1,Strings.len(word) - 1);
						}
						res = res + word;
						if( MdaUtils.compareTo(units,1)>=0 ) {
							if( MdaUtils.compareTo(units,3) == 0 ) {
								res = res + "tré"; // with accent
							} else {
								word = tableIT( units );
								if( MdaUtils.compareTo(units,1) == 0 && MdaUtils.compareTo(sign,1) == 0 ) {
									word = Strings.mid(word,1,Strings.len(word) - 1);
								}
								res = res + word;
							}
						}
					}
				}
			}
		}
		//assign of the groupsign and rule out further groupsigns, if the rest of #the number is zero
		//(-> eg. 1.000.000 one million and not one million thousand ...)
		//and setting a space beetwen the words
		if( MdaUtils.compareTo(paddedGrp,"000")>0 ) {
			switch( sign.intValue() ) {
				case 1:
					if( MdaUtils.compareTo(paddedGrp,"001") == 0 ) {
						res = res + "mille ";
					} else {
						res = res + "mila ";
					}
					break;
				case 2:
					if( MdaUtils.compareTo(paddedGrp,"001") == 0 ) {
						res = res + "milione ";
					} else {
						res = res + "milioni ";
					}
					break;
				case 3:
					if( MdaUtils.compareTo(paddedGrp,"001") == 0 ) {
						res = res + "miliardo ";
					} else {
						res = res + "miliardi ";
					}
					break;
				case 4:
					if( MdaUtils.compareTo(paddedGrp,"001") == 0 ) {
						res = res + "bilione ";
					} else {
						res = res + "bilioni ";
					}
					break;
				case 5:
					if( MdaUtils.compareTo(paddedGrp,"001") == 0 ) {
						res = res + "trilione ";
					} else {
						res = res + "trilioni ";
					}
					break;
			}
		}
		return res;
	}

	/**
	 *   source:sysamt.0006.script
	 */
	public static String amtWrd(BigDecimal argNumToConvert,String argLan) {
		//! Function to convert a Number into a Text using the passed target language.
		//! The resulting Text may include the leading word "minus". Only the integer portion
		//! of the passed Number ist converted. Thus decimal fractions are not converted.
		//! ArgNumToConvert number to be converted
		//! ArgLan two digit language code describing the target language.
		//! If the target language is not supported, English is taken as a default language
		//! and an errorcode -110 is returned.
		String res = "";
		int number = Numerics.toInt(argNumToConvert);
		if( number < 0 ) {
			number = -number;
			res = "minus ";
		}
		switch( Strings.toUpper(argLan) ) {
			case "EN":
				res = res + baseEN( new BigDecimal(number) );
				break;
			case "DE":
				res = baseDE( new BigDecimal(number) );
				break;
			case "FR":
				res = baseFR( new BigDecimal(number) );
				break;
			case "IT":
				res = baseIT( new BigDecimal(number) );
				break;
			default:
				res = res + baseEN( new BigDecimal(number) );
		}
		return Strings.trim(res);
	}

    public static final BigDecimal BIGDECIMAL_THOUNSAND = new BigDecimal("1000");
    public static final BigDecimal BIGDECIMAL_HUNDRED = new BigDecimal("100");
    public static final BigDecimal BIGDECIMAL_TWENTY = new BigDecimal("20");
    private static final String[] ONES = {
            "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
            "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
    };
    private static final String[] TENS = {
            "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"
    };
    private static final String[] THOUSANDS = {
            "", "thousand", "million", "billion", "trillion"
    };

    // 数字转换为英文（小于0手动加负号）
    public static String numberToWords(BigDecimal number) {
        if (number.compareTo(BigDecimal.ZERO) < 0 || number.compareTo(new BigDecimal(999999999999L)) > 0) {
            return "";
        }
        if (number.compareTo(BigDecimal.ZERO) == 0) {
        	return "zero";
		}
        StringBuilder result = new StringBuilder();
        // 百，千，百万，十亿的索引
        int groupIndex = 0;
        BigDecimal groupAmount;

        while (number.compareTo(BigDecimal.ONE) >= 0) {
            groupAmount = number.remainder(BIGDECIMAL_THOUNSAND);
            if (groupAmount.compareTo(BigDecimal.ONE) >= 0 || (groupAmount.compareTo(BigDecimal.ONE) == 0 && result.length() > 0)) {
                result.insert(0, convertGroupToWords(groupAmount) + " " + THOUSANDS[groupIndex] + " ");
            }
            number = number.divide(BIGDECIMAL_THOUNSAND);
            groupIndex++;
        }
        while (result.length() > 0 && result.charAt(result.length() - 1) == ' ') {
            result.setLength(result.length() - 1);
        }
        return result.toString().trim();
    }

    private static String convertGroupToWords(BigDecimal groupAmount) {
        StringBuilder result = new StringBuilder();

        if (groupAmount.compareTo(BIGDECIMAL_HUNDRED) >= 0) {
            result.append(ONES[groupAmount.divide(BIGDECIMAL_HUNDRED).intValue()]).append(" hundred ");
            groupAmount = groupAmount.remainder(BIGDECIMAL_HUNDRED);
        }
        if (groupAmount.compareTo(BIGDECIMAL_TWENTY) >= 0) {
            result.append(TENS[groupAmount.divide(BigDecimal.TEN).intValue()]).append(" ");
            groupAmount = groupAmount.remainder(BigDecimal.TEN);
        }
        if (groupAmount.compareTo(BigDecimal.ZERO) > 0) {
            result.append(ONES[groupAmount.intValue()]).append(" ");
        }
        return result.toString().trim();
    }
}