/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package net.sf.saxon.number;
/**
* Numberer class for the Russian language
*/
public final class Numberer_ru
extends AbstractNumberer
{
private static final long serialVersionUID = 1L;
private static String[] russianOrdinalUnits =
{"", "первый", "второй", "третий", "четвертый", "пятый", "шестой", "седьмой", "восьмой", "девятый", "десятый", "одиннадцатый",
"двенадцатый", "тринадцатый", "четырнадцатый", "пятнадцатый", "шестнадцатый", "семнадцатый", "восемнадцатый", "девятнадцатый"};
private static String[] russianOrdinalTens =
{"", "десятый", "двадцатый", "тридцатый", "сороковой", "пятидесятый", "шестидесятый", "семидесятый", "восьмидесятый", "девяностый"};
private static String[] russianOrdinalHundreds =
{"", "сотый", "двухсотый", "трехсотый", "четырехсотый", "пятисотый", "шестисотый", "семисотый", "восьмисотый", "девятисотый"};
private static String[] russianSpecUnits =
{"", "одна", "двух", "трех", "черырех", "пяти", "шести", "семи", "восьми", "девяти", "десяти", "одиннадцати", "двенадцати",
"тринадцати", "четырнадцати", "пятнадцати", "шестнадцати", "семнадцати", "восемнадцати", "девятнадцати"};
private static String[] russianSpecTens =
{"", "десяти", "двадцати", "тридцати", "сорока", "пятидесяти", "шестидесяти", "семидесяти", "восьмидесяти", "девяносто"};
private static String[] russianSpecHundreds =
{"", "сто", "двухсот", "трехсот", "черырехсот", "пятисот", "шестисот", "семисот", "восьмисот", "девятисот"};
private static String[] russianUnits =
{"", "один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять", "десять", "одиннадцать", "двенадцать",
"тринадцать", "четырнадцать", "пятнадцать", "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать"};
private static String[] russianTens =
{"", "десять", "двадцать", "тридцать", "сорок", "пятьдесят", "шестьдесят", "семьдесят", "восемьдесят", "девяносто"};
private static String[] russianHundreds =
{"", "сто", "двести", "триста", "четыреста", "пятьсот", "шестьсот", "семьсот", "восемьсот", "девятьсот"};
private static String[] russianDays = {"понедельник", "вторник", "среда", "четверг", "пятница", "суббота", "воскресенье"};
private static String[] russianDayAbbreviations = {"пн", "вт", "ср", "чт", "пт", "сб", "вс"};
private static int[] minUniqueDayLength = {2, 2, 2, 2, 2, 2, 2};
public String toBillion( String ordinalParam, long number, int wordCase )
{
String graduate = "миллиардный";
if ( number >= 100000000000L )
{
if ( number % 100000000000L == 0 )
{
long billion = number / 100000000000L;
String result = russianSpecHundreds[(int) billion];
result += graduate;
return applyCase( result, wordCase );
}
}
else if ( number >= 10000000000L )
{
if ( number % 10000000000L == 0 )
{
long billion = number / 10000000000L;
String result = russianSpecTens[(int) billion];
result += graduate;
return applyCase( result, wordCase );
}
}
if ( number % 1000000000L == 0 )
{
long billion = number / 1000000000L;
String result = russianSpecUnits[(int) billion];
result += graduate;
return applyCase( result, wordCase );
}
long rem = number % 1000000000;
long billion = number / 1000000000;
String result = ( number / 1000000000 == 1 ? " один" : toWords( number / 1000000000 ) ) + " миллиард" +
getEnding( (int) billion ) + " " + toOrdinalWords( ordinalParam, rem, wordCase );
return applyCase( result, wordCase );
}
public String toMillion( String ordinalParam, long number, int wordCase )
{
String graduate = "миллионный";
if ( number >= 100000000 )
{
if ( number % 100000000 == 0 )
{
long billion = number / 100000000;
String result = russianSpecHundreds[(int) billion];
result += graduate;
return applyCase( result, wordCase );
}
}
else if ( number >= 10000000 )
{
if ( number % 10000000 == 0 )
{
long billion = number / 10000000;
String result = russianSpecTens[(int) billion];
result += graduate;
return applyCase( result, wordCase );
}
}
if ( number % 1000000 == 0 )
{
long billion = number / 1000000;
String result = russianSpecUnits[(int) billion];
result += graduate;
return applyCase( result, wordCase );
}
long rem = number % 1000000;
long million = number / 1000000;
String result = ( number / 1000000 == 1 ? " один" : toWords( number / 1000000 ) ) + " миллион" +
getEnding( (int) million ) + " " + toOrdinalWords( ordinalParam, rem, wordCase );
return applyCase( result, wordCase );
}
public String toThousand( String ordinalParam, long number, int wordCase )
{
String graduate = "тысячный";
if ( number >= 100000 )
{
if ( number % 100000 == 0 )
{
long billion = number / 100000;
String result = russianSpecHundreds[(int) billion];
result += graduate;
return applyCase( result, wordCase );
}
if ( number % 1000 == 0 )
{
long thousand = number / 1000;
String result = russianHundreds[(int) thousand / 100];
long centum = thousand % 100;
result += russianSpecTens[(int) centum / 10];
result += russianSpecUnits[(int) centum % 10];
result += graduate;
return applyCase( result, wordCase );
}
long rem = number % 1000;
String result = getHundredThousandCount( number );
result += getThousandExponent( number );
result += toOrdinalWords( ordinalParam, rem, wordCase );
return applyCase( result, wordCase );
}
else if ( number >= 10000 )
{
if ( number % 10000 == 0 )
{
long billion = number / 10000;
String result = russianSpecTens[(int) billion];
result += graduate;
return applyCase( result, wordCase );
}
if ( number % 1000 == 0 )
{
long thousand = number / 1000;
if ( thousand > 10 && thousand < 20 )
{
String result = russianSpecUnits[(int) thousand];
result += graduate;
return applyCase( result, wordCase );
}
else
{
String result = russianSpecTens[(int) thousand / 10];
result += russianSpecUnits[(int) thousand % 10];
result += graduate;
return applyCase( result, wordCase );
}
}
long rem = number % 1000;
String result = getTenThousandCount( number );
result += getThousandExponent( number );
result += toOrdinalWords( ordinalParam, rem, wordCase );
return applyCase( result, wordCase );
}
if ( number % 1000 == 0 )
{
long billion = number / 1000;
String result = russianSpecUnits[(int) billion];
result += graduate;
return applyCase( result, wordCase );
}
long rem = number % 1000;
String result = getThousandCount( number );
result += getThousandExponent( number );
result += toOrdinalWords( ordinalParam, rem, wordCase );
return applyCase( result, wordCase );
}
@Override
public String toOrdinalWords( String ordinalParam, long number, int wordCase )
{
if ( number >= 1000000000 )
{
return toBillion( ordinalParam, number, wordCase );
}
else if ( number >= 1000000 )
{
return toMillion( ordinalParam, number, wordCase );
}
else if ( number >= 1000 )
{
return toThousand( ordinalParam, number, wordCase );
}
else if ( ( number % 100 == 0 ) && ( number / 100 < 10 ) )
{
return russianOrdinalHundreds[(int) number / 100];
}
else if ( number >= 100 )
{
long rem = number % 100;
if ( number % 100 == 0 )
{
return russianOrdinalHundreds[(int) number / 100];
}
String result = russianHundreds[(int) number / 100] + " " + toOrdinalWords( ordinalParam, rem, wordCase );
return applyCase( result, wordCase );
}
if ( number < 20 )
{
return russianOrdinalUnits[(int) number];
}
else if ( number % 10 == 0 )
{
return russianOrdinalTens[(int) number / 10];
}
int rem = (int) ( number % 10 );
String result = russianTens[(int) number / 10] + " " + russianOrdinalUnits[rem];
return applyCase( result, wordCase );
}
private String applyCase( String number, int wordCase )
{
if ( wordCase == UPPER_CASE )
{
return number.trim().toUpperCase();
}
else if ( wordCase == LOWER_CASE )
{
return number.trim().toLowerCase();
}
return number.trim();
}
@Override
public String toWords( long number )
{
if ( number >= 1000000000 )
{
long rem = number % 1000000000;
long billion = number / 1000000000;
String result = ( number / 1000000000 == 1 ? " один" : toWords( number / 1000000000 ) ) + " миллиард" +
getEnding( (int) billion ) + " " + toWords( rem );
return result.trim();
}
else if ( number >= 1000000 )
{
long rem = number % 1000000;
long million = number / 1000000;
String result = ( number / 1000000 == 1 ? " один" : toWords( number / 1000000 ) ) + " миллион" +
getEnding( (int) million ) + " " + toWords( rem );
return result.trim();
}
else if ( number >= 100000 )
{
long rem = number % 1000;
String result = getHundredThousandCount( number );
result += getThousandExponent( number );
result += toWords( rem );
return result.trim();
}
else if ( number >= 10000 )
{
long rem = number % 1000;
String result = getTenThousandCount( number );
result += getThousandExponent( number );
result += toWords( rem );
return result.trim();
}
else if ( number >= 1000 )
{
long rem = number % 1000;
String result = getThousandCount( number );
result += getThousandExponent( number );
result += toWords( rem );
return result.trim();
}
else if ( number >= 100 )
{
long rem = number % 100;
String result = russianHundreds[(int) number / 100] + " " + toWords( rem );
return result.trim();
}
else
{
if ( number < 20 )
{
return russianUnits[(int) number];
}
int rem = (int) ( number % 10 );
String result = russianTens[(int) number / 10] + " " + russianUnits[rem];
return result.trim();
}
}
private String getEnding( int number )
{
if ( ( number % 100 > 10 ) && ( number % 100 < 20 ) )
{
return "ов";
}
else if ( number % 10 == 1 )
{
return "";
}
else if ( ( number % 10 > 1 ) && ( number % 10 < 5 ) )
{
return "а";
}
return "ов";
}
private String getThousandCount( long number )
{
if ( number / 1000 == 1 )
{
return " одна";
}
else if ( number / 1000 == 2 )
{
return " две";
}
return toWords( number / 1000 );
}
private String getHundredThousandCount( long number )
{
long mille = number / 1000;
if ( mille % 100 == 1 )
{
long hundreds = number / 100000;
return russianHundreds[(int) hundreds] + " одна";
}
else if ( ( mille % 10 == 1 ) && ( mille % 100 != 11 ) )
{
long hundreds = number / 100000;
long tens = ( ( number / 1000 ) % 100 ) / 10;
return russianHundreds[(int) hundreds] + " " + russianTens[(int) tens] + " одна";
}
else if ( mille % 100 == 2 )
{
long hundreds = number / 100000;
return russianHundreds[(int) hundreds] + " две";
}
else if ( ( mille % 10 == 2 ) && ( mille % 100 != 12 ) )
{
long hundreds = number / 100000;
long tens = ( ( number / 1000 ) % 100 ) / 10;
return russianHundreds[(int) hundreds] + " " + russianTens[(int) tens] + " две";
}
return toWords( number / 1000 );
}
private String getTenThousandCount( long number )
{
long centum = number / 1000;
if ( centum % 10 == 1 )
{
long hundreds = number / 10000;
return russianTens[(int) hundreds] + " одна";
}
else if ( centum % 10 == 2 )
{
long hundreds = number / 10000;
return russianTens[(int) hundreds] + " две";
}
return toWords( number / 1000 );
}
private String getThousandExponent( long number )
{
if ( ( ( number / 1000 ) % 10 == 1 ) && ( ( number / 1000 ) % 100 < 10 ) )
{
return " тысяча ";
}
else if ( ( ( number / 1000 ) % 100 >= 10 ) && ( ( number / 1000 ) % 100 <= 20 ) )
{
return " тысяч ";
}
else if ( ( ( number / 1000 ) % 10 > 1 ) && ( ( number / 1000 ) % 10 < 5 ) )
{
return " тысячи ";
}
else if ( ( number % 100 == 0 ) || ( ( number / 1000 ) % 10 ) == 0 )
{
return " тысяч ";
}
return " тысяча ";
}
@Override
public String toWords( long number, int wordCase )
{
String s;
if ( number == 0 )
{
s = "ноль";
}
else
{
s = toWords( number );
}
if ( wordCase == UPPER_CASE )
{
return s.toUpperCase();
}
else if ( wordCase == LOWER_CASE )
{
return s.toLowerCase();
}
else
{
return s;
}
}
private static String[] russianMonths =
{"января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"};
@Override
public String monthName( int month, int minWidth, int maxWidth )
{
String name = russianMonths[month - 1];
if ( maxWidth < 3 )
{
maxWidth = 3;
}
if ( name.length() > maxWidth )
{
name = name.substring( 0, maxWidth );
}
while ( name.length() < minWidth )
{
name = name + ' ';
}
return name;
}
@Override
public String dayName( int day, int minWidth, int maxWidth )
{
String name = russianDays[day - 1];
if ( maxWidth < 2 )
{
maxWidth = 2;
}
if ( name.length() > maxWidth )
{
name = russianDayAbbreviations[day - 1];
if ( name.length() > maxWidth )
{
name = name.substring( 0, maxWidth );
}
}
while ( name.length() < minWidth )
{
name = name + ' ';
}
if ( minWidth == 1 && maxWidth == 2 )
{
// special case
name = name.substring( 0, minUniqueDayLength[day - 1] );
}
return name;
}
}