/*
    Program:		"MINI-LEMINGI"

    Modul:		Elementy Swiata

    Autor:		Damian Wojtowicz
    Weryfikator:	Michal Zmijewski
    Tester:		Anna Doros

    Krotki opis:	Plik zawiera deklaracje klas: 
			- abstrakcyjnych: ElementSwiata, Komandos,
			  KomandosBezrobotny, KomandosPracujacy, Kopacz,
			  Schodkarz, SzczegolnyElementSwiata;
			- finalnych: Leming, Bloker, KopaczPionowy,
			  KopaczPoziomy, KopaczSkosnyWGore, KopaczSkosnyWDol,
			  SchodkarzPoziomy, SchodkarzGorny, SchodkarzDolny,
			  Bomba, Wejscie, Wyjscie;
			oraz definicje typu wyliczeniowego: typ_czynnosci_bomby.
			Hierarchia klas podana jest w dokumentacji technicznej
			lub mozna ja odczytac z deklaracji.
			Kazda z klas finalnych odpowiada jednemu z elementow
			swiata gry i opisuje jego zachowanie w tym swiecie.
*/

#ifndef __ELEMENTY_SWIATA_H
#define __ELEMENTY_SWIATA_H

#include "parametry.h"
#include "Plansza.h"
#include "stale_ElementySwiata.h"
#include "stale_Leming.h"

/*============================================================================*/
		    /* TYP WYLICZENIOWY: typ_czynnosci_bomby  */
/*============================================================================*/

enum typ_czynnosci_bomby {eksplozja, zanikanie};

/*============================================================================*/
			    /* KLASA: ElementSwiata  */
/*============================================================================*/

class ElementSwiata
{	/* klasa abstrakcyjna */
  protected:
    int wstawiony;		// czy obiekt jest wstawiony na plansze
    Plansza	*plansza;	// wskaznik na plansze (swiat w ktorym zyje)
    
    /* konstruktor bezargumentowy zabroniony dla obcych */
    ElementSwiata() 
	{ wstawiony = 0; /* wstawiony == NIE */};
	
    /* funkcje prywatne */
    typ_rodzaj virtual rodzaj(void) = 0;	// funkcja wirtualana
    void virtual posprzataj(void);
    
  public:
    /* atrybuty publiczne */
    Para	 pozycja;		// pozycja na planszy
    int 	 liczba_impulsow;	// liczba impulsow potrzebnych na wykonanie
					// czynnosci
    int 	 licznik_impulsow;	// ile impulsow juz trwa aktualana czynnosc
    unsigned int stan;			// opis stanu obiektu
    
    /* destruktor */
    virtual ~ElementSwiata(){};
    
    /* funkcja publiczna */
    void virtual odbierzImpuls(void) = 0;	// wirtualna funkcja

    /* wyjatki */
    class Niepowodzenie{};		//obiekt niepoprawnie wstawiony
    class Trup{};			// usunac obiekt

};

/*============================================================================*/
			    /* KLASA: Leming  */
/*============================================================================*/

class Leming : public ElementSwiata
{
  protected:
     /* atrybuty klasowe (statyczne) */
    static int 	predkosc_w_wodzie;
    static int 	predkosc_w_powietrzu;
    static int 	spadanie_w_wodzie;
    static int 	spadanie_w_powietrzu;
    static int 	pojemnosc_pluc;
    static int 	maksymalny_skok;
    static int 	czas_zmiany_stanu;
    
    /* chronione atrybuty obiektowe */
    int 	czas_w_wodzie;
    int		dlugosc_upadku;

    /* chroniony konstruktor bezargumentowy zabroniony */
    Leming(){};

