/*Copyright (C) 2010 Deveaux Duncan

This file is part of Hikou no mizu.

Hikou no mizu 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 3 of the License, or
(at your option) any later version.

Hikou no mizu 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 Hikou no mizu.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "Configuration.hpp"

Configuration::Configuration() :
m_videoMode( sf::VideoMode(1024, 576, 32) ), m_windowStyle( sf::Style::Default ),
m_soundVolume(100)
{
    m_playerKeys[0] = PlayerKeys(); //Player 1 : Default keys
    m_playerKeys[1] = PlayerKeys(sf::Keyboard::P, sf::Keyboard::Up, sf::Keyboard::Left, sf::Keyboard::Right); //Player 2 : Other keys
    
    m_cfgDirectory = Directory::getHome() + "/.hikounomizu/";
}

void Configuration::load()
{
    //Main configuration
    ConfReader mainCfgReader;
    if (mainCfgReader.load(m_cfgDirectory + "main.cfg"))
    {
        //Init variables
        int windowWidth, windowHeight, soundVolume;
        bool fullscreen;
        
        //Get elements
        if (mainCfgReader.getIntItem("window_width", windowWidth) && mainCfgReader.getIntItem("window_height", windowHeight))
        {
            sf::VideoMode requestedMode(windowWidth, windowHeight, 32);
            setVideoMode(requestedMode);
        }
        
        if (mainCfgReader.getBoolItem("fullscreen", fullscreen))
        {
            if (fullscreen)
                setWindowStyle(sf::Style::Fullscreen);
            else
                setWindowStyle(sf::Style::Default);
        }
        
        if (mainCfgReader.getIntItem("sound_volume", soundVolume))
            setSoundVolume(soundVolume);
    }
    
    //Keys configuration
    ConfReader keysCfgReader;
    
    bool browsing = true;
    int i = 0;
    while (browsing)
    {
        std::ostringstream keysFilePath;
        keysFilePath << m_cfgDirectory << "keys/player" << i << ".cfg";
        
        if (keysCfgReader.load(keysFilePath.str()))
        {
            PlayerKeys keys;
            
            //Init variables
            sf::Keyboard::Key attack, jump, moveLeft, moveRight;
            
            if (keysCfgReader.getKeyCodeItem("attack", attack))
                keys.setAttackKey(attack);
            
            if (keysCfgReader.getKeyCodeItem("jump", jump))
                keys.setJumpKey(jump);
            
            if (keysCfgReader.getKeyCodeItem("moveLeft", moveLeft))
                keys.setMoveLeftKey(moveLeft);
            
            if (keysCfgReader.getKeyCodeItem("moveRight", moveRight))
                keys.setMoveRightKey(moveRight);
            
            setPlayerKeys(i, keys);
        }
        else
            browsing = false;
        
        i++;
    }
}

void Configuration::save()
{
    //Create directories if needed
    Directory::create(m_cfgDirectory);
    Directory::create(m_cfgDirectory + "keys/");
    
    //Main configuration
        //Init variables
    int windowWidth = m_videoMode.Width;
    int windowHeight = m_videoMode.Height;
    int soundVolume = m_soundVolume;
    bool fullscreen = false;
    
    if (m_windowStyle == sf::Style::Fullscreen)
        fullscreen = true;
    
        //Set elements
    ConfWriter mainCfgWriter;
    mainCfgWriter.addIntItem("window_width", windowWidth);
    mainCfgWriter.addIntItem("window_height", windowHeight);
    mainCfgWriter.addBoolItem("fullscreen", fullscreen);
    mainCfgWriter.addIntItem("sound_volume", soundVolume);
    
    mainCfgWriter.writeFile(m_cfgDirectory + "main.cfg");
    
    //Keys configuration
    int i = 0;
    std::map<unsigned int, PlayerKeys>::iterator it;
    for (it = m_playerKeys.begin(); it != m_playerKeys.end(); it++)
    {
        //Init variables
        sf::Keyboard::Key attack = it->second.getAttackKey();
        sf::Keyboard::Key jump = it->second.getJumpKey();
        sf::Keyboard::Key moveLeft = it->second.getMoveLeftKey();
        sf::Keyboard::Key moveRight = it->second.getMoveRightKey();
        
        //Set elements
        ConfWriter keysCfgWriter;
        keysCfgWriter.addIntItem("attack", attack);
        keysCfgWriter.addIntItem("jump", jump);
        keysCfgWriter.addIntItem("moveLeft", moveLeft);
        keysCfgWriter.addIntItem("moveRight", moveRight);
        
        std::ostringstream keysFilePath;
        keysFilePath << m_cfgDirectory << "keys/player" << i << ".cfg";
        
        keysCfgWriter.writeFile(keysFilePath.str());
        
        i++;
    }
}

//Get and set methods
    //Video
void Configuration::setVideoMode(const sf::VideoMode &videoMode)
{
    if (m_windowStyle != sf::Style::Fullscreen || videoMode.IsValid())
        m_videoMode = videoMode;
}

const sf::VideoMode &Configuration::getVideoMode() const
{
    return m_videoMode;
}

void Configuration::setWindowStyle(unsigned long windowStyle)
{
    if (windowStyle != sf::Style::Fullscreen || m_videoMode.IsValid())
        m_windowStyle = windowStyle;
}

unsigned long Configuration::getWindowStyle() const
{
    return m_windowStyle;
}

    //Audio
void Configuration::setSoundVolume(float soundVolume)
{
    if (soundVolume >= 0 && soundVolume <= 100)
        m_soundVolume = soundVolume;
}

float Configuration::getSoundVolume() const
{
    return m_soundVolume;
}

    //Keys binding
void Configuration::setPlayerKeys(unsigned int ix, const PlayerKeys &playerKeys)
{
    m_playerKeys[ix] = playerKeys;
}

bool Configuration::getPlayerKeys(unsigned int ix, PlayerKeys &target) const
{
    std::map<unsigned int, PlayerKeys>::const_iterator it = m_playerKeys.find(ix);
    
    if (it != m_playerKeys.end())
    {
        target = it->second;
        return true;
    }
    
    return false;
}