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

/////////////////////
///RoundResultDisk///
/////////////////////
PlayerResults::RoundResultDisk::RoundResultDisk(float diskDiameter,
                                                float diskBorderSize) :
Drawable(),
m_background(Polygon::circle(diskDiameter / 2.f, 16,
                             Color(0, 0, 0, 60),
                             Color(255, 255, 255))),
m_fill(Polygon::circle(diskDiameter / 2.f, 16, Color(255, 255, 255, 180))),
m_wonRound(false)
{
    m_background.setBorderSize(diskBorderSize);
    m_fill.setBorderSize(0.f);
}

void PlayerResults::RoundResultDisk::draw()
{
    //Update matrix
    Drawable::pushMatrix();
    Drawable::updateMatrix();

    m_background.draw();

    if (m_wonRound)
        m_fill.draw();

    Drawable::popMatrix();
}

void PlayerResults::RoundResultDisk::setToWon()
{
    m_wonRound = true;
}

///////////////////
///PlayerResults///
///////////////////
PlayerResults::PlayerResults(float width,
                             float diskDiameter, float diskBorderSize) :
Drawable(), m_winCount(0), m_width(width),
m_diskDiameter(diskDiameter), m_diskBorderSize(diskBorderSize)
{

}

void PlayerResults::reset(std::uint8_t roundsToWin, std::uint8_t wonRounds)
{
    m_winCount = 0;
    m_results.clear();

    if (roundsToWin > 0)
    {
        m_results.reserve(roundsToWin);

        //Position result disks
        const float diskOffset = m_diskDiameter + m_diskBorderSize * 2.f;
        const float offset =
            (static_cast<float>(roundsToWin) * diskOffset > m_width) ?
                m_width / static_cast<float>(roundsToWin) : diskOffset;

        for (std::size_t i = 0; i < roundsToWin; i++)
        {
            m_results.emplace_back(m_diskDiameter, m_diskBorderSize);
            m_results.back().setXPosition(static_cast<float>(i) * offset);
        }

        //Initialize any already won round
        for (std::uint8_t j = 0; j < wonRounds; j++)
            addRoundWin();
    }
}

void PlayerResults::draw()
{
    //Update matrix
    Drawable::pushMatrix();
    Drawable::updateMatrix();

    for (RoundResultDisk &result : m_results)
        result.draw();

    Drawable::popMatrix();
}

void PlayerResults::addRoundWin()
{
    if (m_winCount < m_results.size())
        m_results[m_winCount++].setToWon();
}

float PlayerResults::getWidth() const
{
    return m_width;
}

float PlayerResults::getHeight() const
{
    return m_diskDiameter;
}
