/**
 * Trida Smrk slouzi k vyuce zakladu prace se zdrojovym kodem.
 * Je soucasti projektu Tvary, jenz je startovacim projektem 
 * kurzu objektove orientovaneho programovani.
 *
 * @author     Rudolf Pecinovsky
 * @version    1.07, 3.1.2003
 */
public class Smrk
{
//== VEREJNE KONSTANTY =========================================================

    public static final String BARVA_0 = "zelena";


//== SOUKROME KONSTANTY ========================================================
//== ATRIBUTY TRIDY ============================================================

    private static int krok = 50;
    
    
//== ATRIBUTY INSTANCI =========================================================

    public Trojuhelnik horni;
    private Trojuhelnik stredni;
    private Trojuhelnik dolni;


//== PRISTUPOVE METODY ATRIBUTU TRIDY ==========================================

    /**
     * Vraci velikost kroku, o kterou se posune obrazek smrku
     * pri volani bezparametrickych posunovych metod.
     *
     * @return   velikost kroku v bodech
     */
    public static int getKrok() 
    {   
        return krok;
    }//public static int getKrok() 
        

    /**
     * Nastavi novou velikost kroku, o kterou se posune obrazek 
     * smrku pri volani bezparametrickych posunovych metod.
     *
     * @param krok  nastavovana velikost kroku v bodech
     */
    public static void setKrok( int krok ) 
    {   //Atribut krok kvalifikujeme názvem tridy
        Smrk.krok = krok;
    }//public static void setKrok( int krok )
        

//== OSTATNI METODY TRIDY ======================================================

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

    /**
     * Konstruktor pro objekty tridy Smrk, ktery umozni nastavit
     * souradnice a rozmery vytvareneho obrazce.
     * Souradnicemi objektu se pritom rozumi souradnice
     * leveho horniho rohu opsaneho obdelniku.
     *
     * @param x   x-ova souradnice, x>=0, x=0 ma levy okraj platna
     * @param y   y-ova souradnice, y>=0, y=0 ma horni okraj platna
     * @param sirka   sirka opsaneho obdelniku,  sirka > 0
     * @param vyska   vyska opsaneho obdelniku,  vyska > 0
     * @param c barva trojuhelniku - povolene hodnoty jsou:
     *          "cerna",  "modra",     "cervena", "fialova",
     *          "zelena", "blankytna", "zluta",   "bila".
     *          Barvu je take mozno zadat pomoci hexadecimalnich
     *          hodnot jednotlivych slozek ve tvaru "RGB:rrggbb"  
     *          nebo  "ARGB:aarrggbb"  -- viz dokumentace metody 
     *          Platno.prevedBarva(String nazevBarvy)
     */
    public Smrk( int x, int y, int sirka, int vyska, String barva )
    {
        horni = new Trojuhelnik( x+sirka/5,  y,          3*sirka/5, 3*vyska/7, barva );
        stredni=new Trojuhelnik( x+sirka/10, y+vyska/7,  4*sirka/5, 4*vyska/7, barva );
        dolni = new Trojuhelnik( x,          y+2*vyska/7,  sirka,   5*vyska/7, barva );
    }//public Smrk( int x, int y, int sirka, int vyska, String Barva )


    /**
     * Konstruktor pro objekty tridy Smrk, ktery umozni nastavit
     * souradnice a rozmery vytvareneho obrazce.
     * Souradnicemi objektu se pritom rozumi souradnice
     * leveho horniho rohu opsaneho obdelniku.
     *
     * @param x   x-ova souradnice, x>=0, x=0 ma levy okraj platna
     * @param y   y-ova souradnice, y>=0, y=0 ma horni okraj platna
     * @param sirka   sirka opsaneho obdelniku,  sirka > 0
     * @param vyska   vyska opsaneho obdelniku,  vyska > 0
     */
    public Smrk( int x, int y, int sirka, int vyska )
    {
        this( x, y, 50, 70, BARVA_0 );
    }//public Smrk( int x, int y, int sirka, int vyska )


