import java.awt.*;
import java.awt.geom.*;

/**
 * Trida pro praci s obdelnikem na virualnim platne.
 * Je soucasti projektu Tvary, ktery slouzi k demonstraci moznosti 
 * vyuky objektove orientovaneho programovani.
 *
 * @author     Rudolf Pecinvosky
 * @version    1.0, prosinec 2002
 */

public class Obdelnik
{

//== ATRIBUTY TRIDY ============================================================

    /**
     *  Pocatecni barva nakresleneho obdelniku v pripade,
     *  kdy uzivatel zadnou pozadovanou barvu nezada.
     */
    public static final String POC_BARVA = "cervena";

    private static int    krok   = 50;


//== ATRIBUTY INSTANCI =========================================================

    private int xPos;
    private int yPos;
    private int sirka;
    private int vyska;
    private String barva;


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

    /**
     * Vrati velikost implicitniho kroku, o ktery se obdelnik presune
     * pri volani bezparametrickych metod presunu.
     *
     * @return velikost implicitniho kroku v bodech
     */
     public static int getKrok()
     {
         return krok;
     }//public static int getKrok()


    /**
     * Nastavi velikost implicitniho kroku, o ktery se obdelnik presune
     * pri volani bezparametrickych metod presunu.
     *
     * @param velikost  velikost implicitniho kroku v bodech; velikost>=0
     */
    public static void setKrok( int velikost )
    {
        if( velikost < 0 )
            throw new IllegalArgumentException(
                "Krok nesmi byt zaporny: velikost=" + velikost );
        krok = velikost;
    }//public static void setKrok( int velikost )



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

    /**
     * Vytvori novy obdelnik s implicitnimi rozmery, umistenim a barvou.
     * Obdelnik bude umisten v levem hornim rohu platna a bude mit implicitni,
     * (na pocatku cervenou) barvu, vysku 20 bodu a sirku 40 bodu.
     */
    public Obdelnik()
    {
        this( 0, 0, 40, 20 );
    }//public Obdelnik()


    /**
     * Vytvori novy obdelnik se zadanou polohou a rozmery
     * a implicitni (na pocatku cervenou) barvou.
     *
     * @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 w   sirka obdelniku,  w > 0
     * @param h   vyska obdelniku,  h > 0
     */
    public Obdelnik( int x, int y, int w, int h )
    {
        this( x, y, w, h, POC_BARVA );
    }//public Obdelnik( int x, int y, int w, int h )


    /**
     * Vytvori novy obdelnik se zadanymi rozmery, polohou a barvou.
     *
     * @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 w   sirka obdelniku,  w > 0
     * @param h   vyska obdelniku,  h > 0
     * @param c barva obdelniku - povolene hodnoty jsou:
     *                    "cerna",  "modra",     "cervena", "fialova",
     *                    "zelena", "blankytna", "zluta",   "bila".
     */
    public Obdelnik( int x, int y, int w, int h, String c )
    {
        //Test platnosti parametru
        if( (x<0) || (y<0) || (w<=0) || (h<=0) )
            throw new IllegalArgumentException(
                "Parametry nemaji povolene hodnoty: x="
                + x + ", y=" + y + ", w=" + w + ", h=" + h );
        Platno.getPlatno().setBarvaPopredi( c );

        //Parametry akceptovany --> muzeme tvorit
        sirka = w;
        vyska = h;
        xPos = x;
        yPos = y;
        barva = c;
        kresli();
    }//public Obdelnik( int x, int y, int w, int h, String c )



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

    /**
     * Vrati x-ovou souradnici obdelniku, 
     * tj. souradnici jeho leveho horniho rohu .
     *
     * @return x-ova souradnice leveho horniho rohu obdelniku
     */
     public int getX()
     {
         return xPos;
     }//public int getX()


    /**
     * Vrati y-ovou souradnici obdelniku, 
     * tj. souradnici jeho leveho horniho rohu .
     *
     * @return y-ova souradnice leveho horniho rohu obdelniku
     */
     public int getY()
     {
         return yPos;
     }//public int getY()


    /**
     * Nastavi novou polohu obdelniku.
     *
     * @param x   x-ova pozice leveho horniho rohu obdelniku
     * @param y   y-ova pozice leveho horniho rohu obdelniku
     */
    public void setPozice(int x, int y)
    {
        smaz();
        xPos = x;
        yPos = y;
        kresli();
    }//public void setPozice(int x, int y)


    /**
     * Vrati sirku obdelniku.
     *
     * @return  sirka obdelniku v bodech
     */
     public int getSirka()
     {
         return sirka;
     }//public int getSirka()


    /**
     * Vrati vysku obdelniku.
     *
     * @return  vyska obdelniku v bodech
     */
     public int getVyska()
     {
         return vyska;
     }//public int getVyska()