    /* chronione funkcje skladowe */
    typ_rodzaj virtual rodzaj(void) { return LEMING;};
    void virtual poprawCzasWWodzieIDlugoscUpadku(void);
    int virtual  sprawdzCzyMamUmrzecLubCzyDoszedlemDoWyjscia(void);
    int virtual  sprawdzCzyMamBycSpalonyWKwasie(void);
    typ_teren virtual sprawdzTeren(const Para wspolrzedne);
    int virtual  czyMiekkiTeren(typ_teren teren);
    int virtual  czySchodyPrzeciwne(typ_teren cegla, int zwrot);
    int  virtual czyPrzeszkadzaBloker(void);
    void virtual przesunMnie(const Para na);
    void virtual sprawdzCzyJestemWWodzie(void);
    int virtual  czyMamSpadac(void);
    void virtual iCoDalej(void);
    void virtual ruszamPoIdzie(void);
    void virtual ruszamPoSpada(void);
    void virtual ruszam(void);
	
  public:
    /* publiczne atrybuty */
    int 	kierunek;		// kierunek poruszania sie
    int 	zwrot_nosa;		// zwrot leminga (prawo, lewo)
    
    /* konstruktor */
    Leming(Plansza *wsk_plansza);

    /* destruktor */
    virtual ~Leming(){};    
    
    /* wyjatki */
    class Doszedlem{};
    
    /* publiczne funkcje skladowe */
    void virtual odbierzImpuls(void);
    void virtual umieraj(void);
    
}; //Leming

/*============================================================================*/
			    /* KLASA: Komandos  */
/*============================================================================*/

class Komandos : public Leming
{	/* klasa abstrakcyjna */
  protected:
    /* prywatne konstruktory */
    Komandos(){};
    Komandos(Plansza *wsk_plansza, Para wspolrzedne, int zwrot);

    /* destruktor */
    virtual ~Komandos(){};

}; //Komandos

/*============================================================================*/
			    /* KLASA: KomandosBezrobotny  */
/*============================================================================*/

class KomandosBezrobotny : public Komandos
{	/* klasa abstrakcyjna */
  protected:
    /* konstruktory zabronione dla obcych */
    KomandosBezrobotny(){};
    KomandosBezrobotny(Plansza *wsk_plansza, Para wspolrzedne, int zwrot)
		: Komandos(wsk_plansza, wspolrzedne, zwrot) {};
    /* destruktor */
    virtual ~KomandosBezrobotny(){};    
};

/*============================================================================*/
			    /* KLASA: Bloker  */
/*============================================================================*/

class Bloker : public KomandosBezrobotny
{
  protected:
     /* atrybuty klasowe (statyczne) */
    static int czas_stania;

    /* prywatny konstruktor bezargumentowy zabroniony */
    Bloker(){};

    /* funkcje prywatne */
    typ_rodzaj virtual rodzaj(void) { return BLOKER;};
    void virtual sprawdzamCzyStoje(void);
    void virtual iCoDalej(void);
    void virtual ruszam(void);

  public:
    /* konstruktor */
    Bloker(Plansza *wsk_plansza, Para wspolrzedne);

    /* destruktor */
    virtual ~Bloker(){};

}; //Bloker

/*============================================================================*/
			    /* KLASA: KomandosPracujacy  */
/*============================================================================*/

class KomandosPracujacy : public Komandos
{	/* klasa abstrakcyjna */
  protected:
    /* prywatne konstruktory - zabronione dla innych */
    KomandosPracujacy(){};
    KomandosPracujacy(Plansza *wsk_plansza, Para wspolrzedne, int zwrot)
		: Komandos(wsk_plansza, wspolrzedne, zwrot){};
    /* destruktor */
    virtual ~KomandosPracujacy(){};

    /* funkcje prywatne */
    int  virtual czyMamPracowac(void) = 0;	// funkcja wirtualna
    void virtual dokonczPrace(void) = 0;	// funkcja wirtualna
    void virtual iCoDalej(void);
    void virtual ruszam(void);

  public:
    /* atrybuty publiczne */
    int zapas;	// jaki komandos ma jeszcze zapas sil
    
}; //KomandosPracujacy

/*============================================================================*/
			    /* KLASA: Kopacz  */
/*============================================================================*/

