#include "Equipment.h"
#include "Player.h"

#include <stdint.h>

#include "../util/fileUtils.h"
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>

#include <vector>
using namespace std;

Equipment :: Equipment ()
{
  vector <uint8_t> levelRequirements;
  levelRequirements.resize (PLAYER_CLASS_NUMBER);
  levelRequirements.assign (levelRequirements.size (), 0);
  accuracyBoost = 0;
  damageBoost = 0;
  hpBoost= 0;
  pierceBoost = 0;
  armorBoost = 0;
  luckBoost = 0;
  evadeBoost = 0;
  rechargeBoost = 0;
  isEquipped=false;
}

Equipment :: ~Equipment ()
{
}

uint8_t Equipment :: getAccuracyBoost ()
{
  return accuracyBoost;
}

uint8_t Equipment :: getDamageBoost ()
{
  return damageBoost;
}

uint8_t Equipment :: getHealthBoost ()
{
  return hpBoost;
}

uint8_t Equipment :: getPierceBoost ()
{
  return pierceBoost;
}

uint8_t Equipment :: getArmorBoost ()
{
  return armorBoost;
}

uint8_t Equipment :: getLuckBoost ()
{
  return luckBoost;
}

uint8_t Equipment :: getEvadeBoost ()
{
  return evadeBoost;
}

uint8_t Equipment :: getRechargeBoost ()
{
  return rechargeBoost;
}

void Equipment :: setAccuracyBoost (uint8_t x)
{
  accuracyBoost = x;
}

void Equipment :: setDamageBoost (uint8_t x)
{
 damageBoost = x;
}

void Equipment :: setHealthBoost (uint8_t x)
{
 hpBoost = x;
}

void Equipment :: setPierceBoost (uint8_t x)
{
  pierceBoost = x;
}

void Equipment :: setArmorBoost (uint8_t x)
{
  armorBoost = x;
}

void Equipment :: setLuckBoost (uint8_t x)
{
  luckBoost = x;
}

void Equipment :: setEvadeBoost (uint8_t x)
{
  evadeBoost = x;
}

void Equipment :: setRechargeBoost (uint8_t x)
{
  rechargeBoost = x;
}

uint8_t Equipment :: getLevelRequirement (uint8_t classID)
{
  if (classID >= levelRequirements.size ())
    return 0;

  return levelRequirements.at(classID);
}

void Equipment :: setLevelRequirement (uint8_t x, uint8_t classID)
{
  if (classID >= levelRequirements.size ())
    return;

  levelRequirements.at(classID) = x;
}

uint8_t Equipment :: loadEquipment (const string & id)
{
  //reads the xml file and loads stats into the object.
  //0 : Equipment is now loaded.
  // returns 1 for all other errors.

  xmlDocPtr doc;
  xmlXPathContextPtr xpathCtx;

  string xpathStart="/ItemManifest/Equipment[@ID='";
  xpathStart+=id;
  xpathStart+="']";

  if (!prepareXMLFile (doc, xpathCtx, "resources/game/ItemManifest.xml", xpathStart))
    {
      return 1;
    }

  bool tempBool = xPathExists (doc, xpathCtx, xpathStart, "", "");
  if (tempBool)
    tempBool = loadEquipmentHelper (doc, xpathCtx, xpathStart);

  xmlXPathFreeContext(xpathCtx);
  xmlFreeDoc(doc);

  if (!tempBool)
    return 1;

  setItemID (id);
  return 0;
}