    /**
     * Nastavi novou velikost stran obdelniku -
     * na zadanou velikost se nastavi vyska i sirka.
     *
     * @param velikost  nove nastavovana velikost; velikost>0
     */
    public void setVelikost(int velikost)
    {
        setRozmer( velikost, velikost );
    }//public void setVelikost(int velikost)


    /**
     * Nastavi nove rozmery obdelniku.
     *
     * @param w    nove nastavovana sirka; w>0
     * @param h    nove nastavovana vyska; h>0
     */
    public void setRozmer(int w, int h)
    {
        if( (w <= 0) || (h <= 0) )
            throw new IllegalArgumentException(
                "Rozmery musi byt kladne: w=" + w + ", h=" + h );
        smaz();
        sirka = w;
        vyska = h;
        kresli();
    }//public void setRozmer(int rozmer)


    /**
     * Vráti barvu obdelniku.
     *
     * @return  retezec definujici nastavenou barvu
     */
    public String getBarva()
    {
        return barva;
    }//public String getBarva()


    /**
     * Nastavi novou barvu obdelniku.
     *
     * @param nova nastavovana barva - povolene hodnoty jsou:
     *             "cerna",  "modra",     "cervena", "fialova",
     *             "zelena", "blankytna", "zluta",   "bila".
     */
    public void setBarva(String nova)
    {
        //Nejprve otestuje akceptovatelnost nastavovane barvy
        Platno platno = Platno.getPlatno();
        platno.setBarvaPopredi( nova ); //Zkus nastavit zadavanou barvu
        barva = nova;                   //Proslo to --> nastav ji
        kresli();
    }//public void setBarva(String nova)



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

    /**
     * Nakresli obdelnik na platno.
     */
    protected void kresli()
    {
        Platno platno = Platno.getPlatno();
        platno.setBarvaPopredi(barva);
        platno.zapln(new Rectangle2D.Double(xPos, yPos, sirka, vyska));
    }//protected void kresli()


    /**
     * Smaze dany obdelnik, tj. nakresli jej barvou pozadi platna.
     */
    protected void smaz()
    {
        Platno platno = Platno.getPlatno();
        platno.smaz(new Rectangle2D.Double(xPos, yPos, sirka, vyska));
    }//protected void smaz()


    /**
     * Presune obdelnik o zadany pocet bodu vpravo,
     * pri zaporne hodnote parametru vlevo.
     *
     * @param vzdalenost  pocet bodu, o kterou se obdelnik presune
     */
    public void posunVpravo(int vzdalenost)
    {
        smaz();
        xPos += vzdalenost;
        kresli();
    }//public void posunVpravo(int vzdalenost)


    /**
     * Presune obdelnik krok bodu vpravo.
     */
    public void posunVpravo()
    {
        posunVpravo(krok);
    }//public void posunVpravo()


    /**
     * Presune obdelnik o krok bodu vlevo.
     */
    public void posunVlevo()
    {
        posunVpravo(-krok);
    }//public void posunVlevo()


    /**
     * Pomalu presune obdelnik o zadany pocet bodu vpravo,
     * pri zaporne hodnote parametru vlevo.
     *
     * @param vzdalenost pocet bodu, o ktere se obdelnik presune
     */
    public void pomaluVpravo(int vzdalenost)
    {
        int delta;
        Platno platno = Platno.getPlatno();

        if(vzdalenost < 0)
        {
            delta = -1;
            vzdalenost = -vzdalenost;
        }
        else
        {
            delta = 1;
        }

        for(int i = 0; i < vzdalenost; i++)
        {
            posunVpravo( delta );
            platno.cekej(10);
        }
    }//public void pomaluVpravo(int vzdalenost)


    /**
     * Presune obdelnik o zadany pocet bodu dolu,
     * pri zaporne hodnote parametru nahoru.
     *
     * @param vzdalenost  pocet bodu, o ktere se obdelnik presune
     */
    public void posunDolu(int vzdalenost)
    {
        smaz();
        yPos += vzdalenost;
        kresli();
    }//public void posunDolu(int vzdalenost)


    /**
     * Presune obdelnik o krok bodu nahoru.
     */
    public void posunVzhuru()
    {
        posunDolu(-krok);
    }//public void posunVzhuru()


    /**
     * Presune obdelnik o krok bodu dolu.
     */
    public void posunDolu()
    {
        posunDolu(krok);
    }//public void posunDolu()


    /**
     * Pomalu presune obdelnik o zadany pocet bodu dolu,
     * pri zaporne hodnote parametru nahoru.
     *
     * @param vzdalenost pocet bodu, o ktere se obdelnik presune
     */
    public void pomaluDolu(int vzdalenost)
    {
        int delta;
        Platno platno = Platno.getPlatno();

        if(vzdalenost < 0)
        {
            delta = -1;
            vzdalenost = -vzdalenost;
        }
        else
        {
            delta = 1;
        }

        for(int i = 0; i < vzdalenost; i++)
        {
            posunDolu( delta );
            platno.cekej(10);
        }
    }//public void pomaluDolu(int vzdalenost)

}//public class Obdelnik