/*******************************************************************************
 * Třída Strom_3c obsahuje podobu třídy po zavedení komentářů.
 *
 * Oproti verzi Strom_3b je zdrojový kód pouze okomentován
 * a jednotlivé metody jsou seřazeny do sekcí definovaných řádkovými komentáři.
 *
 * Obsahuje dokumentační komentáře všech veřejných atributů a metod.
 *
 * @author     Rudolf Pecinovský
 * @version    2.01, duben 2004
 */
public class Strom_3c
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    /** Udává, kolikrát je strom vyšší než samotný kmen. */
    public static final int IMPLICITNÍ_POMĚR_VÝŠKY =  3;

    /** Udává, kolikrát je koruna širší než kmen. */
    public static final int IMPLICITNÍ_POMĚR_ŠÍŘKY = 10;



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

    /** Velikost posunu pro bezparametrické posunové metody. */
    private static int krok = 50;



//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================

    private final Elipsa   koruna;   //Koruna stromu
    private final Obdélník kmen;     //Kmen stromu



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

    /***************************************************************************
     * Vrátí velikost implicitního kroku, o který se instance přesune
     * při volaní bezparametrickych metod přesunu.
     *
     * @return Velikost implicitního kroku v bodech
     */
     public static int getKrok()
     {
         return krok;
     }


    /***************************************************************************
     * Nastaví velikost implicitního kroku, o který se instance přesune
     * při volaní bezparametrickych metod přesunu.
     *
     * @param velikost  Velikost implicitního kroku v bodech;<br/>
     *                  musí platit:  0 <= velikost <= 100
     */
    public static void setKrok( int velikost )
    {
        krok = velikost;
    }


    /***************************************************************************
     * Metoda se dotáže uživatele na požadovanou velikost kroku používaného
     * v bezparametrických posunových metodách a zadanou hodnotu nastaví.
     */
    public static void setKrok()
    {
        krok = P.zadej( "Zadejte novou velikost kroku:", krok );
    }



//== OSTATNÍ METODY TŘÍDY ======================================================

    /***************************************************************************
     * Vytvoří instanci zadané velikosti a upraví rozměr plátna tak,
     * aby byla na plátně právě zarámovaná.
     *
     * @param šířka   Šířka stromu, který chceme vytvořit a zarámovat.
     * @param výška   Výška stromu, který chceme vytvořit a zarámovat.
     */
    public static void zarámuj( int šířka, int výška )
    {
        Plátno.getPlátno().setRozměr( šířka, výška );
        new Strom_3c( 0, 0, šířka, výška );
    }


    /***************************************************************************
     * Metoda upraví rozměr plátna a "vysadí" na něj alej dvou řad stromů
     * se třemi stromy v každé řadě. Stromy budou vysazeny šikmo ve směru
     * hlavní diagonály s kmenem zabírajícím 1/3 výšky a 1/10 šířky stromu.
     */
    public static void alej()
    {
        Plátno.getPlátno().setRozměr( 400, 350 );
        new Strom_3c( 100,   0 );      new Strom_3c( 300,   0 );
        new Strom_3c(  50, 100 );      new Strom_3c( 250, 100 );
        new Strom_3c(   0, 200 );      new Strom_3c( 200, 200 );
    }



