#include "CAuiMeter.hpp"

namespace urde
{

CAuiMeter::CAuiMeter(const CGuiWidgetParms& parms, bool noRoundUp,
                     u32 maxCapacity, u32 workerCount)
: CGuiGroup(parms, 0, false), xc4_noRoundUp(noRoundUp),
  xc8_maxCapacity(maxCapacity), xcc_capacity(maxCapacity)
{
    xd4_workers.reserve(workerCount);
}

void CAuiMeter::UpdateMeterWorkers()
{
    float scale = xd4_workers.size() / float(xc8_maxCapacity);

    int etankCap;
    if (xc4_noRoundUp)
        etankCap = xcc_capacity * scale;
    else
        etankCap = xcc_capacity * scale + 0.5f;

    int etankFill;
    if (xc4_noRoundUp)
        etankFill = xd0_value * scale;
    else
        etankFill = xd0_value * scale + 0.5f;

    for (int i=0 ; i<xd4_workers.size() ; ++i)
    {
        CGuiGroup* worker = xd4_workers[i];
        if (!worker)
            continue;

        CGuiWidget* fullTank = worker->GetWorkerWidget(0);
        CGuiWidget* emptyTank = worker->GetWorkerWidget(1);

        if (i < etankFill)
        {
            if (fullTank)
                fullTank->SetIsVisible(true);
            if (emptyTank)
                emptyTank->SetIsVisible(false);
        }
        else if (i < etankCap)
        {
            if (fullTank)
                fullTank->SetIsVisible(false);
            if (emptyTank)
                emptyTank->SetIsVisible(true);
        }
        else
        {
            if (fullTank)
                fullTank->SetIsVisible(false);
            if (emptyTank)
                emptyTank->SetIsVisible(false);
        }
    }
}

void CAuiMeter::OnVisibleChange()
{
    if (GetIsVisible())
        UpdateMeterWorkers();
}

void CAuiMeter::SetCurrValue(s32 val)
{
    xd0_value = zeus::clamp(0, val, xcc_capacity);
    UpdateMeterWorkers();
}

void CAuiMeter::SetCapacity(s32 cap)
{
    xcc_capacity = zeus::clamp(0, cap, xc8_maxCapacity);
    xd0_value = std::min(xcc_capacity, xd0_value);
    UpdateMeterWorkers();
}

void CAuiMeter::SetMaxCapacity(s32 cap)
{
    xc8_maxCapacity = std::max(0, cap);
    xcc_capacity = std::min(xc8_maxCapacity, xcc_capacity);
    xd0_value = std::min(xcc_capacity, xd0_value);
    UpdateMeterWorkers();
}

CGuiWidget* CAuiMeter::GetWorkerWidget(int id) const
{
    return xd4_workers[id];
}

bool CAuiMeter::AddWorkerWidget(CGuiWidget* worker)
{
    CGuiGroup::AddWorkerWidget(worker);
    if (worker->GetWorkerId() >= xd4_workers.size())
        xd4_workers.resize(worker->GetWorkerId() + 1);
    xd4_workers[worker->GetWorkerId()] = static_cast<CGuiGroup*>(worker);
    return true;
}

std::shared_ptr<CGuiWidget> CAuiMeter::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp)
{
    CGuiWidgetParms parms = ReadWidgetHeader(frame, in);
    in.readBool();
    bool noRoundUp = in.readBool();
    u32 maxCapacity = in.readUint32Big();
    u32 workerCount = in.readUint32Big();
    std::shared_ptr<CAuiMeter> ret = std::make_shared<CAuiMeter>(parms, noRoundUp, maxCapacity, workerCount);
    ret->ParseBaseInfo(frame, in, parms);
    return ret;
}

}