#include "CSettingManager.h"

CSettingManager::CSettingManager(const core::stringw settings_file,IrrlichtDevice* device)
{
    xml_file=settings_file;
    MenuDevice=device;

    //some resolution options
    ResolutionOptions.insert(L"640x480", core::dimension2du(640,480));
    ResolutionOptions.insert(L"800x600", core::dimension2du(800,600));
    ResolutionOptions.insert(L"1024x768", core::dimension2du(1024,768));
    ResolutionOptions.insert(L"1280x960", core::dimension2du(1280,960));
    //our preferred defaults
    //SettingMap.insert(L"resolution", L"1024x768");
    //SettingMap.insert(L"fullscreen", L"0"); //0 is false
}

//Exemple
/*<?xml version="1.0"?>
<mygame>
	<video>
		<setting name="driver" value="Direct3D9">
		<setting name="fullscreen" value="0">
		<setting name="resolution" value="1024x768">
	</video>
</mygame>*/
bool CSettingManager::Load()
{
	xml_document<> doc;
    std::string input_xml;
    std::string line;
	std::ifstream settingfile ("settings.xml");
	// read file into input_xml
    while(getline(settingfile,line)) {
        input_xml += line;
        //printf("ajout ligne %s\n",line);
    }

    settingfile.close();

    //doc.parse<0>(&content[0]);

    //printf("content %s\n",input_xml);

    // make a safe-to-modify copy of input_xml
    // (you should never modify the contents of an std::string directly)
    std::vector<char> xml_copy(input_xml.begin(), input_xml.end());
    xml_copy.push_back('\0');
    doc.parse<parse_validate_closing_tags>(&xml_copy[0]);

	// Find our root node
	xml_node<> *pRoot = doc.first_node(); //node mygame
	//Recup node video
	xml_node<> *pVideo = pRoot->first_node("video"); //node mygame
	// Iterate over the brewerys
    for(xml_node<> *pNode=pVideo->first_node("setting"); pNode; pNode=pNode->next_sibling())
    {
        xml_attribute<> *pAttr1 = pNode->first_attribute("name");
        xml_attribute<> *pAttr2= pNode->last_attribute("value");

        //printf("Attr name= %s\n",pAttr1->value());
        //printf("Attr value= %s\n",pAttr2->value());

        //if(pAttr1->value()=="fullscreen") {
        if(strcmp(pAttr1->value(),"fullscreen")==0) {
             //printf("**Attr fullscreen %s\n",pAttr2->value());
             SettingMap[L"fullscreen"] = pAttr2->value();
        }

        //if(pAttr1->value()=="resolution") {
        if(strcmp(pAttr1->value(),"resolution")==0) {
             //printf("**Attr resolution %s\n",pAttr2->value());
             SettingMap[L"resolution"] = core::stringw(pAttr2->value());
        }
    }
    return true;
}

bool CSettingManager::Save()
{
	//if not able to create device don't attempt to save
    if (!MenuDevice)
        return false;

    std::ofstream file_stored("settings.xml");
    file_stored << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl;
    file_stored << "<mygame>" << std::endl;
    file_stored << "<video>" << std::endl;

    core::map<core::stringw, core::stringw>::Iterator i = SettingMap.getIterator();
    for(; !i.atEnd(); i++)
    {
        //xwriter->writeElement(L"setting",false, L"name", i->getKey().c_str(), L"value",i->getValue().c_str() );
        std::wstring wsName(i->getKey().c_str());
        std::string strName(wsName.begin(), wsName.end());

        std::wstring wsValue(i->getValue().c_str());
        std::string strValue(wsValue.begin(), wsValue.end());

        file_stored << "<setting name=\"" <<  strName << "\" value=\"" << strValue << "\"></setting>" << std::endl;
    }

    file_stored << "</video>" << std::endl;
    file_stored << "</mygame>" << std::endl;
    file_stored.close();

    return true;
}

// Set setting in our manager
void CSettingManager::setSetting(const core::stringw& name, const core::stringw& value)
{
    SettingMap[name]=value;
}

// set setting overload to quickly assign integers to our setting map
void CSettingManager::setSetting(const core::stringw& name, s32 value)
{
    SettingMap[name]=core::stringw(value);
}

// Get setting as string
core::stringw CSettingManager::getSetting(const core::stringw& key) const
{
    //the find function or irrmap returns a pointer to a map Node
    //if the key can be found, otherwise it returns null
    //the map node has the function getValue and getKey, as we already know the key, we return node->getValue()
    core::map<core::stringw, core::stringw>::Node* n = SettingMap.find(key);
    if (n)
        return n->getValue();
    else
        return L"";
}

//
bool CSettingManager::getSettingAsBoolean(const core::stringw& key ) const
{
    core::stringw s = getSetting(key);
    if (s.empty())
        return false;
    return s.equals_ignore_case(L"1");
}

//
s32 CSettingManager::getSettingAsInteger(const core::stringw& key) const
{
    //we implicitly cast to string instead of stringw because strtol10 does not accept wide strings
    const core::stringc s = getSetting(key);
    if (s.empty())
        return 0;

    return core::strtol10(s.c_str());
}

CSettingManager::~CSettingManager()
{

}
