#include "tinyxml2.h"
#include "statistic.h"

using namespace tinyxml2;

namespace game {

Statistic::Statistic()
{
    Load();
}

Statistic::~Statistic()
{
    Clear();
}

void Statistic::Clear()
{
    for (auto i = data.begin(); i != data.end(); i++) {
        delete i->second;
    }

    data.clear();
}

void Statistic::Load()
{
    XMLDocument doc;
    if (doc.LoadFile("statistic.xml") != XML_SUCCESS) {
        return;
    }

    Clear();

    for (XMLElement *e = doc.RootElement()->FirstChildElement(); e; e = e->NextSiblingElement()) {
        levelStatistic *temp = new levelStatistic;
        temp->grade = e->FloatAttribute("grade", 0);
        temp->score = e->IntAttribute("score", 0);
        temp->maxCombo = e->IntAttribute("max-combo", 0);
        temp->played = e->IntAttribute("played", 0);

        data[e->Attribute("id")] = temp;
    }
}

void Statistic::Save()
{
    XMLDocument doc;

    XMLElement *root = doc.NewElement("data");

    doc.InsertEndChild(root);

    for (auto i = data.begin(); i != data.end(); i++) {
        XMLElement *info = doc.NewElement("level");

        info->SetAttribute("id", i->first.c_str());
        info->SetAttribute("grade", i->second->grade);
        info->SetAttribute("score", i->second->score);
        info->SetAttribute("max-combo", i->second->maxCombo);
        info->SetAttribute("played", i->second->played);

        root->InsertEndChild(info);
    }

    doc.SaveFile("statistic.xml", true);
}

const levelStatistic *Statistic::GetLevelStatistic(const std::string &id)
{
    auto i = data.find(id);

    if (i == data.end()) {
        return nullptr;
    }

    return i->second;
}

void Statistic::GetLevelStatistic(const std::string &id, levelStatistic *out)
{
    auto i = data.find(id);

    if (i == data.end()) {
        memset(out, 0, sizeof(levelStatistic));
    } else {
        memcpy(out, i->second, sizeof(levelStatistic));
    }
}

void Statistic::SetLevelStatistic(const std::string &id, const levelStatistic *stats)
{
    auto i = data.find(id);

    if (i == data.end()) {
        levelStatistic *ptr = new levelStatistic;
        data[id] = ptr;
        memcpy(ptr, stats, sizeof(levelStatistic));
    } else {
        levelStatistic *ptr = i->second;

        ptr->grade = std::max(ptr->grade, stats->grade);
        ptr->maxCombo = std::max(ptr->maxCombo, stats->maxCombo);
        ptr->score = std::max(ptr->score, stats->score);
        ptr->played = stats->played;
    }
}

}
