/*******************************************************************************
 * Třída Výtah_6 simuluje výtah vozící pasažéry
 *
 * @author    Rudolf Pecinovský
 * @version   0.00.000,  0.0.2003
 */
public class Výtah_6 implements IKreslený, IPosuvný
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================
    
    /** Aktivní plátno, které dohlíží na správné vykreslení instance. */
    private static final AktivníPlátno AP = AktivníPlátno.getPlátno();
    
    
    
//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================

    /** Počet dosud vytvořených instancí. */
    private static int počet = 0;

    

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

    /** Pořadí vytvoření dané instance v rámci třídy. */
    private final int pořadí = ++počet;

    /** Sloupec plátna, v němž se výtah pohybuje. */
    private final int sloupec;
    
    /** Barva kabiny. */
    private final Barva barva;
    
    /** Výtah_6 použije pro všechny posuny jednoho soukromého přesouvače. */
    private final Přesouvač přesouvač;
    
    
    
//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
    
    /** Patro, v němž se výtah právě nachází. */
    private int patro;
    
    private Obdélník kabina;
    
    private IPosuvný pasažér;

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

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

    /***************************************************************************
     * Konstruktor definující ve kterém sloupci bude výtah jezdit, 
     * jakou bude jezdit rychlostí a jakou bude mít barvu.
     * 
     * @param sloupec  Sloupec aktivního plátna, v němž bude výtah jezdit.
     * @param rychlost Rychlost nastavená přesouvači, který bude mít daný výtah
     *                 na starosti.
     * @param barva    Barva výtahu.          
     */
    public Výtah_6(int sloupec, int rychlost, Barva barva)
    {
        this.sloupec = sloupec;
        this.přesouvač = new Přesouvač( rychlost );
        this.barva = barva;
        this.patro = 0;
        
        int krok = AP.getKrok();
        int x = sloupec * krok;
        int y = (AP.getVýška()-1) * krok;
        
        this.kabina = new Obdélník( x, y, krok, krok, barva );
        
        AP.přidej( (IKreslený)this );
    }


    /***************************************************************************
     * Konstruktor definující ve kterém sloupci bude výtah jezdit, 
     * jakou bude jezdit rychlostí a jakou bude mít barvu.
     * 
     * @param sloupec  Sloupec aktivního plátna, v němž bude výtah jezdit.
     * @param rychlost Rychlost nastavená přesouvači, který bude mít daný výtah
     *                 na starosti.
     * @param barva    Barva výtahu.          
     */
    public Výtah_6(int sloupec)
    {
        this( sloupec, 2, Barva.ČERNÁ );
    }

    

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


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

    
    /***************************************************************************
     * Vrátí y-ovou souřadnici pozice instance.
     *
     * @return  y-ová souřadnice.
     */
    public int getY() 
    {
        return kabina.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) 
    {
        kabina. setPozice( x, y );
    }
    
    
    
//== 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) 
    {
        kabina .nakresli( kreslítko );
        //((IKreslený)pasažér).nakresli( kreslítko );
    }
    
    
    
//== PŘEKRYTÉ ABSTRAKTNÍ METODY RODIČOVSKÉ TŘÍDY ===============================
//== PŘEKRYTÉ KONKRÉTNÍ METODY RODIČOVSKÉ TŘÍDY ================================

    /***************************************************************************
     * Převede instanci na řetězec, v němž bude uvedeno pořadové číslo
     * výtahu, sloupec, v němž jezdí a patro, v němž se právě nachází.
     *
     * @return Řetězcová reprezentace dané instance.
     */
    public String toString()
    {
        return "Výtah_6_" + pořadí + ": sloupec=" + sloupec + ", patro=" + patro;
    }



