import rup.česky.tvary.AktivníPlátno;
import rup.česky.tvary.IKreslený;
import rup.česky.tvary.Kreslítko;
import rup.česky.tvary.Obdélník;
import rup.česky.tvary.Trojúhelník;
import rup.česky.tvary.Barva;
import rup.česky.tvary.Směr8;


/*******************************************************************************
 * Instance třídy Segment představují jednotlivé segmenty sedmisegmentového 
 * displeje pro zobrazení číslic.
 *
 * @author Rudolf Pecinovský
 */
public class Segment implements IKreslený
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================
    
    /***************************************************************************
     * Parametry jednotlivých segmetů:                                    0
     * 0. index: vodorovná políčková souřadnice v rámci číslice         1   2
     * 1. index: svislá políčková souřadnice v rámci číslice              3
     * 3. index: příznak vodorovnosti (0=vodorovný, 1=svislý)           4   5
     *                                                                    6
     */
    private static final int[][] param = 
        { {0,0,0}, {0,0,1}, {1,0,1}, {0,1,0}, {0,1,1}, {1,1,1}, {0,2,0} };
        //  V-H     S-H-L    S-H-R     V-S     S-D-L    S-D-R     V-D
        
        

//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================

    /** ířka segmentu v bodech - Modul. */
    private static int M;
    
    /** Délka segmentu bez krajích trojúhelníků jako násobek jeho ířky. */
    private static int D;
    
    /** Celková (Totátlní) délka segmentu, tj. délka včetně krajních 
     *  trojúhelníků jako násobek ířky segmentu. */
    private static int T;
    
    /** Polovina ířky segmentu v bodech (= výka trojúhelníků). */
    private static int P;
    
    /** Barva popředí = barva svítících segmetnů. */
    private static Barva A;
    
    /** Barva pozadí = počáteční barva segmentů + barva zhasnutých segmentů. */
    private static Barva Z;
    
    
    
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================

    /** Levá nebo horní pička. */
    private final Trojúhelník pičkaLH;
    
    /** Tělo segmentu. */
    private final Obdélník tělo;    
    
    /** Pravá nebo dolní pička. */
    private final Trojúhelník pičkaRD; 
    
    
    
//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
    
    private boolean svítí = false;
    
    
    
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ METODY TŘÍDY ======================================================
    
    /***************************************************************************
     * Nastaví hodnoty konstant, s jejich pomocí se budou vypočítávat
     * pozice a rozměnry vytvářených segmetnů.
     */
    static void nastavKonstanty( int modul, int délka, 
                                 Barva popředí, Barva pozadí )
    {
        M = modul;
        P = modul / 2;
        D = délka * M;
        T = M + D;
        A = popředí;
        Z = pozadí;
    }

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

    /***************************************************************************
     * Vytvoří na zadané políčkové souřadnici segment 
     * se zadanou orientací, modulem a počáteční barvou.
     *
     * @param i   Index segmentu.
     * @param x0  Vodorovná políčková souřadnice počátku bloku..
     * @param y0  Svislá políčková souřadnice počátku bloku.
     */
    private Segment( int i, int x0, int y0 )
    {
        int x = x0 + T*param[i][0];
        int y = y0 + T*param[i][1]; 
        
        if( param[i][2] == 0 )  //vodorovný
        {
            pičkaLH = new Trojúhelník( x+P, y, P, M, Z, Směr8.ZÁPAD );
            tělo     = new Obdélník   ( x+M, y, D, M, Z              );
            pičkaRD = new Trojúhelník( x+T, y, P, M, Z, Směr8.VÝCHOD);
        }
        else //svislý
        {    
            pičkaLH = new Trojúhelník( x, y+P, M, P, Z, Směr8.SEVER );
            tělo     = new Obdélník   ( x, y+M, M, D, Z              );
            pičkaRD = new Trojúhelník( x, y+T, M, P, Z, Směr8.JIH   );
        }
        AktivníPlátno.getPlátno().přidej( this );
    }
    
    

    /***************************************************************************
     * Tovární metoda, která vrátí kompletní sedmici segmentů
     * pro číslici sedmisegmentového displeje na zadané pozici.
     *
     * @param mm  Velikost modulu v bodech.
     * @param xp  Vodorovná políčková souřadnice.
     * @param yp  Svislá políčková souřadnice.
     * @param b   Barva segmentu.
     */
    public static Segment[] getSedmička( int x0, int y0 )
    {
        Segment[] sedmička = new Segment[7];
        for( int i=0;   i < 7;   i++)
            sedmička[i] = new Segment( i, x0, y0 );
        return sedmička;
    }
    
    
//== ABSTRAKTNÍ METODY =========================================================
//== PŘÍSTUPOVÉ METODY ATRIBUTU INSTANCÍ =======================================

    /***************************************************************************
     * Podle hodnoty parametr segmen tozsvítí, tj. nastaví mu barvu poředí,
     * nebo zhasne, tj. nastaví mu barvu pozadí. 
     * Pokud segment poadovanou barvu ji má, neudělá nic.
     *
     * @param rozsvítit   Zda segmentu nastavit barvu popředí.
     */
    public void setBarva( boolean rozsvítit )
    {
        if( rozsvítit == svítí )   
            return;   //================>

        svítí = ! svítí;
        Barva b = svítí ? A : Z;
        pičkaLH.setBarva(b);
        tělo    .setBarva(b);
        pičkaRD.setBarva(b);
    }


    
//== PŘEKRYTÉ METODY IMPLEMENTOVANÝCH ROZHRANÍ =================================

    /***************************************************************************
     * Nakreslí segment za pomoci dodaného kreslítka.
     * 
     * @param g  Kreslítko.
     */
    public void nakresli( Kreslítko kr )
{
        pičkaLH.nakresli( kr );
        tělo    .nakresli( kr );
        pičkaRD.nakresli( kr );
    }



//== PŘEKRYTÉ ABSTRAKTNÍ METODY RODIČOVSKÉ TŘÍDY ===============================
//== OSTATNÍ PŘEKRYTÉ METODY RODIČOVSKÉ TŘÍDY ==================================
//== OSTATNÍ METODY INSTANCÍ ===================================================
//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== VNOŘENÉ A VNITŘNÍ TŘÍDY ===================================================
//== TESTY A METODA MAIN =======================================================
}