//== KONSTRUKTORY ==============================================================

    /***************************************************************************
     * Implicitní konstruktor třídy Strom_3c vytvoří v levém horním rohu plátna
     * instanci širokou 100 bodů, vysokou 150 bodů
     * s kmenem zabírajícím 1/3 výška a 1/10 šířky stromu.
     */
    public Strom_3c()
    {
        this( 0, 0 );
    }


    /***************************************************************************
     * Vytvoří na zadaných souřadnicích
     * instanci širokou 100 bodů, vysokou 150 bodů
     * s kmenem zabírajícím 1/3 výška a 1/10 šířky stromu.
     *
     * @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
     */
    public Strom_3c( int x, int y )
    {
        this( x, y, 100, 150 );
    }


    /***************************************************************************
     * Vytvoří na zadaných souřadnicích instanci se zadanou šířkou a výškou.
     * Poměr velikosti kmene ku zbytku stromu zůstane implicitní, tj.
     * kmen bude zabírat 1/3 výška a 1/10 šířky stromu.
     *
     * @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 Strom_3c( int x, int y, int šířka, int výška )
    {
        this( x, y, šířka, výška,
            IMPLICITNÍ_POMĚR_ŠÍŘKY, IMPLICITNÍ_POMĚR_VÝŠKY );
    }


    /***************************************************************************
     * Vytvoří na zadaných souřadnicích instanci se zadanou šířkou, výškou.
     * a poměrem velikosti kmene ku zbytku stromu.
     *
     * @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
     * @param podílVýškyKmene  Kolikrát je kmen menší než celý strom
     * @param podílŠířkyKmene  Kolikrát je kmen užší než celý strom
     */
    public Strom_3c( int x, int y, int šířka, int výška,
                  int podílŠířkyKmene, int podílVýškyKmene )
    {
        int výškaKmene  = výška / podílVýškyKmene;
        int výškaKoruny = výška - výškaKmene;
        int šířkaKmene  = šířka / podílŠířkyKmene;
        int posunKmene  = ( šířka - šířkaKmene) / 2;
        koruna = new Elipsa  ( x, y, šířka, výškaKoruny, Barva.ZELENÁ  );
        kmen   = new Obdélník( x+posunKmene, y+výškaKoruny,
                               šířkaKmene, výškaKmene, Barva.HNĚDÁ );
    }



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

    /***************************************************************************
     * Vrátí x-ovou souřadnici pozice instance.
     *
     * @return  x-ová souřadnice.
     */
    public int getX()
    {
        return koruna.getX();
    }


    /***************************************************************************
     * Vrátí y-ovou souřadnici pozice instance.
     *
     * @return  y-ová souřadnice.
     */
    public int getY()
    {
        return koruna.getY();
    }


    /***************************************************************************
     * Nastaví novou pozici instance.
     *
     * @param x   Nová x-ová pozice instance
     * @param y   Nová y-ová pozice instance
     */
    public void setPozice(int x, int y)
    {
        koruna.setPozice( x, y );
        kmen  .setPozice( x  +  (koruna.getŠířka() - kmen.getŠířka()) / 2,
                          y  +  koruna.getVýška()     );
        koruna.nakresli();
    }


    /***************************************************************************
     * Vrátí šířku instance.
     *
     * @return  Šířka instance v bodech
     */
    public int getŠířka()
    {
        return koruna.getŠířka();
    }


    /***************************************************************************
     * Vrátí výšku instance.
     *
     * @return  Výška instance v bodech
     */
    public int getVýška()
    {
        return koruna.getVýška() + kmen.getVýška();
    }


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


    /***************************************************************************
     * Nastaví novou barvu koruny.
     *
     * @param nová  Požadovaná nová barva.
     */
    public void setBarvaKoruny( Barva nová )
    {
        koruna.setBarva( nová );
    }



//== OSTATNÍ METODY INSTANCÍ ===================================================

    /***************************************************************************
     * Vykreslí obraz své instance na plátno.
     */
    public void nakresli()
    {
        koruna.nakresli();
        kmen  .nakresli();
    }


    /***************************************************************************
     * Smaže obraz své instance z plátna (nakreslí ji barvou pozadí plátna).
     */
    public void smaž()
    {
        koruna.smaž();
        kmen  .smaž();
    }


    /***************************************************************************
     * Přesune instanci o zadaný počet bodů vpravo,
     * při záporné hodnotě parametru vlevo.
     *
     * @param vzdálenost Vzdálenost, o kterou se instance přesune.
     */
    public void posunVpravo( int vzdálenost )
    {
        koruna.posunVpravo( vzdálenost );
        kmen  .posunVpravo( vzdálenost );
    }


    /***************************************************************************
     * Přesune instanci o krok bodů vpravo.
     */
    public void posunVpravo()
    {
        posunVpravo( krok );
    }


    /***************************************************************************
     * Přesune instanci o krok bodů vlevo.
     */
    public void posunVlevo()
    {
        posunVpravo( -krok );
    }


    /***************************************************************************
     * Přesune instanci o zadaný počet bodů dolů,
     * při záporné hodnotě parametru nahoru.
     *
     * @param vzdálenost   Počet bodů, o které se instance přesune.
     */
    public void posunDolů( int vzdálenost )
    {
        koruna.posunDolů( vzdálenost );
        kmen  .posunDolů( vzdálenost );
        koruna.nakresli();
    }


    /***************************************************************************
     * Přesune instanci o krok bodů dolů.
     */
    public void posunDolů()
    {
        posunDolů( krok );
    }


    /***************************************************************************
     * Přesune instanci o krok bodů nahoru.
     */
    public void posunVzhůru()
    {
        posunDolů( -krok );
    }


    /***************************************************************************
     * Nastaví parametry okna s plátnem tak, aby právě zarámovalo danou
     * instanci. Instanci před tím přesune do levého horního rohu plátna.
     */
    public void zarámuj()
    {
        Plátno.getPlátno().setRozměr( getŠířka(), getVýška() );
        setPozice( 0, 0 );
    }



}

