// ---------------------------------------------------------------------------
// 
//   Lily Engine alpha
// 
//   Copyright (c) 2010 Clifford Jolly
//     http://cliffjolly.com
//     cliff@cliffjolly.com
// 
// ---------------------------------------------------------------------------
// 
//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation; either version 2 of the License, or
//   (at your option) any later version.
//  
//   This program is distributed in the hope that it will be useful, but
//   WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
//   General Public License for more details.
// 
//   You should have received a copy of the GNU General Public License
//   along with this program; if not, write to the Free Software
//   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
//   USA
// -------------------------- END HEADER -------------------------------------

#include <iostream>
using namespace std;

#include "../filesystem/filesystem.h"
#include "../parser/parser.h"
#include "../texturemanager/texturemanager.h"
#include "../console/console.h"

using namespace LilyParser;
using namespace Console;

#include "input.h"
#include "engineui.h"
#include "config.h"
#include "world.h"

void loadConfig(const std::string &gameName, World *world) {

    if(!gameName.size()) {
        return;
    }

    string parserFileName = gameName + ".cfg";
    string realParserFileName;

    if(FileSystem::fileExists(parserFileName)) {

        // Saved config.
        realParserFileName = parserFileName;

    } else if(FileSystem::fileExists("games/" + gameName + "/default.cfg")) {

        // Default config.
        realParserFileName = "games/" + gameName + "/default.cfg";
    }


    // Load the file.
    string errStr;
    ParserNode *rootNode = LilyParser::loadAndParse(realParserFileName, &errStr);
    if(!rootNode) {
        out("error") << "Config load error in " << realParserFileName << ": " << errStr << endl;
        return;
    }


    // Load input binds.
    ParserNode *inputNode = rootNode->getChildByName("input");
    if(inputNode) {
        inputLoadBindsFromParserNode(inputNode);
    }

    // Load sound settings.
    ParserNode *audioNode = rootNode->getChildByName("audio");
    
    if(audioNode) {

        float soundVolume = 0;
        float musicVolume = 0;

        audioNode->getFloatValue("soundVolume", &soundVolume);
        audioNode->getFloatValue("musicVolume", &musicVolume);

        if(soundVolume > 1) soundVolume = 1;
        if(soundVolume < 0) soundVolume = 0;
        if(musicVolume > 1) musicVolume = 1;
        if(musicVolume < 0) musicVolume = 0;

        world->soundResourceManager.setSoundVolume(soundVolume);
        world->soundResourceManager.setMusicVolume(musicVolume);
    }

    // Load video settings.
    ParserNode *videoNode = rootNode->getChildByName("video");

    if(videoNode) {
        
        bool shadersEnabled = 1;
        bool lightingEnabled = 1;

        videoNode->getBooleanValue("shadersEnabled", &shadersEnabled);
        videoNode->getBooleanValue("lightingEnabled", &lightingEnabled);

        world->setLighting(lightingEnabled);
        
        TextureManager *manager = TextureManager::get();
        manager->setShadersEnabled(shadersEnabled);

    }

    delete rootNode;

}

void saveConfig(const std::string &gameName, World *world) {

    if(!gameName.size()) {
        return;
    }

    // Input config.
    ParserNode *inputNode = inputSaveBindsToParserNode();

    // Audio config.
    ParserNode *audioNode = new ParserNode("audio");

    float soundVolume = world->soundResourceManager.getSoundVolume();
    float musicVolume = world->soundResourceManager.getMusicVolume();

    audioNode->setFloatValue("soundVolume", soundVolume);
    audioNode->setFloatValue("musicVolume", musicVolume);

    // Video config.

    ParserNode *videoNode = new ParserNode("video");

    TextureManager *manager = TextureManager::get();

    videoNode->setBooleanValue("shadersEnabled", manager->getShadersEnabled());
    videoNode->setBooleanValue("lightingEnabled", world->getLighting());

    // Make a new doc. (ParserNode)
    ParserNode *root = new ParserNode();
    root->addChildToEnd(inputNode);
    root->addChildToEnd(audioNode);
    root->addChildToEnd(videoNode);

    // Write it out.
    string parserBuffer = root->toString();
    FileSystem::saveFile(gameName + ".cfg", parserBuffer.c_str(), parserBuffer.size());

}

