/*Copyright (C) 2010-2023 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 "RoundResultInfo.hpp"
#include "Graphics/Resources/Font.hpp"
#include "Engines/Resources/TextureManager.hpp"

#include "PlayerIcon.hpp"
#include "Tools/ScaledPixel.hpp"
#include "Tools/I18n.hpp" ///< _ macro for i18n

namespace
{
    constexpr float ICON_TEXT_SPACE = 20.f;
    constexpr float PLAYER_RESULTS_SCALE = 2.f;
}

RoundResultInfo::RoundResultInfo(const Vector &viewSize) :
Drawable(), m_text(ScaledPixel{viewSize.x}(4.f)),
m_results(ScaledPixel{viewSize.x}(60.f),
          ScaledPixel{viewSize.x}(16.f),
          ScaledPixel{viewSize.x}(2.f)),
m_textureManager(nullptr), m_viewSize(viewSize), m_status(Status::Deactivated)
{
    m_text.setColor(Color(255, 255, 255), Color(50, 93, 151));
    m_results.setScale(PLAYER_RESULTS_SCALE);
}

void RoundResultInfo::draw()
{
    if (m_status != Status::Deactivated)
    {
        //Update matrix
        Drawable::pushMatrix();
        Drawable::updateMatrix();

        if (m_status == Status::PlayerWin)
        {
            m_icon.draw();
            m_results.draw();
        }

        m_text.draw();

        Drawable::popMatrix();
    }
}

void RoundResultInfo::setResources(Font &font, TextureManager &textureManager)
{
    m_textureManager = &textureManager;
    m_text.setFont(font);
}

void RoundResultInfo::activate(const Utf8::utf8_string &winnerUsername,
                               const std::string &character,
                               std::uint8_t wonRounds,
                               std::uint8_t roundsToWin)
{
    activateWinner(_f(RoundResultNetworkedWinner,
                      std::make_pair("username", winnerUsername.get())),
                   character, wonRounds, roundsToWin);
}

void RoundResultInfo::activate(const std::size_t &winnerId,
                               const std::string &character,
                               std::uint8_t wonRounds,
                               std::uint8_t roundsToWin)
{
    activateWinner(_f(RoundResultLocalWinner,
                      std::make_pair("name", character),
                      std::make_pair("player_id", winnerId)),
                   character, wonRounds, roundsToWin);
}

void RoundResultInfo::activateWinner(const std::string &winText,
                                     const std::string &character,
                                     std::uint8_t wonRounds,
                                     std::uint8_t roundsToWin)
{
    const ScaledPixel sp(m_viewSize.x);

    if (m_textureManager != nullptr)
    {
        m_icon = PlayerIcon::load(character, (*m_textureManager));
        m_icon.setScale(sp.lower(1.f, 1.f));
    }

    m_text.setText(winText);
    m_text.setXPosition(m_icon.getWidth() * m_icon.getXScale() +
                        sp(ICON_TEXT_SPACE));

    if (roundsToWin > 1)
    {
        m_results.reset(roundsToWin, wonRounds);
        m_results.setPosition(
            (m_icon.getWidth() * m_icon.getXScale() - sp(100.f)) / 2.f,
            m_icon.getHeight() * m_icon.getYScale());

        m_text.setYPosition((m_icon.getHeight() * m_icon.getYScale() +
                            (m_results.getHeight() * sp(PLAYER_RESULTS_SCALE)) -
                             m_text.getHeight()) * .6f);
    }
    else //Do not show the player result disk for single round games
    {
        m_results.reset(0);
        m_text.setYPosition((m_icon.getHeight() * m_icon.getYScale() -
                             m_text.getHeight()) * .6f);
    }

    m_status = Status::PlayerWin;
}

void RoundResultInfo::activateDraw()
{
    m_text.setText(_(RoundResultDrawGame));
    m_text.setPosition(0.f, 0.f);

    m_status = Status::DrawGame;
}

void RoundResultInfo::positionToCenter()
{
    setPosition((m_viewSize.x - getWidth()) / 2.f,
            (m_viewSize.y - m_text.getHeight()) * .4f - m_text.getYPosition());
}

void RoundResultInfo::deactivate()
{
    m_status = Status::Deactivated;
}

float RoundResultInfo::getWidth() const
{
    return (m_status != Status::PlayerWin) ? m_text.getWidth() :
        m_icon.getWidth() * m_icon.getXScale() +
        ScaledPixel{m_viewSize.x}(ICON_TEXT_SPACE) + m_text.getWidth();
}

float RoundResultInfo::getTextBottomLine() const
{
    return m_text.getYPosition() + m_text.getHeight();
}
