#include <tinyxml2.h>
#include <stdexcept>
#include <vector>
#include <color.h>
#include "items.h"

using namespace tinyxml2;

namespace game{

std::vector<itemInfo> items;
std::vector<receiptInfo> receipts;
std::vector<const char*> receiptNames;

void readItems(const std::string &filename)
{
    XMLDocument doc;
    if(doc.LoadFile(filename.c_str()))
        throw std::runtime_error(doc.ErrorName());

    if(XMLElement *itemsEl = doc.RootElement()->FirstChildElement("items"))
    {
        items.reserve(itemsEl->UnsignedAttribute("count"));
        for(itemsEl=itemsEl->FirstChildElement("item"); itemsEl; itemsEl = itemsEl->NextSiblingElement("item"))
        {
            itemInfo item;
            item.code = itemsEl->Attribute("id");
            item.name = itemsEl->Attribute("name");
            item.price = itemsEl->FloatAttribute("price");
            items.push_back(item);
        }
    }
    else
        throw std::runtime_error("Invalid items file");
    for(int i = 0; i < items.size(); i++)
        items[i].color = color::hsv2rgba(vec3f(360*i/items.size(),1,1),0.6);

    if(XMLElement *receiptEl = doc.RootElement()->FirstChildElement("receipts"))
    {
        receipts.reserve(receiptEl->UnsignedAttribute("count"));
        for(receiptEl=receiptEl->FirstChildElement("receipt"); receiptEl; receiptEl = receiptEl->NextSiblingElement("receipt"))
        {
            receiptInfo receipt;

            receipt.price = receiptEl->FloatAttribute("price");
            receipt.ticks = receiptEl->UnsignedAttribute("ticks");
            receipt.name  = receiptEl->Attribute("name");

            if(receiptEl->FirstChildElement("input"))
                for(XMLElement *inputEl = receiptEl->FirstChildElement("input")->FirstChildElement("item"); inputEl; inputEl = inputEl->NextSiblingElement())
                {
                    productInfo item;
                    item.id = getItemIdByCode(inputEl->Attribute("id"));
                    item.amount = inputEl->FloatAttribute("amount");

                    receipt.input.push_back(item);
                }

            if(receiptEl->FirstChildElement("output"))
                for(XMLElement *outputEl = receiptEl->FirstChildElement("output")->FirstChildElement("item"); outputEl; outputEl = outputEl->NextSiblingElement())
                {
                    productInfo item;
                    item.id = getItemIdByCode(outputEl->Attribute("id"));
                    item.amount = outputEl->FloatAttribute("amount");

                    receipt.output.push_back(item);
                }

            receipts.push_back(receipt);
        }
    }
    else
        throw std::runtime_error("Invalid items file");

    for(auto &i: receipts)
        receiptNames.push_back(i.name.c_str());
}

uint32_t getItemIdByCode(const std::string &id)
{
    for(uint32_t i = 0; i < items.size(); i++)
        if(id == items[i].code)
            return i;

    throw std::runtime_error(id+" item not found");
}

const itemInfo *getItemById(uint32_t id)
{
    return &items[id];
}

uint32_t itemsCount()
{
    return items.size();
}

const char* const* getReceiptNames()
{
    return receiptNames.data();
}

}
