#ifndef SpielKlasse_H
#define SpielKlasse_H

#include "SpielV.h"
#include "SpielChat.h"
#include "Ende.h"
#include "STKNachricht.h"
#include <Bildschirm.h>
#include <Kamera2D.h>
#include <Random.h>
#include "Spieler.h"
#include "Bariere.h"
#include "Base.h"
#include "Drop.h"
#include "Geschoss.h"
#include "Schalter.h"
#include "Schiene.h"
#include "Trigger.h"
#include "Tunnel.h"
#include "Umlenkung.h"
#include "DrachenAuge.h"
#include "Brand.h"
#include "Resource.h"
#include "SpielerGUI.h"

class Spiel : public SpielV
{
private:
    RCArray< STKNachricht > *stkn;
    Schrift *schrift;
    KSGClient::InformationServerClient *infoKlient;
    KSGClient::SpielServerClient *spielKlient;
    Bildschirm *zScreen;
    SpielChat *chat;
    Ende *end;
    SpielerGUI *spielerGUI;
    RCArray< DeadPlayer > *deads;
    RandomGenerator randG;
    RCArray< VarPointer > variablen;
    RCArray< Spieler > spieler;
    RCArray< Team > teams;
    RCArray< Bariere > barieren;
    RCArray< Base > basen;
    RCArray< Drop > drops;
    RCArray< Gegenstand > items;
    RCArray< Geschoss > shots;
    RCArray< FeuerballTreffer > feuer;
    RCArray< Schalter > schalter;
    RCArray< Schiene > schienen;
    RCArray< Timer > timer;
    RCArray< Tunnel > tunnel;
    RCArray< Umlenkung > umlenkungen;
    RCArray< Trigger > trigger;
    RCArray< TriggerRun > triggerRuns;
    Punkt mapSize;
    Team *zWinner;
    Critical c;
    Trigger *lastRunnedTrigger;
    Bariere *zuletztEingeschalteteBariere;
    Bariere *zuletztAusgeschalteteBariere;
    Bariere *zuletztBewegteBariere;
    Base *lastTeamChangedBase;
    Drop *lastDropedDrop;
    GegenstandTyp zuletztAufgehobenerGegenstand;
    GegenstandTyp zuletztBenutzterGegenstand;
    GegenstandTyp zuletztGedropterGegenstand;
    Geschoss *zuletztAbgefeuertesGeschoss;
    Geschoss *zuletztUmgelenktesGeschoss;
    Geschoss *zuletztBariereGetroffenesGeschoss;
    Geschoss *zuletztTunnelBenutztesGeschoss;
    Geschoss *zuletztGeschossGetroffenesGeschoss;
    Schalter *zuletztAktivierterSchalter;
    Spieler *zuletztSchadenGemachterSpieler;
    Spieler *zuletztSchadenGenommenerSpieler;
    Spieler *zuletztGeheilterSpieler;
    Spieler *zuletztLevelUpSpieler;
    Spieler *zuletztErfahrungBekommenerSpieler;
    Spieler *zuletztGegenstandAktivierterSpieler;
    Spieler *zuletztGegenstandAufgehobenerSpieler;
    Spieler *zuletztSchalterAktivierterSpieler;
    Spieler *zuletztTunnelBenutzterSpieler;
    Spieler *zuletztGestorbenerSpieler;
    Spieler *zuletztWiederbelebterSpieler;
    Spieler *zuletztGeschossenerSpieler;
    Timer *zuletztAbgelaufenerTimer;
    Timer *zuletztGestarteterTimer;
    Timer *zuletztPausierterTimer;
    Timer *zuletztFortgesetzterTimer;
    Tunnel *zuletztBenutzterTunnel;
    Umlenkung *zuletztBenutzteUmlenkung;
    ResourceRegistry *resources;
    int nextId;
    bool rendern;
    double rZeit;
    int gameTicks;
    int spielerAnzahl;
    int karteId;
    int ladenProzent;
    int spielerNummer;
    char *tasten;
    bool pause;
    int ref;

