package rup.česky.tvary_3;

/*******************************************************************************
 * Třída pro prací s trojúhelníkem komunikujícím s aktivním plátnem.
 *
 * Oproti stejnojmenné třídě z projektu
 * 06_Rozhraní se změnilo pouze implementované rozhraní.
 *
 * @author     Rudolf Pecinovský
 * @version    2.01, duben 2004
 */
public class Trojúhelník extends Hýbací implements IHýbací
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    /** Počáteční barva nakreslené instance v případě,
     *  kdy uživatel žádnou požadovanou barvu nezadá -
     *  pro trojúhelník Barva.ZELENÁ. */
    public static final Barva IMPLICITNÍ_BARVA = Barva.ZELENÁ;

    /** Počáteční barva nakresleného trojúhelníku v případě,
     *  kdy uživatel žádnou požadovanou barvu nezadá.    */
    public static final Směr8 IMPLICITNÍ_SMĚR = Směr8.SEVER;



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

    private Barva  barva;   //Barva instance
    private Směr8  směr;    //Směr, do nějž je otočen vrchol trojúhelníku



//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ METODY TŘÍDY ======================================================

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

    /***************************************************************************
     * Vytvoří novou instanci s implicitními rozměry, umístěním, barvou
     * a natočením.
     * Instance bude umístěna v levém horním rohu plátna
     * a bude mít implicitní barvu,
     * výšku 1 pole, šířku 2 pole a bude natočena vrocholem na sever.
     */
    public Trojúhelník()
    {
        this( 0, 0, 2*AP.getKrok(), AP.getKrok() );
    }


    /***************************************************************************
     * Vytvoří novou instanci se zadanou polohou a rozměry
     * a implicitní barvou a směrem natočení.
     *
     * @param x       x-ová souřadnice počátku, x>=0, x=0 má levý okraj plátna
     * @param y       y-ová souřadnice počátku, y>=0, y=0 má horní okraj plátna
     * @param šířka   šířka vytvářené instance,  šířka > 0
     * @param výška   výška vytvářené instance,  výška > 0
     */
    public Trojúhelník( int x, int y, int šířka, int výška )
    {
        this( x, y, šířka, výška, IMPLICITNÍ_BARVA, IMPLICITNÍ_SMĚR );
    }


    /***************************************************************************
     * Vytvoří novou instanci se zadanou polohou, rozměry a směrem natočení
     * a s implicitní barvou.
     *
     * @param x       x-ová souřadnice, x>=0, x=0 má levý okraj plátna
     * @param y       y-ová souřadnice, y>=0, y=0 má horní okraj plátna
     * @param šířka   šířka instance,  šířka > 0
     * @param výška   výška instance,  výška > 0
     * @param směr    Směr, do nějž bude natočen vrchol trojúhelníku -
     *                je třeba zadat některou z instancí třídy Směr8
     */
    public Trojúhelník( int x, int y, int šířka, int výška, Směr8 směr )
    {
        this( x, y, šířka, výška, IMPLICITNÍ_BARVA, směr );
    }


    /***************************************************************************
     * Vytvoří novou instanci se zadanými rozměry, polohou a barvou.
     * Směr natočení bude implicitní, tj. na sever.
     *
     * @param x       x-ová souřadnice instance, x>=0, x=0 má levý okraj plátna
     * @param y       y-ová souřadnice instance, y>=0, y=0 má horní okraj plátna
     * @param šířka   šířka vytvářené instance,  šířka > 0
     * @param výška   výška vytvářené instance,  výška > 0
     * @param barva   Barva vytvářené instance
     */
    public Trojúhelník( int x, int y, int šířka, int výška, Barva barva )
    {
        this( x, y, šířka, výška, barva, IMPLICITNÍ_SMĚR );
    }


    /***************************************************************************
     * Vytvoří novou instanci se zadanou polohou a rozměry, barvou a měrem.
     *
     * @param pozice  Pozice vytvářené instance
     * @param rozměr  Rozměr vytvářené instance
     * @param barva   Barva vytvářené instance
     * @param směr    Směr, do nějž je natočen vrchol trojúhelníku -
     *                je třeba zadat některou z instancí třídy Směr8
     */
    public Trojúhelník( Pozice pozice, Rozměr rozměr, Barva barva, Směr8 směr )
    {
        this( pozice.x, pozice.y, rozměr.šířka, rozměr.výška, barva, směr );
    }


    /***************************************************************************
     * Vytvoří novou instanci v zadané oblasti a se zadanou barvou.
     *
     * @param oblast  Oblast, v níž se má instance vytvořit
     * @param barva   Barva vytvářené instance
     * @param směr    Směr, do nějž je natočen vrchol trojúhelníku -
     *                je třeba zadat některou z instancí třídy Směr8
     */
    public Trojúhelník( Oblast oblast, Barva barva, Směr8 směr )
    {
        this( oblast.x, oblast.y, oblast.šířka, oblast.výška, barva, směr );
    }


    /***************************************************************************
     * Vytvoří novou instanci se zadanými rozměry, polohou, barvou,
     * i směrem natočení.
     *
     * @param x       x-ová souřadnice instance, x>=0, x=0 má levý okraj plátna
     * @param y       y-ová souřadnice instance, y>=0, y=0 má horní okraj plátna
     * @param šířka   šířka vytvářené instance,  šířka > 0
     * @param výška   výška vytvářené instance,  výška > 0
     * @param barva   Barva vytvářené instance
     * @param směr    Směr, do nějž bude natočen vrchol trojúhelníku -
     *                je třeba zadat některou z instancí třídy Směr8
     */
    public Trojúhelník( int x, int y, int šířka, int výška, Barva barva, Směr8 směr )
    {
        super( x, y, šířka, výška );
        this.barva = barva;
        this.směr  = směr;
    }