bool Equipment :: loadEquipmentHelper (xmlDocPtr doc, xmlXPathContextPtr xpathCtx, const string & xpath)
{
  xmlChar * element;
  int temp;

  element = getFirstElementUsingXPath (doc, xpathCtx, xpath, "/Price", "");
  if (element == NULL)
    temp = 0;
  else
    temp = int(xmlXPathCastStringToNumber(element));

  if (temp < 0)
    temp = 0;

  if (temp > 255)
    temp = 255;
  xmlFree (element);
  setPrice (temp);

  element = getFirstElementUsingXPath (doc, xpathCtx, xpath, "/AccuracyBoost", "");
  if (element == NULL)
    temp = 0;
  else
    temp = int(xmlXPathCastStringToNumber(element));

  if (temp < 0)
    temp = 0;

  if (temp > 255)
    temp = 255;
  xmlFree (element);
  setAccuracyBoost (temp);

  element = getFirstElementUsingXPath (doc, xpathCtx, xpath, "/DamageBoost", "");
  if (element == NULL)
    temp = 0;
  else
    temp = int(xmlXPathCastStringToNumber(element));

  if (temp < 0)
    temp = 0;

  if (temp > 255)
    temp = 255;
  xmlFree (element);
  setDamageBoost (temp);

  element = getFirstElementUsingXPath (doc, xpathCtx, xpath, "/HealthBoost", "");
  if (element == NULL)
    temp = 0;
  else
    temp = int(xmlXPathCastStringToNumber(element));

  if (temp < 0)
    temp = 0;

  if (temp > 255)
    temp = 255;
  xmlFree (element);
  setHealthBoost (temp);

  element = getFirstElementUsingXPath (doc, xpathCtx, xpath, "/PierceBoost", "");
  if (element == NULL)
    temp = 0;
  else
    temp = int(xmlXPathCastStringToNumber(element));

  if (temp < 0)
    temp = 0;

  if (temp > 255)
    temp = 255;
  xmlFree (element);
  setPierceBoost (temp);

  element = getFirstElementUsingXPath (doc, xpathCtx, xpath, "/LuckBoost", "");
  if (element == NULL)
    temp = 0;
  else
    temp = int(xmlXPathCastStringToNumber(element));

  if (temp < 0)
    temp = 0;

  if (temp > 255)
    temp = 255;
  xmlFree (element);
  setLuckBoost (temp);

  element = getFirstElementUsingXPath (doc, xpathCtx, xpath, "/EvadeBoost", "");
  if (element == NULL)
    temp = 0;
  else
    temp = int(xmlXPathCastStringToNumber(element));

  if (temp < 0)
    temp = 0;

  if (temp > 255)
    temp = 255;

  xmlFree (element);
  setEvadeBoost (temp);

  element = getFirstElementUsingXPath (doc, xpathCtx, xpath, "/RechargeBoost", "");
  if (element == NULL)
    temp = 0;
  else
    temp = int(xmlXPathCastStringToNumber(element));

  if (temp < 0)
    temp = 0;

  if (temp > 255)
    temp = 255;
  xmlFree (element);
  setRechargeBoost (temp);

  element = getFirstElementUsingXPath (doc, xpathCtx, xpath, "/LevelWarrior", "");
  if (element == NULL)
    temp = 0;
  else
    temp = int(xmlXPathCastStringToNumber(element));

  if (temp < 0)
    temp = 0;

  if (temp > 255)
    temp = 255;
  xmlFree (element);
  setLevelRequirement (temp, PLAYER_CLASS_WARRIOR);

  element = getFirstElementUsingXPath (doc, xpathCtx, xpath, "/LevelArcher", "");
  if (element == NULL)
    temp = 0;
  else
    temp = int(xmlXPathCastStringToNumber(element));

  if (temp < 0)
    temp = 0;

  if (temp > 255)
    temp = 255;
  xmlFree (element);
  setLevelRequirement (temp, PLAYER_CLASS_ARCHER);

  element = getFirstElementUsingXPath (doc, xpathCtx, xpath, "/LevelMage", "");
  if (element == NULL)
    temp = 0;
  else
    temp = int(xmlXPathCastStringToNumber(element));

  if (temp < 0)
    temp = 0;

  if (temp > 255)
    temp = 255;
  xmlFree (element);
  setLevelRequirement (temp, PLAYER_CLASS_MAGE);

  element = getFirstElementUsingXPath (doc, xpathCtx, xpath, "/LevelSwashbuckler", "");
  if (element == NULL)
    temp = 0;
  else
    temp = int(xmlXPathCastStringToNumber(element));

  if (temp < 0)
    temp = 0;

  if (temp > 255)
    temp = 255;
  xmlFree (element);
  setLevelRequirement (temp, PLAYER_CLASS_SWASHBUCKLER);

  return true;
}

bool Equipment ::getEquipped()
{
  return isEquipped;
}

void Equipment ::setEquipped(bool equipped)
{
  isEquipped=equipped;
}