class Kopacz : public KomandosPracujacy
{	/* klasa abstrakcyjna */
  protected:
     /* atrybuty klasowe (statyczne) */
    static int czas_kopania;

    /* prywatne konstruktory - zabronione dla obcych */ 
    Kopacz(){};
    Kopacz(Plansza *wsk_plansza, Para wspolrzedne, int zwrot)
		: KomandosPracujacy(wsk_plansza, wspolrzedne, zwrot)
    { 
	zapas = ZAPAS_SIL_KOPACZA; 
    };
    /* destruktor */
    virtual ~Kopacz(){};
    /* funkcje prywatne */
    int  virtual czyTerenDoKopania(typ_teren teren);
    void virtual wykonajPrace(void);
    void virtual dokonczPrace(void);
    
    /* publiczne funkcje skladowe */
    void virtual odbierzImpuls(void);
    
}; //Kopacz

/*============================================================================*/
			    /* KLASA: KopaczPionowy  */
/*============================================================================*/

class KopaczPionowy : public Kopacz
{
  protected:
    /* prywatny konstruktor bezargumentowy zabroniony */
    KopaczPionowy(){};
    /* prywatne funkcje */
    typ_rodzaj virtual rodzaj(void) { return KOPACZ_PIONOWY;};
    int  virtual czyMamPracowac(void);

  public:
      /* konstruktor */
    KopaczPionowy(Plansza *wsk_plansza, Para wspolrzedne, int zwrot);
    /* destruktor */
    virtual ~KopaczPionowy(){};
    
}; // KopaczPionowy

/*============================================================================*/
			    /* KLASA: KopaczPoziomy  */
/*============================================================================*/

class KopaczPoziomy : public Kopacz
{
  protected:
    /* prywatny konstruktor bezargumentowy zabroniony */
    KopaczPoziomy(){};
    /* prywatne funkcje */
    typ_rodzaj virtual rodzaj(void) { return KOPACZ_POZIOMY;};
    int  virtual czyMamPracowac(void);

  public:
    /* konstruktor */
    KopaczPoziomy(Plansza *wsk_plansza, Para wspolrzedne, int zwrot);
    /* destruktor */
    virtual ~KopaczPoziomy(){};
}; //KopaczPoziomy

/*============================================================================*/
			    /* KLASA: KopaczSkosnyWGore  */
/*============================================================================*/

class KopaczSkosnyWGore : public Kopacz
{
  protected:
    /* prywatny konstruktor bezargumentowy zabroniony */
    KopaczSkosnyWGore(){};
    /* prywatne funkcje */
    typ_rodzaj virtual rodzaj(void) { return KOPACZ_GORNY;};
    int  virtual czyMamPracowac(void);
    
  public:
    /* konstruktor */
    KopaczSkosnyWGore(Plansza *wsk_plansza, Para wspolrzedne, int zwrot);
    /* destruktor */
    virtual ~KopaczSkosnyWGore(){};
    
}; //KopaczSkosnyWGore

/*============================================================================*/
			    /* KLASA: KopaczSkosnyWDol  */
/*============================================================================*/

class KopaczSkosnyWDol : public Kopacz
{
  protected:
    /* prywatny konstruktor bezargumentowy zabroniony */
    KopaczSkosnyWDol(){};
    /* prywatne funkcje */
    typ_rodzaj virtual rodzaj(void) { return KOPACZ_DOLNY;};
    int  virtual czyMamPracowac(void);

  public:
    /* konstruktor */
    KopaczSkosnyWDol(Plansza *wsk_plansza, Para wspolrzedne, int zwrot);
    /* destruktor */
    virtual ~KopaczSkosnyWDol(){};

}; //KopaczSkosnyWDol

/*============================================================================*/
			    /* KLASA: Schodkarz  */
/*============================================================================*/

class Schodkarz : public KomandosPracujacy
{	/* klasa abstrakcyjna */
  protected:
     /* atrybuty klasowe (statyczne) */  
    static int czas_budowania;
  
