#include "UIMLProgressAndStateView.h"

#include <Bild.h>
#include <DateiSystem.h>
#include <TextFeld.h>
#include <ToolTip.h>

#include "Globals.h"

#undef max

UIMLProgressAndStateView::UIMLProgressAndStateView(Framework::Text id,
    Framework::Text background,
    Framework::Text foreground,
    int* targetAddress,
    int addressLength,
    char registerMessage,
    char unregisterMessage,
    Framework::Text toolTipPrefix,
    Framework::Text toolTipSuffix)
    : Framework::Zeichnung(),
      NetworkAPIProcessor(),
      id(id),
      background(0),
      foreground(0),
      registerMessage(registerMessage),
      unregisterMessage(unregisterMessage),
      toolTipPrefix(toolTipPrefix),
      toolTipSuffix(toolTipSuffix),
      targetAddress(targetAddress),
      addressLength(addressLength),
      max(0),
      current(0)
{
    Framework::LTDBDatei file;
    file.setDatei(
        background.getTeilText(0, background.positionVon(".ltdb/") + 5));
    file.leseDaten(0);
    this->background = file.laden(
        0, background.getTeilText(background.positionVon(".ltdb/") + 6));
    file.setDatei(
        foreground.getTeilText(0, foreground.positionVon(".ltdb/") + 5));
    file.leseDaten(0);
    this->foreground = file.laden(
        0, foreground.getTeilText(foreground.positionVon(".ltdb/") + 6));
    char* msg = new char[id.getLength() + 6];
    msg[0] = registerMessage; // register progress/state observer
    msg[1] = (char)id.getLength();
    memcpy(msg + 2, id.getText(), id.getLength());
    *(int*)(msg + 2 + id.getLength()) = NetworkAPIProcessor::getId();
    World::INSTANCE->zClient()->componentAPIRequest(
        targetAddress, addressLength, msg, id.getLength() + 6);
    delete[] msg;
}

UIMLProgressAndStateView::~UIMLProgressAndStateView()
{
    char* msg = new char[id.getLength() + 6];
    msg[0] = unregisterMessage; // unregister fuel state observer
    msg[1] = (char)id.getLength();
    memcpy(msg + 2, id.getText(), id.getLength());
    *(int*)(msg + 2 + id.getLength()) = NetworkAPIProcessor::getId();
    World::INSTANCE->zClient()->componentAPIRequest(
        targetAddress, addressLength, msg, id.getLength() + 6);
    delete[] msg;
    if (background)
    {
        background->release();
    }
    if (foreground)
    {
        foreground->release();
    }
    delete[] targetAddress;
}

void UIMLProgressAndStateView::api(char* message)
{
    max = *(int*)message;
    current = *(int*)(message + 4);
    uiFactory.initParam.bildschirm->lock();
    lockZeichnung();
    Framework::Text toolTipText;
    toolTipText.append() << toolTipPrefix.getText() << current << " / " << max
                         << toolTipSuffix;
    if (!toolTip)
    {
        setToolTipText(toolTipText,
            uiFactory.initParam.bildschirm,
            uiFactory.initParam.schrift);
    }
    else
    {
        Framework::TextFeld* textField
            = dynamic_cast<Framework::TextFeld*>(toolTip->zMember(0));
        if (textField)
        {
            textField->setText(toolTipText);
            textField->setSize(
                textField->getNeededWidth(), textField->getNeededHeight());
        }
        else
        {
            setToolTipText(toolTipText,
                uiFactory.initParam.bildschirm,
                uiFactory.initParam.schrift);
        }
    }
    toolTip->setRender();
    rend = 1;
    unlockZeichnung();
    uiFactory.initParam.bildschirm->unlock();
}

void UIMLProgressAndStateView::render(Framework::Bild& rObj)
{
    if (hatStyleNicht(Style::Sichtbar)) return;
    lockZeichnung();
    if (!rObj.setDrawOptions(pos.x, pos.y, gr.x, gr.y))
    {
        unlockZeichnung();
        return;
    }
    Zeichnung::render(rObj);
    rObj.alphaBild(0, 0, gr.x, gr.y, *background);
    if (max > 0 && current > 0)
    {
        double progrss = (double)current / max;
        if (hatStyle(Style::Vertical))
        {
            int height = (int)(gr.y * progrss);
            if (hatStyle(Style::Reversed))
            {
                if (rObj.setDrawOptions(0, gr.y - height, gr.x, height))
                {
                    rObj.alphaBild(0, height - gr.y, gr.x, gr.y, *foreground);
                    rObj.releaseDrawOptions();
                }
            }
            else
            {
                rObj.alphaBild(0, 0, gr.x, height, *foreground);
            }
        }
        else
        {
            int width = (int)(gr.x * progrss);
            if (hatStyle(Style::Reversed))
            {
                if (rObj.setDrawOptions(gr.x - width, 0, width, gr.y))
                {
                    rObj.alphaBild(width - gr.x, 0, gr.x, gr.y, *foreground);
                    rObj.releaseDrawOptions();
                }
            }
            else
            {
                rObj.alphaBild(0, 0, width, gr.y, *foreground);
            }
        }
    }
    rObj.releaseDrawOptions();
    unlockZeichnung();
}
