import java.util.Timer;
import java.util.TimerTask;

import rup.česky.tvary.AktivníPlátno;
import rup.česky.tvary.Barva;


/*******************************************************************************
 * Třída realizuje několikamístný displej ze sedmisegmentových číslic.
 * Při vytváření displeje můžeme zadat počet číslic, velikost modulu
 * určujícícho výslednou velikost číslic, barvu pozadí a barvu číslic.
 * <p>
 * Třída nabízí jedinou metodu, která je určena k vykreslenízadaného čísla
 * na vytvořeném displeji.
 *
 * @author Rudolf Pecinovský
 */
public class Displej
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    static final AktivníPlátno AP = AktivníPlátno.getPlátno();
    
    
    
//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================

    /** Počet číslic zobrazovaných displejem. */
    final int ČÍSLIC;   //Počet číslic displeje

    /** Šířka segmentu v bodech. */
    final int MODUL;    
    
    /** Délka segmentu bez krajích trojúhelníků jako násobek jeho šířky. */
    final int DÉLKA;
    
    /** Barva popředí, tj. barva svítících sebmentů. */
    final Barva POPŘEDÍ;
    
    /** Barva pozadí a zhasnutých segmentů. */
    final Barva POZADÍ; 
    
    /** Základ číselné soutavy, ve které display zobrazuje. */
    final int SOUSTAVA;  
    
    /** Maximálně zobrazitelné číslo. */
    final int MAX;
    
    /** Šířka jedné zobrazované číslice v bodech. */
    final int ŠÍŘKA_ČÍSLICE;

    /** Jednotlivé zobrazované číslice = oblasti na displeji. */
    private final Číslice[] číslice;



//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ METODY TŘÍDY ======================================================

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

    /***************************************************************************
     * Vytvoří displej o zadaném počtu sedmisegmentových číslic s definovanou
     * barvou pozadí a popředí. Upraví rozměry plátna tak, aby právě pojalo
     * požadovaný displej se zadanou velikostí modulu.
     *
     * @param číslic   Počet číslic displeje.
     * @param modul    Bodová velikost bloků, z nichž jsou vytvořena segmenty,
     *                 Velikost modulu je současně šířkou segmentů.
     * @param délka    Délka těla segmentu bez okrajových trojůhelníků
     *                 zadaná jako násobek jeho šířky (=velikosti modulu).
     * @param podklad  Barva pozadí.
     * @param znaky    Barva popředí.
     * @param soustava Číselná soustava, ve které bude displej
     *                 zobrazovat zadané hodnoty.
     */
    public Displej( int číslic, int modul, int délka, 
                    Barva podklad, Barva znaky, int soustava)
    {
        this.ČÍSLIC   = číslic;
        this.MODUL    = modul;
        this.DÉLKA    = délka;
        this.POPŘEDÍ  = znaky;
        this.POZADÍ   = podklad;
        this.SOUSTAVA = soustava;
        ŠÍŘKA_ČÍSLICE = MODUL * (2 + DÉLKA);
        
        int max = 1;
        for( int i=číslic;   i-- > 0;   max = soustava*max );
        this.MAX = max-1;
        
        AP.setKrokRozměr(MODUL, ČÍSLIC*(DÉLKA + 3)-1, 2*DÉLKA + 3);
        AP.setBarvaPozadí(podklad);
        AP.setMřížka(false);
        
        Segment.nastavKonstanty( MODUL, DÉLKA, POPŘEDÍ, POZADÍ );
        číslice = new Číslice[číslic];
        for( int i=0;   i < číslic;   i++ )
            číslice[i] = new Číslice( i*(ŠÍŘKA_ČÍSLICE+MODUL), 0 );
    }



//== PŘÍSTUPOVÉ METODY ATRIBUTU INSTANCÍ =======================================
//== PŘEKRYTÉ METODY IMPLEMENTOVANÝCH ROZHRANÍ =================================
//== PŘEKRYTÉ ABSTRAKTNÍ METODY RODIČOVSKÉ TŘÍDY ===============================
//== OSTATNÍ PŘEKRYTÉ METODY RODIČOVSKÉ TŘÍDY ==================================
//== OSTATNÍ METODY INSTANCÍ ===================================================

    /***************************************************************************
     * Zobrazí zadané číslo na dipleji. Má-li číslo menší počet číslic,
     * než kolik je míst na displeji, zobrazí se před ním vedoucí nuly.
     *
     * @param číslo  Zobrazené číslo.
     */
    public void zobraz( int číslo )
    {
        if( (číslo < 0)  ||  (MAX < číslo) )
            throw new IllegalArgumentException(
                "\nDislej zobrazuje pouze čísla od 0 do " + MAX + 
                ", zadáno číslo " + číslo );
        
        AP.nekresli();
    ČÍSLICE:
        for( int i=ČÍSLIC;   --i >= 0;  )
        {
            int zobrazit = číslo % SOUSTAVA;
            číslice[i].zobraz(zobrazit );
            číslo /= SOUSTAVA;
            if( číslo == 0 )
            {
                for( int j=i-1;   j >= 0;   j--)
                    číslice[j].zhasni();
                break ČÍSLICE;
            }
        }
        AP.vraťKresli();
    }


    /***************************************************************************
     * Zhasne displej -- plátno bude pokryto pouze barvou pozadí.
     *
     * @param číslo  Zobrazené číslo.
     */
    public void zhasni()
    {
        AP.nekresli();
            for( int i=ČÍSLIC;   --i >= 0;   )
            {
                číslice[i].zhasni();
            }
        AP.vraťKresli();
    }



//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== VNOŘENÉ A VNITŘNÍ TŘÍDY ===================================================
//== TESTY A METODA MAIN =======================================================
}

