/*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 "TextMenu.hpp"

TextMenu::TextMenu() : Menu(), m_button(NULL), m_space(10), m_orientation(0), m_browsed(false)
{
    
}

TextMenu::TextMenu(const TextButton &button, float space, int orientation) :
Menu(), m_button(&button), m_space(space), m_orientation(orientation), m_browsed(false)
{
    
}

TextMenu::TextMenu(const TextButton &button, float space, int orientation, float width, float height, const Color &color) :
Menu(width, height, color), m_button(&button), m_space(space), m_orientation(orientation), m_browsed(false)
{
    
}

void TextMenu::draw()
{
    //Update matrix
    Drawable::pushMatrix();
    Drawable::updateMatrix();
    
    m_background.draw();
    
    for (unsigned int i = 0; i < m_buttonsList.size(); i++)
        m_buttonsList[i].draw();
    
    Drawable::popMatrix();
}

void TextMenu::launch()
{
    //Clearing possible selections
    m_selections.clear();
    m_browsed = false;
    
    //Drawing root elements
    Menu::resetCurrentElement();
    draw(m_currentElement);
}

bool TextMenu::mouseClick(const Vector &mouseCoords)
{
    Vector localMouse = Widget::localCoords(mouseCoords);
    
    //Browse the list
    for (unsigned int i = 0; i < m_buttonsList.size(); i++)
    {
        if (m_buttonsList[i].mouseClick(localMouse)) //Button clicked
        {
            std::string buttonString = m_buttonsList[i].getText();
            
            //Search the matching TinyXML element
            while (m_currentElement)
            {
                std::string itemName = m_currentElement->Attribute("content");
                std::string itemId = m_currentElement->Attribute("id");
                
                if (itemName == buttonString) //Found
                {
                    //Register selection in m_selections
                    m_selections.push_back(itemId);
                    
                    if (m_currentElement->NoChildren()) //Selection ended
                        m_browsed = true;
                    else //Continue browsing
                    {
                        //Draw next items
                        m_currentElement = m_currentElement->FirstChildElement();
                        draw(m_currentElement);
                    }
                    
                    return true; //End the fonction now
                }
                
                m_currentElement = m_currentElement->NextSiblingElement();
            }
        }
    }
    
    return false;
}

bool TextMenu::mouseMove(const Vector &mouseCoords)
{
    Vector localMouse = Widget::localCoords(mouseCoords);
    
    for (unsigned int i = 0; i < m_buttonsList.size(); i++)
        m_buttonsList[i].mouseMove(localMouse);
    
    return Widget::contains(localMouse);
}

bool TextMenu::browsed() const
{
    return m_browsed;
}

const std::vector<std::string> &TextMenu::result() const
{
    return m_selections;
}

void TextMenu::draw(TiXmlElement *itemsList)
{
    if (m_button != NULL)
    {
        m_buttonsList.clear();
        
        int i = 0;
        while (itemsList)
        {
            std::string itemName = itemsList->Attribute("content");
            
            TextButton itemButton = (*m_button);
            itemButton.setText(itemName);
            
            if (m_orientation == 0)
                itemButton.setPosition( (m_width - contentWidth()) / 2 , 20 + i * (itemButton.getHeight() + m_space) );
            else if (m_orientation == 1)
                itemButton.setPosition( 20 + i * (itemButton.getWidth() + m_space), (m_height - contentHeight()) / 2 );
            
            m_buttonsList.push_back(itemButton);
            
            itemsList = itemsList->NextSiblingElement();
            i++;
        }
    }
}

float TextMenu::contentWidth() const
{
    float width = 0;
    
    if (m_button != NULL)
    {
        if (m_orientation == 0) //Menu is vertical
            width = m_button->getWidth();
        
        else if (m_orientation == 1) //Menu is Horizontal
            width = (m_button->getWidth() + m_space) * m_buttonsList.size();
    }
    
    return width;
}

float TextMenu::contentHeight() const
{
    float height = 0;
    
    if (m_button != NULL)
    {
        if (m_orientation == 0) //Menu is vertical
            height = (m_button->getHeight() + m_space) * m_buttonsList.size();
        
        else if (m_orientation == 1) //Menu is horizontal
            height = m_button->getHeight();
    }
    
    return height;
}

//Get and set methods
void TextMenu::setButton(const TextButton &button)
{
    m_button = &button;
    
    if (m_currentElement != NULL)
        draw(m_currentElement);
}

void TextMenu::setOrientation(int orientation)
{
    if (orientation == 0 || orientation == 1)
        m_orientation = orientation;
}

int TextMenu::getOrientation() const
{
    return m_orientation;
}

void TextMenu::setSpace(float space)
{
    m_space = space;
}

float TextMenu::getSpace() const
{
    return m_space;
}
