package pascal;

/*******************************************************************************
 * Třída Sbl_Třída slouží k ...
 *
 * @author    Rudolf Pecinovský
 * @version   0.00.000,  0.0.2003
 */
public class Pascal_14c
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================
    
    private static final String mezery = "                                    ";
    private static final int délkaBloku = mezery.length();
        
    
    
//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================
    
    int[][] trojúhelník;
//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ METODY TŘÍDY ======================================================

//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     * 
     */
    public Pascal_14c(int n)
    {
        if( n <= 0 )
            throw new IllegalArgumentException(
                "Trojúhelník musí mít kladný počet řádků - zadáno " + n );
        
        trojúhelník = new int[n][];
        trojúhelník[0] = new int[] { 1 };
        if( n == 1 )   return;      //====================>
        
        trojúhelník[1] = new int[] { 1, 1 };
        for( int r = 2;   r < n;   r++ )
        {
            int[] řádek = new int[r+1];
            řádek[0] = řádek[r] = 1;
            for( int s=1;   s < r;   s++ )
                řádek[s] = trojúhelník[r-1][s-1] + trojúhelník[r-1][s];
            trojúhelník[r] = řádek;
        }
    }

    

//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ INSTANCÍ =====================================
//== PŘEKRYTÉ METODY IMPLEMENTOVANÝCH ROZHRANÍ =================================
//== PŘEKRYTÉ ABSTRAKTNÍ METODY RODIČOVSKÉ TŘÍDY ===============================
//== PŘEKRYTÉ KONKRÉTNÍ METODY RODIČOVSKÉ TŘÍDY ================================
    
    public String toString()
    {
        StringBuffer sb = new StringBuffer( 
                          2 * trojúhelník.length*trojúhelník.length );
        sb.append("START\n");
        int řádků    = trojúhelník.length;
        int maxCifer = cifer( trojúhelník[řádků - 1][řádků/2] ) + 1;
        if( (maxCifer&1) != 0 )
            maxCifer++;
        int poslZnaků = řádků * maxCifer;
        
        for( int r=0;   r < řádků;   r++ )
        {
            int počMezer = (poslZnaků - r*maxCifer) / 2;
            přidejMezer( počMezer, sb );
            int[] řádek = trojúhelník[ r ];
            for( int hodnota : řádek )
                sb.append(mezery.
                        substring( délkaBloku - (maxCifer-cifer(hodnota)) ) )
                  .append( hodnota );
            sb.append( "\n" );
        }
        sb.append( "KONEC" );
        return sb.toString();
    }
    
    
    
//== NOVĚ ZAVEDENÉ METODY INSTANCÍ =============================================
//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
    
    private int cifer( int číslo )
    {
        int číslic = 1;
        while( (číslo /= 10) > 0 )
            číslic ++;
        return číslic;
    }
    
    private void přidejMezer( int počet, StringBuffer sb )
    {
        while( délkaBloku < počet )
        {
            sb.append( mezery );
            počet -= délkaBloku;
        }
        if( počet > 0 )
            sb.append( mezery.substring( délkaBloku - počet ) );
    }
    
    
    
    
//== VNOŘENÉ A VNITŘNÍ TŘÍDY ===================================================
//== TESTY A METODA MAIN =======================================================

    public static void test( int n )
    {
        System.out.println( new Pascal_14c( n ) );
    }
    
    public static void test6()
    {
        test( 6 );
    }
}

