package číslo_slovy;

/**
 * @author Jan Hoskovec
 * @version 9.4.2004
 */
public class HonzaSlovy
{
//-------------------------------------atributy------------------------------------
    //popisy čísel od 0 do 9
    private static String jednotky[] = new String[]{
        "nula","jedna","dva","tři","čtyři","pět","šest","sedm","osm","devět",
        "deset","jedenáct","dvanáct","třináct","čtrnáct","patnáct","šestnáct",
        "sedmnáct","osmnáct","devatenáct"
            };
    //popisy desítek (20, 30 ...)
    private static String desítky[] = new String[]{
        "dvacet","třicet","čtyřicet","padesát","šedesát","sedmdesát",
        "osmdesát","devadesát"
            };
            
    //popisy stovek ( 100, 200, 300 ...)
    private static String stovky[] = new String[]{
        "sto","dvě stě", "tři sta","čtyři sta","pět set","šest set",
        "sedm set","osm set","devět set"
            };
//-------------------------------------metody---------------------------------------
    /**
     * Jediná veřejná metoda třídy vrací popis zadaného čísla
     * @param   č   jakékoli číslo od 0 do 99
     * @return  zadané číslo slovy
     */ 
    public static String číslo( int č ){
        String s = "";//sem se bude postupně ukládat popis pro vrácení
        
        //kontrola platnosti parametru
        if( Math.abs( č ) > 999999 ){
            throw new IllegalArgumentException("Absolutní hodnota čísla " + č + " je větší " + 
            "než 999.999 a tak ho tato verze není schopna určit.");
            }
         //první rozhodování - pokud je číslo záporné, bude popis začínat slove mínus,
         //v opačném případě zůstane začátek řetězce prázdný
        if( č < 0 ){
            s = "mínus ";
            č = -č;
        }
        
         //dostane popis čísla a výsledek přidá na konec řetězce
        if( č < 1000 ){
            s += getKrátké( č );
        }else{
            s += getDlouhé( č );
        }
        
        return s;   //vrátí určenou hodnotu
        
    }
    
    
    
//-----------------------------------pomocné metody----------------------------------
    //vrací popis čísla s jednoslovným názvem( menší než dvacet )
    private static String getJednociferné( int č ){
        //kontrola argumentů
        if( ( č < 0 )||( č > 19 ) ){
            throw new IllegalArgumentException(
                "Chybný argument - tato metoda vrací jen čísla od 0 do 19.");
        }
        return jednotky[ č ];
    }
    
    
    //vrací popis čísla od 20 do 99
    private static String getDvouciferné( int č ){
        //kontrola argumentu
        if( ( č < 0 ) || ( č > 99 ) ){
            throw new IllegalArgumentException(
                "Chybný argument - tato metoda vrací jen čísla od 0 do 99.");
        }
        if( (č % 10) == 0 ){//pokud je číslo dělitelné deseti
            return desítky[ ( č / 10 ) - 2 ];//vrať jen desítku
        }else{
            return desítky[ ( č / 10 ) - 2 ] + " " + jednotky[ č % 10 ];
            //vrat desítku a jednotku
        }
    }
    
    
    //vrací popis čísla od 100 do 999
    private static String getTrojciferné( int č ){
        //kontrola argumentu
        if( ( č < 100 ) || ( č > 999 ) ){
            throw new IllegalArgumentException("Chybný argument - tato metoda "+
            "vrací jen čísla od 100 do 999.");
        }
        
        if( (č % 100) == 0 ){//pokud je číslo dělitelné stem
            return stovky[ ( č / 100 ) - 1 ];//vrať jen stovku
        }else{
            if( (č % 100)>19 ){
                return stovky[ ( č / 100 ) - 1 ] + " " + getDvouciferné( č % 100  );
            }else{
                return stovky[ ( č / 100 ) - 1 ] + " " +getJednociferné( č % 100 );
            }
        }
    }

    
    //vrací popis čísla od 1000 do 999999
    private static String getDlouhé( int č ){
        //kontrola argumentu
        if( ( č < 1000 ) || ( č > 999999 ) ){
            throw new IllegalArgumentException("Chybný argument - tato metoda "+
            "vrací jen čísla od 1000 do 999 999.");
        }
        
        //připraví si dva pomocné řetězce
        String s1, s2, s3;
        s1 = getKrátké( č / 1000 );
        s2 = getKrátké( č % 1000 );
        s1 = ( s1 == jednotky[ 1 ] ) ? "" : s1 + " ";//jedna tisíc se nezobrazuje
        s2 = ( s2 == jednotky[ 0 ] ) ? "" : " " + s2 ;
        
        //určí, jestli prostřední slovo bude tisíc nebo tisíce
        if( ( č / 1000 ) > 1 && ( č / 1000 ) < 5 ){
            s3 = "tisíce";
        }else{
            s3 = "tisíc";
        }
        //vrátí výsledek
        return s1 + s3 + s2;
        
    }
    
    
    private static String getKrátké( int č ){
        //kontrola argumentu
        if( ( č < 0 ) || ( č > 999 ) ){
            throw new IllegalArgumentException("Chybný argument - tato metoda "+
            "vrací jen čísla od 0 do 999.");
        }
        
        //postupně se zkouší volat různé metody, výsledek se vezme od té, od které to půjde
        try{
            return getJednociferné( č );//zkus to dostat z jednociferných
        }catch( IllegalArgumentException exc ){//pokud to nevyjde
            try{
                return getDvouciferné( č );//zkus to číslo vytáhnout z dvouciferných
            }catch( IllegalArgumentException exc2 ){//pokud ani to nepůjde
                return getTrojciferné( č );
                //jiná možnost už není, takže není potřeba hlídat výjimku
            }
        }
    }
}