    /**
     * Konstruktor pro objekty tridy Smrk, ktery umi nastavit
     * pocatecni pozici objektu. Velikost je implicitni.
     * Souradnicemi objektu se pritom rozumi souradnice
     * leveho horniho rohu opsanohu ctverce.
     *
     * @param x   x-ova souradnice, x>=0, x=0 ma levy okraj platna
     * @param y   y-ova souradnice, y>=0, y=0 ma horni okraj platna
     */
    public Smrk( int x, int y )
    {
        this( x, y, 50, 70 );
    }//public Smrk( int x, int y )


    /**
     * Bezparametricky konstruktor pro objekty tridy Smrk.
     * Nakresli objekt standardni velikosti se souradnicemi [0;0].
     */
    public Smrk()
    {
        this( 0, 0, 50, 70 );
    }//public Smrk()


//== PRISTUPOVE METODY ATRIBUTU INSTANCI =======================================

    /**
     * Vraci x-vou souradnici celeho smrku.
     *
     * @return  x-ova souradnice smrku
     */
    public int getX() 
    {   //x-ova souradnice spodniho trojuhelniku
        //je zaroven x-vou souradnici celeho smrku
        return dolni.getX();
    }//public int getX() 
        
        
    /**
     * Vraci y-ovou souradnici celeho smrku.
     *
     * @return  y-ova souradnice smrku
     */
    public int getY() 
    {   //y-ova souradnice horniho trojuhelniku
        //je zaroven y-ovou souradnici celeho smrku
        return horni.getY();
    }//public int getY() 
        
        
    /**
     * Nastavi novou pozici stromku na platne.
     *
     * @param x  nova x-ova souradnice smrku
     * @param y  nova y-ova souradnice smrku
     */
    public void setPozice( int x, int y ) 
    {   
        //Pripravime si casto pouzivane hodnoty
        int x0 = getX();
        int y0 = getY();

        //Protoze se velikost stromku nezvetsila, muzeme za posuny 
        //jednotlivych trojuhelniku od leveho horniho rohu smrku
        //jedoduse dosadit jejich stavajici posuny
        horni.setPozice  ( x + horni.getX()  -x0,  y                     );
        stredni.setPozice( x + stredni.getX()-x0,  y + stredni.getY()-y0 ); 
        dolni.setPozice  ( x + dolni.getX()  -x0,  y + dolni.getY()  -y0 ); 

        //Pri odmazavani nekterych dilu se muze umazat kus jinych
        kresli();       //Radeji vse prekreslime
    }//public void getY( int x, int y ) 
    
    
    /**
     * Vrati sirku celeho obrazce.
     *
     * @return  sirka smrku
     */
    public int getSirka() 
    {   //Sirka spodniho trojuhelniku je zaroven sirkou celeho stromku
        return dolni.getSirka();
    }//public int getSirka() 


    /**
     * Vrati vysku celeho obrazce.
     *
     * @return   vyska smrku
     */
    public int getVyska() 
    {   //Vysku spoctu jako rozdil y-ovych souradnic 
        //spicky a spodni hrany smrku
        return dolni.getY()+dolni.getVyska() - horni.getY();
    }//public int getVyska() 
        
        
    /**
     * Nastavi novy rozmer stromku na platne.
     *
     * @param s  nova sirka smrku
     * @param v  nova vyska smrku
     */
    public void setRozmer( int s, int v ) 
    {   
        //Zmenou velikosti celeho smrku se meni i pozice
        //jeho jednotlivych casti - je treba nastavit obe
        //Pri nastavovani muzeme vyjit z definice kontruktoru
        
        //Pripravime si casto pocitane vyrazy
        int s5 = s/5;   
        int v7 = v/7;
        int x = getX();
        int y = getY();
        
        //Spocteme a nastavime novou pozici jednotlivych casti
        horni.setPozice  ( x + s5,   y );
        stredni.setPozice( x + s/10, y + v7 ); 
        dolni.setPozice  ( x,        y + v7*2 );
        
        //Spocteme a nastavime definitivni podobu casti
        horni.setRozmer  ( 3 * s5,   3 * v7 );
        stredni.setRozmer( 4 * s5,   4 * v7 );
        dolni.setRozmer  (     s,    5 * v7 );
        
        //Pri odmazavani nekterych dilu se muze umazat kus jinych
        kresli();       //Radeji vse prekreslime
    }//public void setRozmer( int s, int w )