//== NOVĚ ZAVEDENÉ METODY INSTANCÍ =============================================
     
    /***************************************************************************
     * Přijede di patra, ve kterém se nachází pasažér.
     * odveze jej do požadovaného patra; pasažér zůstává ve výtahu.
     * 
     * @param pasažér   Pasažér, do jehož řádku je třebaq přijet.
     */
    public void přijeďK( IPosuvný pasažér )
    {
        int patro = AP.getVýška() - pasažér.getY()/AP.getKrok() - 1;
        doPatra( patro );
    }
    
   
    /***************************************************************************
     * Přesune zadaného pasažéra z jeho výchozí pozice do výtahu.
     * V zájmu reálnosti grafické simulace by se měl pasažér vejít do 
     * jednoho políčka aktivního plátna.          
     *
     * @param pasažér   Gemetrický tvar, který bude zastupovat pasažera.
     */
    public void nástup( IPosuvný pasažér )
    {
        this.pasažér = pasažér;
        AP.přidejPod( (IKreslený)this, (IKreslený)pasažér );
        přesouvač.přesunNa( pasažér, getX(), getY() );
        AP.odstraň( (IKreslený) pasažér );
    }
    
   
    /***************************************************************************
     * Odjede s výtahem do zadaného patra;
     * je-li nastoupený pasažér, odjede i s ním.
     *
     * @param patro   Pořadové číslo cílového patra (přízemí má 0).
     */
    public void doPatra( int patro )
    {
        přesouvač.přesunO( this, 0, (this.patro - patro)*AP.getKrok() );
        this.patro = patro;
    }
    
    
    /***************************************************************************
     * Přesune pasažéra výtahu na sousední políčko vpravo vedle výtahu.
     */
    public void výstupVpravo()
    {
        výstup( AP.getKrok() );
    }
    
    
    /***************************************************************************
     * Přesune pasažéra výtahu na sousední políčko vlevo vedle výtahu.
     */
    public void výstupVlevo()
    {
        výstup( -AP.getKrok() );
    }
    
     
    /***************************************************************************
     * Přivolá do pasažérova patra výtah, nechá pasažéra nastoupit,
     * odveze jej do požadovaného patra a tam jej nechá vystoupit doprava.
     * 
     * @param pasažér   Gemetrický tvar, který bude zastupovat pasažera.
     * @param doPatra   Pořadové číslo cílového patra (přízemí má 0).
     */
    public void odvezVpravo( IPosuvný pasažér, int doPatra )
    {
        odvez( pasažér, doPatra );
        výstupVpravo();
    }   
    
     
    /***************************************************************************
     * Přivolá do pasažérova patra výtah, nechá pasažéra nastoupit,
     * odveze jej do požadovaného patra a tam jej nechá vystoupit doleva.
     * 
     * @param pasažér   Gemetrický tvar, který bude zastupovat pasažera.
     * @param doPatra   Pořadové číslo cílového patra (přízemí má 0).
     */
    public void odvezVlevo( IPosuvný pasažér, int doPatra )
    {
        odvez( pasažér, doPatra );
        výstupVlevo();
    }   
    
    
    
//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
    
    /***************************************************************************
     * Přesune pasažéra výtahu na sousední políčko vlevo vedle výtahu.
     */
    private void výstup( int posun )
    {
        int krok = AP.getKrok();
        pasažér.setPozice( getX(), getY() );
	    AP.přidejPod( (IKreslený)this, (IKreslený) this.pasažér );
        přesouvač.přesunO( pasažér, posun,  0 );
        pasažér = null;
    }
    
     
    /***************************************************************************
     * Přivolá do pasažérova patra výtah, nechá pasažéra nastoupit,
     * odveze jej do požadovaného patra; pasažér zůstává ve výtahu.
     * 
     * @param pasažér   Gemetrický tvar, který bude zastupovat pasažera.
     * @param doPatra   Pořadové číslo cílového patra (přízemí má 0).
     */
    private void odvez( IPosuvný pasažér, int doPatra )
    {
        přijeďK( pasažér );
        nástup( pasažér );
        doPatra( doPatra );
    }
    


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