//== PŘÍSTUPOVÉ METODY ATRIBUTU INSTANCÍ =======================================

    /***************************************************************************
     * Vrátí barvu instance.
     *
     * @return  Instance třídy Barva definující nastavenou barvu.
     */
    public Barva getBarva()
    {
        return barva;
    }


    /***************************************************************************
     * Nastaví novou barvu instance.
     *
     * @param nová   Požadovaná nová barva.
     */
    public void setBarva(Barva nová)
    {
        barva = nová;
        AP.překresli();
    }


    /***************************************************************************
     * Vrátí směr instance. tj. směr, co nějž je otočen vrchol.
     *
     * @return  Instance třídy Směr8 definující nastavený směr.
     */
    public Směr8 getSměr()
    {
        return směr;
    }


    /***************************************************************************
     * Nastaví nový směr instance.
     *
     * @param nový  Požadovaný nový směr.
     */
    public void setSměr(Směr8 nový)
    {
        směr = nový;
        AP.překresli();
    }



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

    /***************************************************************************
     * Za pomoci dodaného kreslítka vykreslí obraz své instance
     * na animační plátno.
     *
     * @param kreslítko   Kreslítko, kterým se instance nakreslí na plátno.
     */
    public void nakresli( Kreslítko kreslítko )
    {
        int[][] points = getVrcholy();
        kreslítko.vyplňPolygon( points[0], points[1], barva );
    }



//== PŘEKRYTÉ ABSTRAKTNÍ METODY RODIČOVSKÉ TŘÍDY ===============================
//== PŘEKRYTÉ KONKRÉTNÍ METODY RODIČOVSKÉ TŘÍDY ================================

    /***************************************************************************
     * Převede instanci na řetězec. Používá se především při ladění.
     *
     * @return Řetězcová reprezentace dané instance.
     */
    public String toString()
    {
        return super.toString() + ", barva=" + barva + ", směr=" + směr;
    }



//== NOVĚ ZAVEDENÉ METODY INSTANCÍ =============================================
//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================

    /***************************************************************************
     * Vrátí matici se souřadnicemi vrcholů daného trojúhelníku.
     *
     * @return Požadovaná matice
     */
    private int[][] getVrcholy()
    {
        int[] x = null;
        int[] y = null;

        //Volám rodičovskou verzi metody, abych měl jistotu, co se zavolá,
        //a aby se při překrytí některé z použitých metod
        //nezavolalo něco jiného, co může vráti pro mne nevhodnou hodnotu.
        int gx = super.getX();
        int gy = super.getY();
        int gš = super.getŠířka();
        int gv = super.getVýška();

        switch( směr )
        {
            case VÝCHOD:
                x = new int[]{ gx, gx+gš,     gx    };
                y = new int[]{ gy, gy+(gv/2), gy+gv };
                break;

            case SEVEROVÝCHOD:
                x = new int[]{ gx, gx+gš, gx+gš };
                y = new int[]{ gy, gy,    gy+gv };
                break;

            case SEVER:
                x = new int[]{ gx,    gx+(gš/2), gx+gš };
                y = new int[]{ gy+gv, gy,        gy+gv };
                break;

            case SEVEROZÁPAD:
                x = new int[]{ gx,    gx, gx+gš };
                y = new int[]{ gy+gv, gy, gy    };
                break;

            case ZÁPAD:
                x = new int[]{ gx,        gx+gš, gx+gš };
                y = new int[]{ gy+(gv/2), gy,    gy+gv };
                break;

            case JIHOZÁPAD:
                x = new int[]{ gx, gx,    gx+gš };
                y = new int[]{ gy, gy+gv, gy+gv };
                break;

            case JIH:
                x = new int[]{ gx, gx+(gš/2), gx+gš };
                y = new int[]{ gy, gy+gv,     gy    };
                break;

            case JIHOVÝCHOD:
                x = new int[]{ gx,    gx+gš, gx+gš };
                y = new int[]{ gy+gv, gy+gv, gy    };
                break;

            default:
                throw new IllegalStateException(
                    "Instance ukazuje do nedefinovaného směru" );
        }
        return new int[][] { x, y };
    }



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