    /* prywatne konstruktory bezargumentowe - zabronione */
    Schodkarz(){};
    Schodkarz(Plansza *wsk_plansza, Para wspolrzedne, int zwrot)
		: KomandosPracujacy(wsk_plansza, wspolrzedne, zwrot)
	{ 
	    zapas = ZAPAS_SIL_SCHODKARZA; 
	};
    /* destruktor */
    virtual ~Schodkarz(){};
    /* funkcje prywatne */
    int virtual czyTerenDoBudowania(typ_teren teren);
    void virtual wstawSchodek(const Para pozycja, const typ_teren cegla);
}; //Schodkarz

/*============================================================================*/
			    /* KLASA: SchodkarzPoziomy  */
/*============================================================================*/

class SchodkarzPoziomy : public Schodkarz
{
  protected:
    /* prywatny konstruktor bezargumentowy zabroniony */
    SchodkarzPoziomy(){};
    /* funkcje prywatne */
    typ_rodzaj virtual rodzaj(void) { return SCHODKARZ_POZIOMY;};
    int virtual czyMamPracowac(void);
    void virtual dokonczPrace(void);
    
  public:
    /* konstruktor */
    SchodkarzPoziomy(Plansza *wsk_plansza, Para wspolrzedne, int zwrot);
    /* destruktor */
    virtual ~SchodkarzPoziomy(){};
    
}; //SchodkarzPoziomy

/*============================================================================*/
			    /* KLASA: SchodkarzGorny  */
/*============================================================================*/

class SchodkarzGorny : public Schodkarz
{
  protected:
    /* prywatny konstruktor bezargumentowy zabroniony */
    SchodkarzGorny(){};
    /* funkcje prywatne */
    typ_rodzaj virtual rodzaj(void) { return SCHODKARZ_GORNY;};
    int virtual czyMamPracowac(void);
    void virtual dokonczPrace(void);
    
  public:
    /* konstruktor */
    SchodkarzGorny(Plansza *wsk_plansza, Para wspolrzedne, int zwrot);
    /* destruktor */
    virtual ~SchodkarzGorny(){};
    
}; //SchodkarzGorny

/*============================================================================*/
			    /* KLASA: SchodkarzDolny  */
/*============================================================================*/

class SchodkarzDolny : public Schodkarz
{
  protected:
    /* prywatny konstruktor bezargumentowy zabroniony */
    SchodkarzDolny(){};
    /* funkcje prywatne */
    typ_rodzaj virtual rodzaj(void) { return SCHODKARZ_DOLNY;};
    int  virtual czyMamPracowac(void);
    void virtual dokonczPrace(void);

  public:
    /* konstruktor */
    SchodkarzDolny(Plansza *wsk_plansza, Para wspolrzedne, int zwrot);
    /* destruktor */
    virtual ~SchodkarzDolny(){};
    
};  //SchodkarzDolny

/*============================================================================*/
			    /* KLASA: Pijus  */
/*============================================================================*/

class  Pijus : public KomandosPracujacy
/*
    Klasa jest klasa dodana w ramach uzgodnionej modyfikacji programu.
    Umiejscowienie tej klasy w tym miejscu w hierarchii klas jest uzasadnione
    pomimo duzego podobienstwa (przynajmniej na pierwszy rzut oka) pijusa do
    kopacza poziomego. Wynika to stad iz istnieja sytuacje w ktorych sie
    np. jest problem ze schodami w wodzie (schody pierwszy plan, woda drugi plan)
    poza tym kopacz w momenciw pracy porusza sie, a pijus stoi obok kratek
    z ktorych wypompowuje wode.
*/
{
  protected:
     /* atrybuty klasowe (statyczne) */
    static int czas_picia;

    /* prywatne konstruktory - zabronione dla obcych */ 
    Pijus(){};
    /* destruktor */
    virtual ~Pijus(){};
    /* funkcje prywatne */
    typ_rodzaj virtual rodzaj(void) { return PIJUS;};
    int virtual czyTerenNaKropceDoPicia(Para wspol);
    void virtual dokonczPrace(void);
    int virtual czyMamPracowac(void);

  public:
    Pijus(Plansza *wsk_plansza, Para wspolrzedne, int zwrot);
    
}; //Pijus

