#include "Store.h"

#include <iostream>
using namespace std;

Store :: Store ()
{
  
}

Store :: ~Store ()
{
  //iterate through and delete everything
}

void Store :: initialize ()
{
  //clear everything.
 
  consumablesForSale.clear();

  consumableDesc.clear();

  equipmentForSale.clear();
  equipmentDesc.clear();

  descAndPrice.clear();
  abilityDesc.clear();

  abilitiesToTrain.clear();
}

bool Store :: addItemToStock (const string & id, const string & type)
{
  //loads item according to the name and type

  if (itemExists(id))
    return false;

  Consumable con;
  Equipment equ;
  string description;

  char indexStr [5];

  if (type == "Equipment" && equ.loadEquipment (id) == 0)
    {
      equipmentForSale.push_back (equ);
      description=equ.getItemID ();
      description+=" ";
      sprintf (indexStr, "%u", equ.getPrice ());
      description+=indexStr;
      equipmentDesc.push_back(description);
    }
  else if (type == "Consumable" && con.loadConsumable (id) == 0)
    {
      consumablesForSale.push_back (con);
      description=con.getItemID ();
      description+=" ";
      sprintf (indexStr, "%u", con.getPrice ());
      description+=indexStr;
      consumableDesc.push_back (description);
    }
  else
    return false;

  repairDescAndPrice ();
  return true;
}

void Store :: repairDescAndPrice ()
{
  //rebuild desc and price everytime something is added.
  descAndPrice.clear ();

  vector <string> :: iterator iterStrings;
  iterStrings = equipmentDesc.begin ();
  while (iterStrings != equipmentDesc.end ()) {
    descAndPrice.push_back (*iterStrings);
    iterStrings ++;
  }

  iterStrings = consumableDesc.begin ();
  while (iterStrings != consumableDesc.end ()) {
    descAndPrice.push_back (*iterStrings);
    iterStrings ++;
  }
}

vector <string> & Store :: getStoreList ()
{
  return descAndPrice;
}

bool Store :: itemExists (const string & id)
{
  //is there something with that ID?
  vector <Equipment> :: iterator iterEquips;
  iterEquips = equipmentForSale.begin ();
  while (iterEquips != equipmentForSale.end ()) {
    if (iterEquips -> getItemID () == id)
      return true;
    iterEquips ++;
  }

  vector <Consumable> :: iterator iterCons;
  iterCons = consumablesForSale.begin ();
  while (iterCons != consumablesForSale.end ()) {
    if (iterCons -> getItemID () == id)
      return true;
    iterCons ++;
  }
  return false;
}

uint8_t Store :: buyItem (Player & p, int16_t slot)
{
  //player p attempts to buy the item located at position slot.
  //Return code:
  //0 : Transaction completed.
  //1 : Player is invalid (NULL)
  //2 : slot is invalid
  //4 : Player does not have enough money to afford the item.
  //8 : Player rejected the item for some reason. Out of space, probably.

  if (slot < 0 || slot >= int16_t(consumablesForSale.size () + equipmentForSale.size ()))
    return 2;
  
  uint8_t price;
  string itemID;
  string type;

  if (slot < int16_t(equipmentForSale.size ()))
    {
      price = equipmentForSale[slot].getPrice ();
      itemID = equipmentForSale[slot].getItemID ();
      type="Equipment";
    }
  else
    {
      price = consumablesForSale[slot - equipmentForSale.size ()].getPrice ();
      itemID = consumablesForSale[slot - equipmentForSale.size ()].getItemID ();
      type="Consumable";
    }

  if (price > p.getMoney ())
    return 4;
  
  if (!p.addNewItem (itemID, type))
    return 8;

  p.addMoney (-1 * price);
  return 0;
}

uint8_t Store :: addAbilityToStore (const string & abilID)
{
  //0 = success
  //1 = ability already exists
  //2 = ability is invalid

  vector <PlayerAbility> :: iterator iterAbils;
  iterAbils = abilitiesToTrain.begin ();
  while (iterAbils != abilitiesToTrain.end ()) {
    if (abilID == iterAbils -> getAbilityName ())
      return 1; //already in inventory
    iterAbils ++;
  }

  PlayerAbility pab;

  if (!pab.loadPlayerAbility (abilID))
    {
      return 2;
    }

  abilitiesToTrain.push_back (pab);
  abilityDesc.push_back (pab.getAbilityName ());
  return 0;
}

uint8_t Store :: teachAbility (Player & pray, int16_t slot)
{
  //0 = success
  //1 = player has all the abilites he can learn.
  //2 = invalid slot index.
  //3 = player already has this ability/invalid ability.
  //4 = This ability is too high level for the player to learn.

  if (pray.numNaturalAbilities () >= pray.numAbilitiesAtCurrentLevel ())
    return 1;

  if (slot < 0 || slot >= int(abilitiesToTrain.size ()))
    return 2;

  if (abilitiesToTrain.at (slot).getMinLevel (pray.getClassID ()) > pray.getLevel ())
    return 4;

  if (pray.learnAbility (abilitiesToTrain.at (slot).getAbilityName (), "Natural", "") != 0)
    return 3;

  return 0;
}

vector <string> & Store :: getStoreAbilityList ()
{
  return abilityDesc;
}
