#ifndef PLAYER_H
#define PLAYER_H

#include <stdint.h>

#include "Item.h"
#include "Ability.h"
#include "PlayerAbility.h"
#include "../util/SlotStorage.h"

#include <vector>
#include <map>
#include <string>
#include <algorithm>
using namespace std;

#include "PlayerDefines.h"

class Player {
 public:
  Player ();
  ~Player ();
  void clear (int cID=PLAYER_CLASS_NULL);
  void initialize (int cID);

  //These are the final stats, taking equipment into account.
  int getHealth ();
  int getArmor ();
  int getAccuracy ();
  int getDamage ();
  int getPierce ();
  int getEvade ();
  int getLuck ();

  //These are the base stats.
  int getBaseHealth ();
  int getBaseArmor ();
  int getBaseAccuracy ();
  int getBaseDamage ();
  int getBasePierce ();
  int getBaseEvade ();
  int getBaseLuck ();

  int getMoney ();
  int getLevel ();
  int getExperience ();
  int getClassID ();

  //These adjust the base stats.
  void setHealth (int x);
  void setArmor (int x);
  void setAccuracy (int x);
  void setDamage (int x);
  void setPierce (int x);
  void setEvade (int x);
  void setLuck (int x);

  void setMoney (int x);
  void addMoney (int x);
  void setLevel (int x);
  void setExperience (int x);
  void setClassID (int x);

  void addExperience (int x);
  int getExperienceToLevel ();
  void setExperienceToLevel (int);
  bool checkForLevelUp ();
  void levelUp ();

  int numAbilitiesAtCurrentLevel ();

  const string & getName ();
  void setName (const string & x);

  //Inventory Management
  bool addItem(const string & itemName);
  int getInventorySize ();
  bool getItem (const string & itemName, map<string, Item>::iterator & itemIter);
  bool sellItem (const string & itemName);
  bool decrementItem (const string & itemName, int amount=1);

  //Equipment-specific management
  bool equipItem(const string &);
  int getNumberOfEquippedItems();
  bool unequipItem(const string &);
  void rebuildEquipmentStats();

  //Ability-specific stuff
  bool getPlayerAbility (map<string,PlayerAbility>::iterator & ans, int slot);
  bool learnPlayerAbility (const string & abilityName);
  bool readyAbility (const string & abilityName, int slot=-1);
  int getAttackPathNames (vector <string> & attackPathNames);

  //During Battle-specific data.
  void clearDuringBattleData();
  void startDuringBattleData();
  int getCurrentHealth ();
  void setCurrentHealth (int x);
  void loseCurrentHealth (int x);
  bool isDead ();

 private:
  vector <int> baseStats;
  vector <int> equipmentStats;

  int money;
  int level, experience, experienceToLevel;
  string name;
  int classID;
  void levelUpHelper (xmlDocPtr &, xmlXPathContextPtr &, string &);

  //There is one "hard copy" of inventory. Everything else are keys referring to the data.
  map <string, Item> inventory;
  vector <string> equippedItems;

  //There is only one "hard copy" of your abilities.
  map <string, PlayerAbility> playerAbilities; //All usuable abilities that can be readied
  SlotStorage<string> readiedAbilities; //Can be used during combat
  vector <string> learnedAbilities; //Powers the player knows from levelling up and training.
  bool addPlayerAbility (PlayerAbility & patToAdd);

  //Battle-specific stuff
  int currentHealth;
  vector <int> status;
};

#endif
