#pragma once

#include "Team.h"
#include "Gegenstand.h"
#include "Effect.h"
#include <Array.h>

class Spiel;

#define INVENTORY_SLOTS 8

class Inventar
{
private:
    GegenstandTyp slots[ INVENTORY_SLOTS ];
    int anzahl[ INVENTORY_SLOTS ];
    float abklingzeit[ INVENTORY_SLOTS ];
    int selected;

public:
    Inventar();
    void addItem( GegenstandTyp typ, int anzahl );
    void setSelected( int slot );
    bool hatAbklingzeit( GegenstandTyp typ ) const;
    GegenstandTyp useItem();
    void tick( double zeit );
    bool canAddItem( GegenstandTyp typ ) const;
    GegenstandTyp selectedItem() const;
    int getItemAnzahl() const;
    int getItemAnzahl( GegenstandTyp typ ) const;
    GegenstandTyp getItemTyp( int index ) const;
    void removeItem( GegenstandTyp typ, int anzahl );
    int getSelectedIndex() const;
    float getAbklingzeit( int index ) const;
};

class Spieler : public GameObject
{
private:
    RCArray< Effect > effekte;
    int accountId;
    int spielerNummer;
    Team *team;
    bool amLeben;
    int maxWiederbelebungsZeit;
    float wiederbelebungsZeit;
    GegenstandTyp zuletztAufgehoben;
    GegenstandTyp zuletztAktiviert;
    float leben;
    int maxLeben;
    int level;
    float erfahrung;
    int maxErfahrung;
    int spawnX;
    int spawnY;
    float laufTempo;
    float geschossTempo;
    float armor;
    float schadensBonus;
    float lebensraub;
    float lebensRegeneration;
    float abklingZeitVerringerung;
    int color;
    int kills;
    int tode;
    int treffer;
    int getroffen;
    float schadenGenommen;
    float schadenGemacht;
    float lebenGeheilt;
    float erhalteneErfahrung;
    int itemsAufgehoben;
    int itemsVerwendet;
    int tunnelBenutzt;
    int schalterAktiviert;
    int geschosseGeschossen;
    bool tastenStand[ 256 ];
    Text name;
    Richtung ausrichtung;
    Inventar inv;
    int currentImage;
    double currentNext;
    Resource *current;
    int heilungImage;
    double heilungNext;
    bool showHeilung;
    Resource *heilungR;
    int schadenImage;
    double schadenNext;
    bool showSchaden;
    Resource *schadenR;
    ResourceRegistry *resources;

public:
    Spieler( ResourceRegistry *zResources, int id, Team *team, int spawnX, int spawnY, int farbe );
    ~Spieler();
    bool setTastenStand( unsigned char taste, bool pressed );
    void setTeam( Team *team );
    void setAccount( int id );
    void addEffekt( Effect *e );
    void setLaufTempo( float pps );
    void addErfahrung( float anz, Spiel *zSpiel );
    void levelUp( Spiel *zSpiel );
    void levelDown( Spiel *zSpiel );
    void addTunnelBenutzung( Spiel *zSpiel );
    void addSchalterBenutzung( Spiel *zSpiel );
    // aktualisiert auch die team statistik
    void addKill();
    void addTreffer( Spiel *zSpiel );
    void addGetroffen();
    void move( double zeit );
    void wiederbelebung( Spiel *zSpiel );
    void tick( double zeit, Spiel *zSpiel );
    void render( Bild &rObj ) override;
    void useItem( Spiel *zSpiel );
    bool addItem( GegenstandTyp typ, int anz, Spiel *zSpiel );
    // heilt auch um den lebensraub prozentsatz
    void addGemachterSchaden( float schaden, Spiel *zSpiel );
    // zieht die r�stung ab
    void nimmSchaden( float schaden, Spieler *zVerursacher, Richtung r, Spiel *zSpiel );
    void heilung( float heal, Spiel *zSpiel, bool show = 1 );
    void setSchadenBonus( float bonus );
    void setLebensRaub( float raub );
    void setGeschossTempo( float tempo );
    void setArmor( float armor );
    void setLebensRegeneration( float reg );
    void setName( const char *name );
    // setzt alle eigenschafften, die mit dem level gesetzt werden entsprechend
    void setLevel( int level, Spiel *zSpiel );
    void removeItem( GegenstandTyp typ, int anzahl );
    void setLeben( float leben );
    void setMaxLeben( int leben );
    // steuert auch level up oder level downs bei negativer erfahrung
    void setErfahrung( float erf, Spiel *zSpiel );
    void setMaxErfahrung( int erf );
    void setAbklingZeitVerringerung( float verringerung );
    float getLebensRegenneration() const;
    float getArmor() const;
    float getGeschossTempo() const;
    float getLebensRaub() const;
    float getSchadenBonus() const;
    Team *zTeam() const;
    Team *getTeam() const;
    int getFarbe() const;
    int getAccountId() const;
    int getPunkte() const;
    bool istAmLeben() const;
    float getLaufTempo() const;
    bool isVerwundbar( Richtung r ) const;
    bool istBeweglich( Richtung r ) const;
    bool istSichtbar( Team *zTeam ) const;
    bool istGegenstandErlaubt( GegenstandTyp typ ) const;
    Richtung getAusrichtung() const;
    float getAbklingZeitVerringerung() const;
    int getId() const;
    int getLevel() const;
    float getLeben() const;
    int getMaxLeben() const;
    float getErfahrung() const;
    int getMaxErfahrung() const;
    int getTode() const;
    int getKills() const;
    int getTreffer() const;
    int getGetroffen() const;
    float getErlittenerSchaden() const;
    float getGemachterSchaden() const;
    float getGeheiltesLeben() const;
    int getItemsAufgehoben() const;
    int getItemsVerwendet() const;
    int getItemsInInventory() const;
    int getItemsInInventory( GegenstandTyp typ ) const;
    int getTunnelBenutzt() const;
    int getSchalterAktiviert() const;
    int getGeschossen() const;
    GegenstandTyp getInventorySlot( int index ) const;
    const char *getName() const;
    const Inventar &getInventory() const;
};

class DeadPlayer : public GameObject
{

public:

    bool isFinished() const;
};