/*Copyright (C) 2010-2020 Duncan Deveaux

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 "MainTab.hpp"

#define TOP_SPACE 20
#define LEFT_SPACE 20

MainTab::MainTab(Font &labelFont, const Configuration &configuration, TextureManager &manager, SoundEngine &soundEngine, const std::vector<Vector> &displayModes, float width, float height, const Color &color) :
Tab(width, height, color), m_labelFont(NULL), m_horizontalSpace(0)
{
    setLabelFont(labelFont);
    
    //Fullscreen mode checkbox
    m_fullscreen = Checkbox(configuration.getFullscreen());
    m_fullscreen.setColor( Color(27, 66, 119) );
    m_fullscreen.setSoundEngine(soundEngine);
    m_fullscreen.setClickSound("sound/ui/menuClick.ogg");
    
    //Dynamic camera checkbox
    m_dynamicCamera = Checkbox(configuration.isCameraDynamic());
    m_dynamicCamera.setColor( Color(27, 66, 119) );
    m_dynamicCamera.setSoundEngine(soundEngine);
    m_dynamicCamera.setClickSound("sound/ui/menuClick.ogg");
    
    //Debug mode checkbox
    m_debugMode = Checkbox(configuration.getDebugMode());
    m_debugMode.setColor( Color(27, 66, 119) );
    m_debugMode.setSoundEngine(soundEngine);
    m_debugMode.setClickSound("sound/ui/menuClick.ogg");
    
    //Resolution chooser
    std::vector<std::string> items;
    
    unsigned int defaultItem = 0;
    for (unsigned int i = 0; i < displayModes.size(); i++)
    {
        if (displayModes[i].x == configuration.getWindowWidth() && displayModes[i].y == configuration.getWindowHeight())
            defaultItem = i;
        
        std::ostringstream itemText;
        itemText << displayModes[i].x << "x" << displayModes[i].y;
        
        items.push_back(itemText.str());
    }
    
    Sprite chooser_default( (*manager.getTexture("gfx/ui/ui.png")), Box(0, 0, 240.f / 512, 60.f / 512) ),
    chooser_hover( (*manager.getTexture("gfx/ui/ui.png")), Box(0, 64.f / 512, 240.f / 512, 60.f / 512) );
    
    SkinBox skin(120.f, 30.f, chooser_default, chooser_hover);
    SkinSound sounds(soundEngine, "sound/ui/menuFocus.ogg", "sound/ui/menuClick.ogg");
    
    TextButton chooser_button(skin, sounds);
    
    chooser_button.setTextFont(*m_labelFont);
    chooser_button.setTextColor(Color(255, 255, 255));
    
    m_resolution = Chooser(chooser_button, items, defaultItem);
    
    //Adding widgets
    addWidget("Fullscreen :", m_fullscreen, 0);
    addWidget("Resolution :", m_resolution, 3);
    addWidget("Dynamic Camera :", m_dynamicCamera, 5);
    addWidget("Debug :", m_debugMode, 3);
}

void MainTab::draw()
{
    //Update matrix
    Drawable::pushMatrix();
    Drawable::updateMatrix();
    
    m_background.draw();
    
    std::vector< std::pair<Text, Widget*> >::iterator it;
    for (it = m_widgetsList.begin(); it != m_widgetsList.end(); it++)
    {
        it->first.draw();
        it->second->draw();
    }
    
    Drawable::popMatrix();
}

bool MainTab::mouseClick(const Vector &mouseCoords)
{
    Vector localMouse = Widget::localCoords(mouseCoords);
    
    m_fullscreen.mouseClick(localMouse);
    
    if (m_fullscreen.isChecked())
        m_resolution.mouseClick(localMouse);
    
    m_dynamicCamera.mouseClick(localMouse);
    m_debugMode.mouseClick(localMouse);
    
    return Widget::contains(localMouse);
}

bool MainTab::mouseMove(const Vector &mouseCoords)
{
    Vector localMouse = Widget::localCoords(mouseCoords);
    
    m_fullscreen.mouseMove(localMouse);
    
    if (m_fullscreen.isChecked())
        m_resolution.mouseMove(localMouse);
    
    m_dynamicCamera.mouseMove(localMouse);
    m_debugMode.mouseMove(localMouse);
    
    return Widget::contains(localMouse);
}

void MainTab::apply(Configuration &configuration)
{
    configuration.setFullscreen(m_fullscreen.isChecked());
    
    if (m_fullscreen.isChecked())
    {
        std::string result = m_resolution.getData()[m_resolution.getSelection()];
        std::istringstream splitResult(result);
        
        std::string str_width, str_height;
        std::getline(splitResult, str_width, 'x');
        std::getline(splitResult, str_height, 'x');
        
        int width, height;
        std::istringstream convertWidth(str_width), convertHeight(str_height);
        convertWidth >> width;
        convertHeight >> height;
        
        configuration.setWindowWidth(width);
        configuration.setWindowHeight(height);
    }
    else
    {
        configuration.setWindowWidth(1024);
        configuration.setWindowHeight(576);
    }
    
    configuration.setCameraDynamic(m_dynamicCamera.isChecked());
    configuration.setDebugMode(m_debugMode.isChecked());
}

void MainTab::setLabelFont(Font &font)
{
    m_labelFont = &font;
}

const Font *MainTab::getLabelFont() const
{
    return m_labelFont;
}

bool MainTab::addWidget(const std::string &label, Widget &widget, float space)
{
    if (m_labelFont != NULL)
    {
        Text labelText(label, *m_labelFont);
        m_widgetsList.push_back( std::make_pair(labelText, &widget) );
        
        if (labelText.getWidth() + 20 > m_horizontalSpace)
            m_horizontalSpace = labelText.getWidth() + 20;
        
        //Position
        float base = TOP_SPACE + space;
        if (m_widgetsList.size() > 1)
        {
            Widget *previousWidget = m_widgetsList[m_widgetsList.size() - 2].second;
            base = (previousWidget->getYPosition() + previousWidget->getHeight()) + space;
        }
        
        Text &addedLabel = m_widgetsList.back().first;
        Widget *addedWidget = m_widgetsList.back().second;
        
        addedLabel.setXPosition(LEFT_SPACE);
        addedLabel.setYPosition(base + (addedWidget->getHeight() - addedLabel.getHeight()) / 2);
        
        addedWidget->setXPosition(LEFT_SPACE + m_horizontalSpace);
        addedWidget->setYPosition(base);
        
        return true;
    }
    
    return false;
}