/*============================================================================*/
			    /* KLASA: Bomba  */
/*============================================================================*/

class Bomba : public ElementSwiata
{
  protected:
     /* atrybuty klasowe (statyczne) */
    static int 	promien_wybuchu;
    static int 	czas_oczekiwania;
    static int 	predkosc_wybuchu;
    static int  predkosc_zaniku;

    int promien;		// aktualny promien wybuchu

    /* prywatny konstruktor bezargumentowy zabroniony */
    Bomba(){};
    /* funkcje prywatne */
    typ_rodzaj virtual rodzaj(void) { return BOMBA;};
    void virtual modyfikujKropke(Para wspolrz, typ_czynnosci_bomby czynnosc);
    void virtual modyfikujTeren(typ_czynnosci_bomby czynnosc);

  public:
    /* konstruktor */
    Bomba(Plansza *wsk_plansza, Para wspolrzedne);
    /* destruktor */
    virtual ~Bomba(){};

    /*publiczna funkcja skladowa */
    void virtual odbierzImpuls(void);

    /* wyjatek */
    class Koniec{};			// usunac obiekt, bomba zakonczyla wybuch
    
}; //Bomba

/*============================================================================*/
		    /* KLASA: SzczegolnyElementSwiata  */
/*============================================================================*/

class SzczegolnyElementSwiata : public ElementSwiata
/* klasa abstrakcyjana */
{
  protected:
     /* atrybuty klasowe (statyczne) */
    static int 	czas_ruchu_elementu_szczegolnego;
    /* prywatne atrybuty obiektowe */  
    int maksymalne_przesuniecie;
    int aktualne_przesuniecie;

    /* konstruktory - zabronione dla obcych */
    SzczegolnyElementSwiata(){};
    SzczegolnyElementSwiata(Plansza *wsk_plansza, int przesuniecie);  
    /* destruktor */
    virtual ~SzczegolnyElementSwiata(){};

    /* funkcje prywatne */
    void virtual posprzataj(void){};
    int virtual przesunMnie(const Para na) = 0;
    void virtual swojeCzynnosci(void){};

  public:
    /* atrybuty publiczne */
    int 	zwrot;			// zwrot poruszajacego sie obiektu

    /* funkcja publiczna */
    void virtual odbierzImpuls(void);

}; //SzczegolnyElementSwiata

/*============================================================================*/
			    /* KLASA: Wejscie  */
/*============================================================================*/

class Wejscie : public SzczegolnyElementSwiata
{
  protected:
    /* atrybuty prywatne */
    int 	czy_zamykac;		//czy zamykac wejscie
    /* prywatny konstruktor bezargumentowy */
    Wejscie(){};
  
    /* funkcje prywatne */
    typ_rodzaj virtual rodzaj(void) { return WEJSCIE;};
    int virtual przesunMnie(const Para na);
    void virtual swojeCzynnosci(void);

  public:
    /* konstruktor */
    Wejscie(Plansza *wsk_plansza, int przesuniecie = 0);
    /* destruktor */
    virtual ~Wejscie(){};

    /* funkcja publiczna */
    void virtual zamknij(void);

}; //Wejscie

/*============================================================================*/
			    /* KLASA: Wyjscie  */
/*============================================================================*/

class Wyjscie : public SzczegolnyElementSwiata
{
  protected:
    /* prywatny konstruktor bezargumentowy */
    Wyjscie(){};

    /* funkcje prywatne */
    typ_rodzaj virtual rodzaj(void) { return WYJSCIE;};
    int virtual przesunMnie(const Para na);

  public:
    /* konstruktor */
    Wyjscie(Plansza *wsk_plansza, int przesuniecie = 0);
    /* destruktor */
    virtual ~Wyjscie(){};

}; //Wyjscie


#endif /* __ELEMENTY_SWIATA_H */