    bool istAmLeben() const;
    void tick();

public:
    // Konstruktor
    Spiel();
    // Destruktor
    ~Spiel();
    // nicht constant
    void lock();
    void unlock();
    void setSchrift( Schrift *schrift ) override; // call 4
    void setBildschirm( Bildschirm *zScreen ) override; // call 3
    void nachricht( int l�n, char *bytes ) override;
    void setKlients( KSGClient::InformationServerClient *infoKlient, KSGClient::SpielServerClient *spielKlient ) override; // call 2
    void setKarteId( int karteId ) override; // call 1
    void ladeDaten() override; // call 5
    void doPublicMausEreignis( MausEreignis &me ) override;
    void doTastaturEreignis( TastaturEreignis &te ) override;
    void stknVerarbeitung();
    bool tick( double zeit ) override;
    void render( Bild &zRObj ) override;
    void setMapSize( int width, int height );
    void setPausiert( bool pausiert );
    void addVariable( const char *name, Variable *var );
    void setVariable( const char *name, Variable *var );
    void addTeam( Team *team );
    void addSpieler( Spieler *spieler );
    void addBariere( Bariere *bariere );
    void addBase( Base *base );
    void addDrop( Drop *drop );
    void addGegenstand( Gegenstand *gegenstand );
    void addGeschoss( Geschoss *geschoss );
    void addSchalter( Schalter *schalter );
    void addSchiene( Schiene *schiene );
    void addTimer( Timer *timer );
    void addTunnel( Tunnel *tunnel );
    void addUmlenkung( Umlenkung *umlenkung );
    void addTrigger( Trigger *trigger );
    void addTriggerRun( TriggerRun *tRun );
    void spielerActivate( Spieler *zSpieler );
    void activateShalter( int id );
    void throwEvent( Ereignis *e );
    Variable *getVariable( const char *name ) const;
    Variable *zVariable( const char *name ) const;
    bool istPausiert() const;
    bool needEvent( EreignisTyp typ ) const;
    Team *getTeam( int id ) const;
    Spieler *getSpieler( int id ) const;
    Iterator< Spieler * > getSpieler() const;
    Iterator< Bariere * > getBarieren() const;
    Bariere *getBariere( int id ) const;
    Base *getBase( int id ) const;
    Drop *getDrop( int id ) const;
    Schalter *getSchalter( int id ) const;
    Schiene *getSchiene( int id ) const;
    Timer *getTimer( int id ) const;
    Tunnel *getTunnel( int id ) const;
    Umlenkung *getUmlenkung( int id ) const;
    Trigger *getTrigger( int id ) const;
    int getNextId();
    double getRand();
    int getTickCount() const;
    void setEnde( Team *zGewinner );
    Trigger *getRandomTrigger();
    Trigger *getLastRunnedTrigger() const;
    Bariere *getRandomBariere();
    void setZuletztEingeschalteteBariere( Bariere *b );
    Bariere *getZuletztEingeschalteteBariere() const;
    void setZuletztAusgeschalteteBariere( Bariere *b );
    Bariere *getZuletztAusgeschalteteBariere() const;
    void setZuletztBewegteBariere( Bariere *b );
    Bariere *getZuletztBewegteBariere() const;
    Base *getRandomBase();
    void setLastTeamChangedBase( Base *b );
    Base *getLastTeamChangedBase() const;
    Drop *getRandomDrop();
    void setLastDrop( Drop *d );
    Drop *getLastDrop() const;
    void setItemZuletztAufgehoben( GegenstandTyp g );
    GegenstandTyp getItemZuletztAufgehoben() const;
    void setItemZuletztAktiviert( GegenstandTyp g );
    GegenstandTyp getItemZuletztAktiviert() const;
    GegenstandTyp getItemZuletztGedropt() const;
    Geschoss *getRandomGeschoss();
    Geschoss *getGeschossZuletztAbgefeuert() const;
    void setGeschossZuletztUmgelenkt( Geschoss *g );
    Geschoss *getGeschossZuletztUmgelenkt() const;
    Geschoss *getGeschossZuletztBariereGetroffen() const;
    void setGeschossZuletztTunnelBenutzt( Geschoss *g );
    Geschoss *getGeschossZuletztTunnelBenutzt() const;
    void setGeschossZuletztGeschossGetroffen( Geschoss *g );
    Geschoss *getGeschossZuletztGeschossGetroffen() const;
    Schalter *getRandomSchalter();
    void setSchalterZuletztAktiviert( Schalter *s );
    Schalter *getSchalterZuletztAktiviert() const;
    Spieler *getRandomSpieler();
    Spieler *getRandomSpieler( Team *zTeam );
    void setSpielerZuletztSchadenGemacht( Spieler *s );
    Spieler *getSpielerZuletztSchadenGemacht() const;
    void setSpielerZuletztSchadenGenommen( Spieler *s );
    Spieler *getSpielerZuletztSchadenGenommen() const;
    void setSpielerZuletztGeheilt( Spieler *s );
    Spieler *getSpielerZuletztGeheilt() const;
    void setSpielerZuletztLevelUp( Spieler *s );
    Spieler *getSpielerZuletztLevelUp() const;
    void setSpielerZuletztErfahrungBekommen( Spieler *s );
    Spieler *getSpielerZuletztErfahrungBekommen() const;
    void setSpielerZuletztGegenstandAktiviert( Spieler *s );
    Spieler *getSpielerZuletztGegenstandAktiviert() const;
    void setSpielerZuletztGegenstandAufgehoben( Spieler *s );
    Spieler *getSpielerZuletztGegenstandAufgehoben() const;
    void setSpielerZuletztSchalterAktiviert( Spieler *s );
    Spieler *getSpielerZuletztSchalterAktiviert() const;
    void setSpielerZuletztTunnelBenutzt( Spieler *s );
    Spieler *getSpielerZuletztTunnelBenutzt() const;
    void setSpielerZuletztGestorben( Spieler *s );
    Spieler *getSpielerZuletztGestorben() const;
    void setSpielerZuletztWiederbelebt( Spieler *s );
    Spieler *getSpielerZuletztWiederbelebt() const;
    void setSpielerZuletztGeschossen( Spieler *s );
    Spieler *getSpielerZuletztGeschossen() const;
    Team *getRandomTeam();
    Timer *getRandomTimer();
    void setTimerZuletztAbgelaufen( Timer *t );
    Timer *getTimerZuletztAbgelaufen() const;
    void setTimerZuletztGestartet( Timer *t );
    Timer *getTimerZuletztGestartet() const;
    void setTimerZuletztPausiert( Timer *t );
    Timer *getTimerZuletztPausiert() const;
    void setTimerZuletztFortgesetzt( Timer *t );
    Timer *getTimerZuletztFortgesetzt() const;
    Tunnel *getRandomTunnel();
    void setTunnelZuletztBenutzt( Tunnel *t );
    Tunnel *getTunnelZuletztBenutzt() const;
    Umlenkung *getRandomUmlenkung();
    void setUmlenkungZuletztBenutzt( Umlenkung *t );
    Umlenkung *getUmlenkungZuletztBenutzt() const;
    ResourceRegistry *zResources() const;
    // constant
    int l�uft() const override;
    // Reference Counting
    SpielV *getThis() override;
    SpielV *release() override;
};

#endif