/* MODUL PLANSZA - zawiera deklaracje klasy plansza */

/* Klasa Plansza jest odpowiedzialna za przechowywanie informacji na temat
   swiata gry. Do niej odwoluja sie inne obiekty aby dowiedziec sie
   co w danym polu planszy znajduje sie.
                        .    
   Autor: Michal Wiktor Zmijewski   (grupa nr 5)
*/   

#ifndef __PLANSZA_H
#define __PLANSZA_H

#include <stl.h>
#include "typy.h"
#include "stale_ElementySwiata.h"
#include "parametry.h"

#ifdef TYP_TEREN_INT
#define MNOZNIK_TLA 256 /* przesuniecia w bita dla zapisu tla terenu */
#endif

/* definicje struktur pomocniczych i typow */
typedef struct daneORodzaju
{ 
   int licznik;    // okresla ile jest elementow rodzaju rodzaj
};//daneORodzaju

enum _typ_stan { _pobor,_nic,_aktualizacja };

class InfoZmian
{ 
public:
   Para  wsp;    // wspolrzedne pola ktore uleglo zmianie
   int   zmiana_tla; // 1 jesli byla zmiana tla terenu, 0 wpp.
   InfoZmian():wsp(),zmiana_tla(0){};
   InfoZmian(Para w):wsp(w),zmiana_tla(0){};
   InfoZmian(Para w,int z):wsp(w),zmiana_tla(z){};
   ~InfoZmian(){};
};//InfoZmian

class PoleZmian
{ 
public:
   InfoZmian  zmiana;    // informacje o polu ktore uleglo zmianie(wspolrzedne pola,czy byla zmiana tla)
   _typ_stan stan; // okresla w jakim celu bylo ogladane pole

   PoleZmian():zmiana(),stan(_nic){}
   PoleZmian(Para x):zmiana(x),stan(_nic){};
   PoleZmian(Para x,int z):zmiana(x,z),stan(_nic){};
   PoleZmian(InfoZmian x):zmiana(x),stan(_nic){};
   PoleZmian(InfoZmian x,_typ_stan y):zmiana(x),stan(y){};
   ~PoleZmian(){};
};//PoleZmian

/* definicje typow */ 
typedef   map<typ_rodzaj,daneORodzaju>     typ_sl_rodzajow;
typedef   list<InfoZmian>                  typ_lista_zmian;
typedef   list<PoleZmian>                  typ_lista_polZmian;

class PolePlanszy {
public:
#ifndef TYP_TEREN_INT
      typ_teren                  tlo;  // informacja o rodzaju tla terenu
#endif

     typ_teren                  teren;  // informacja o rodzaju terenu
     typ_sl_rodzajow      sl_rodzajow;  // slownik informacji o el. roznych rodz.
};//PolePlanszy

     
/*  ***************************** */

class Plansza {
protected:
    Para          wejscie;       // wspolrzedne wejscia
    Para          wyjscie;       // wspolrzedne wyjscia
    Para          rozmiar;       // rozmiar planszy - swiata
    PolePlanszy **swiatAktualny; // plansza z ktorej pobiera sie informacje
                                 // o aktualnym swiecie gry
    typ_teren   **swiatNowy;     // plansza na ktore nanoszone sa zmiany terenu
    int           robic_zmiany;   // gdy jest rowna 1 bedzie dokonywana aktualizacja
                                  // planszy dopiero po odbiorze impulsu wpp. na bierzaco
    typ_lista_polZmian  lista_zmian; // lista z informacja o zmienionych polach
    typ_lista_polZmian::iterator iter_zmian;    // iterator naniesionych zmian
public:
         // konstruktor i destruktor
	        Plansza(const Param_plansza&,int zmiana=1,typ_teren tlo=0);
	       ~Plansza();
	       	
        class  PozaPlansza{};	 // wyjatek odwolania sie poza obszar planszy
	class  Brak_pamieci{};   // wyjatek braku pamieci 
    typ_teren  jakiTeren(const Para x);
         void  ustawTeren(const Para x,const typ_teren z);
    typ_teren  jakieTlo(const Para x);
         void  ustawTlo(const Para x,const typ_teren z);
          int  ileJestElementowRodzaju(const Para x,const typ_rodzaj z);
         void  wstawElementRodzaju(const Para x,const typ_rodzaj z);
	  int  usunElementRodzaju(const Para x,const typ_rodzaj z);
	 Para  wspolrzedneWejscia() { return wejscie; }
	 Para  wspolrzedneWyjscia() { return wyjscie; }
	 void  wspolrzedneWejscia(Para x) { wejscie=x; }
	 void  wspolrzedneWyjscia(Para x) { wyjscie=x; }
	 Para  rozmiarPlanszy() { return rozmiar; }
	  int  listaZmian(typ_lista_zmian &l);
	  int  czyAktualizacjaCykliczna() { return (robic_zmiany==1); }
	  int  odbierzImpuls();
private:
          int zla_alokacja;

   inline int czyDobreWspolrzedne(const Para wsp) // sprawdza poprawnosc wsp
     { return !((wsp.x<0)||(wsp.x>=rozmiar.x)||(wsp.y<0)||(wsp.y>=rozmiar.y)); };
     
};//Plansza


#endif /* __PLANSZA_H */