    /**
     * Vraci aktualni barvu smrku.
     *
     * @return  barva smrku
     */
    public String getBarva() 
    {   
        return dolni.getBarva();
    }//public String getBarva()
        

    /**
     * Nastavi aktualni barvu smrku.
     *
     * @param barva nastavovana barva
     */
    public void setBarva( String barva ) 
    {   
        dolni.setBarva( barva );
        stredni.setBarva( barva );
        horni.setBarva( barva );
    }//public void setBarva( String barva )
        

//== OSTATNI METODY INSTANCI ===================================================

    /**
     * Nakresli obrazek smrku na platno.
     */
    public void kresli()
    {
        horni.kresli();
        stredni.kresli();
        dolni.kresli();
    }//public void kresli()


    /**
     * Smaze obrazek smrku na platne.
     */
    public void smaz()
    {
        horni.smaz();
        stredni.smaz();
        dolni.smaz();
    }//public void smaz()


    /**
     *  Posune obrazek smrku o zadany pocet bodu vpravo,
     *  pri zapornem parametru vlevo.
     *  
     *  @param n   pocet bodu, o ktere se smrcek posune
     */
    public void posunVpravo( int n )
    {
        dolni.posunVpravo( n );
        stredni.posunVpravo( n );
        horni.posunVpravo( n );
        //Pri vodorovnem posunu nemuze odmazani horniho patra poskodit 
        //dolni patro => pri kresleni od spodu neni treba nic znovu kreslit
     }//public void posunVpravo( int n )


    /**
     * Posune obrazek smrku o krok bodu vpravo.
     */
    public void posunVpravo() 
    {   
        this.posunVpravo( krok );
    }//public void posunVpravo()


    /**
     * Posune obrazek smrku o krok bodu vlevo.
     */
    public void posunVlevo() 
    {   //Pro posun vlevo musime zadat zapornou hodnotu
        this.posunVpravo( -krok );
    }//public void posunVlevo()


    /**
     *  Posune obrazek smrku o zadany pocet bodu dolu,
     *  pri zapornem parametru nahoru.
     *  
     *  @param n  pocet bodu, o ktere se smrcek posune
     */
    public void posunDolu( int n )
    {
        horni.posunDolu( n );
        stredni.posunDolu( n );
        dolni.posunDolu( n );

        //Pri odmazavani nekterych dilu se muze umazat kus 
        //jinych dilu => je treba je pro jistotu prekreslit
        kresli();       //Radeji vse prekreslime
     }//public void posunDolu( int n )


    /**
     * Posune obrazek smrku o krok bodu nahoru.
     */
    public void posunNahoru() 
    {   //Pro posun nahoru musime zadat zapornou hodnotu
        this.posunDolu( -krok );
    }//public void posunNahoru()


    /**
     * Posune obrazek smrku o krok bodu dolu.
     */
    public void posunDolu() 
    {   
        this.posunDolu( krok );
    }//public void posunDolu()


    /**
     * Prebarvi obrazek smrku barvou pozadi platna.
     */
    public void schovejVPozadi() 
    {   
        //Metodu tridy kvalifikujeme tridou
        Platno platno = Platno.getPlatno();
        //Metodu instance kvalifikujeme instanci
        String pozadi = platno.getBarvaPozadi();
        horni.setBarva( pozadi );
        stredni.setBarva( pozadi );
        dolni.setBarva( pozadi );
    }//public void posunDolu()


    /**
     * Metoda prevadi instanci na retezec -
     * pouziva se vetsinou pro ucely ladeni.
     * Mela by ji definovat kazda trida a uvest v ni
     * vsechny potrebne informace o vnitrnim stavu instance.
     *
     * @return     retezec informujici o vnitrnim stavu instance
     */
    public String toString()
    {
        //Nasledujici prikaz nahradte vlastnim kodem
        return "Smrk: x=" + getX() + ", y=" + getY() + 
               ", sirka=" + getSirka() + ", vyska=" + getVyska() +
               ", barva=" + getBarva() + ", krok=" + krok;
    }//public String toString()


//== SOUKROME A POMOCNE METODY =================================================
//== VNORENE A VNITRNI TRIDY ===================================================

}//public class Smrk