#include "Progress.h"

#include "AlphaField.h"
#include "Border.h"
#include "Font.h"
#include "Image.h"
#include "Scroll.h"
#include "Text.h"

using namespace Framework;

// Contents of the ProgressBar class from Progress.h
// Constructor
ProgressBar::ProgressBar()
    : DrawableBackground(),
      maxAk(0),
      ak(0),
      fBorder(0),
      fBuffer(0),
      fBgF(0xFF000000),
      fBgImage(0),
      textRd(0),
      fontColor(0),
      fontSize(0)
{
    style = 0;
}

// Destructor
ProgressBar::~ProgressBar()
{
    if (fBorder) fBorder->release();
    if (fBuffer) fBuffer->release();
    if (fBgImage) fBgImage->release();
    if (textRd) textRd->release();
}

// non-constant
void ProgressBar::setActionCount(__int64 ak) // sets the number of actions
{
    maxAk = ak;
    rend = 1;
}

void ProgressBar::actionPlus(__int64 aktionen) // multiple actions are finished
{
    ak += aktionen;
    if (ak > maxAk) ak = maxAk;
    rend = 1;
}

void ProgressBar::reset() // resets the completed actions
{
    ak = 0;
    rend = 1;
}

void ProgressBar::setFBorderZ(
    Border* ram) // sets a pointer to the completion border
{
    if (fBorder) fBorder->release();
    fBorder = ram;
    rend = 1;
}

void ProgressBar::setFRColor(int f) // sets the completion border color
{
    if (!fBorder) fBorder = new LBorder();
    fBorder->setColor(f);
    rend = 1;
}

void ProgressBar::setFRWidth(int br) // sets the completion border width
{
    if (!fBorder) fBorder = new LBorder();
    fBorder->setBorderWidth(br);
    rend = 1;
}

void ProgressBar::setFAlphaFieldZ(
    AlphaField* af) // sets a pointer to the completion AlphaField
{
    if (fBuffer) fBuffer->release();
    fBuffer = af;
    rend = 1;
}

void ProgressBar::setFAFColor(int f) // sets the completion AlphaField color
{
    if (!fBuffer) fBuffer = new AlphaField();
    fBuffer->setColor(f);
    rend = 1;
}

void ProgressBar::setFAFStrength(
    int st) // sets the strength of the completion AlphaField
{
    if (!fBuffer) fBuffer = new AlphaField();
    fBuffer->setStrength(st);
    rend = 1;
}

void ProgressBar::setFBgColor(int f) // sets the completion background color
{
    fBgF = f;
    rend = 1;
}

void ProgressBar::setFBgImageZ(Image* b) // sets the completion background image
{
    if (fBgImage) fBgImage->release();
    fBgImage = b;
    rend = 1;
}

void ProgressBar::setFBgImage(
    Image* b) // copies into the completion background image
{
    if (!fBgImage) fBgImage = new Image();
    fBgImage->newImage(b->getWidth(), b->getHeight(), 0);
    fBgImage->drawImage(0, 0, b->getWidth(), b->getHeight(), *b);
    b->release();
    rend = 1;
}

void ProgressBar::setTextRendererZ(TextRenderer* textRd)
{
    if (this->textRd) this->textRd->release();
    this->textRd = textRd;
}

void ProgressBar::setFontZ(Font* s) // sets the font
{
    if (!textRd)
        textRd = new TextRenderer(s);
    else
        textRd->setFontZ(s);
    rend = 1;
}

void ProgressBar::setSColor(int f) // sets the font color
{
    fontColor = f;
    rend = 1;
}

void ProgressBar::setSSize(unsigned char gr) // sets the font size
{
    fontSize = gr;
    rend = 1;
}

void ProgressBar::render(Image& zRObj) // renders into zRObj
{
    if (!hasStyle(Style::Visible)) return;
    rwLock.lockRead();
    removeStyle(Style::VScroll | Style::HScroll);
    DrawableBackground::render(zRObj);
    if (!zRObj.setDrawOptions(pos, gr))
    {
        rwLock.unlockRead();
        return;
    }
    int xx = 0;
    int yy = 0;
    int b = gr.x;
    int h = gr.y;
    if (hasStyle(Style::L_R))
        b = (int)((gr.x / 100.0) * getProzent());
    else if (hasStyle(Style::R_L))
    {
        b = (int)((gr.x / 100.0) * getProzent());
        xx -= b;
    }
    else if (hasStyle(Style::O_U))
        h = (int)((gr.y / 100.0) * getProzent());
    else if (hasStyle(Style::U_O))
    {
        h = (int)((gr.y / 100.0) * getProzent());
        yy -= h;
    }
    if (maxAk == 0) b = 0, h = 0;
    if (!zRObj.setDrawOptions(xx, yy, b, h))
    {
        zRObj.releaseDrawOptions();
        rwLock.unlockRead();
        return;
    }
    int rbr = 0;
    if (hasStyle(Style::FBorder) && fBorder)
    {
        fBorder->setSize(b, h);
        fBorder->render(zRObj);
        rbr = fBorder->getRWidth();
    }
    if (hasStyle(Style::FColor))
    {
        if (hasStyle(Style::FAlpha))
            zRObj.alphaRegion(rbr, rbr, b - rbr * 2, h - rbr * 2, fBgF);
        else
            zRObj.fillRegion(rbr, rbr, b - rbr * 2, h - rbr * 2, fBgF);
    }
    if (hasStyle(Style::FImage) && fBgImage)
    {
        if (hasStyle(Style::FAlpha))
            zRObj.alphaImageScaled(
                rbr, rbr, gr.x - rbr * 2, gr.y - rbr * 2, *fBgImage);
        else
            zRObj.alphaImageScaled(
                rbr, rbr, gr.x - rbr * 2, gr.y - rbr * 2, *fBgImage);
    }
    if (hasStyle(Style::FBuffered) && fBuffer)
    {
        fBuffer->setSize(b - rbr * 2, h - rbr * 2);
        fBuffer->render(zRObj);
    }
    zRObj.releaseDrawOptions();
    if (hasStyle(Style::Aktionen) && textRd)
    {
        textRd->setFontSize(fontSize);
        Text txt = Text("") + ak + "/" + maxAk;
        if (hasStyle(Style::Prozent))
            txt += Text(" (") + (int)(getProzent() + 0.5) + "%)";
        zRObj.alphaRegion(
            rbr + (gr.x - rbr * 2) / 2 - textRd->getTextWidth(txt) / 2,
            rbr + (gr.y - rbr * 2) / 2 - textRd->getTextHeight(txt) / 2,
            textRd->getTextWidth(txt),
            textRd->getTextHeight(txt),
            0x70000000);
        textRd->renderText(
            rbr + (gr.x - rbr * 2) / 2 - textRd->getTextWidth(txt) / 2,
            rbr + (gr.y - rbr * 2) / 2 - textRd->getTextHeight(txt) / 2,
            txt,
            zRObj,
            fontColor);
    }
    else if (hasStyle(Style::Prozent) && textRd)
    {
        textRd->setFontSize(fontSize);
        Text txt;
        txt.append((int)(getProzent() + 0.5));
        txt.append("%");
        zRObj.alphaRegion(
            rbr + (gr.x - rbr * 2) / 2 - textRd->getTextWidth(txt) / 2,
            rbr + (gr.y - rbr * 2) / 2 - textRd->getTextHeight(txt) / 2,
            textRd->getTextWidth(txt),
            textRd->getTextHeight(txt),
            0x70000000);
        textRd->renderText(
            rbr + (gr.x - rbr * 2) / 2 - textRd->getTextWidth(txt) / 2,
            rbr + (gr.y - rbr * 2) / 2 - textRd->getTextHeight(txt) / 2,
            txt,
            zRObj,
            fontColor);
    }
    zRObj.releaseDrawOptions();
    rwLock.unlockRead();
}

// constant
__int64 ProgressBar::getActionCount() const // returns the number of actions
{
    return maxAk;
}

double ProgressBar::getProzent() const // returns the current percentage
{
    if (!maxAk) return 0;
    return (double)ak / ((double)maxAk / 100.0);
}

__int64 ProgressBar::getAktion() const // returns the completed actions
{
    return ak;
}

Border* ProgressBar::getFBorder() const // returns the completion border
{
    if (fBorder) return dynamic_cast<Border*>(fBorder->getThis());
    return 0;
}

Border* ProgressBar::zFBorder() const
{
    return fBorder;
}

AlphaField*
ProgressBar::getFAlphaField() const // returns the completion AlphaField
{
    if (fBuffer) return dynamic_cast<AlphaField*>(fBuffer->getThis());
    return 0;
}

AlphaField* ProgressBar::zFAlphaField() const
{
    return fBuffer;
}

int ProgressBar::getFBgColor() const // returns the completion background color
{
    return fBgF;
}

Image*
ProgressBar::getFBgImage() const // returns the completion background image
{
    if (fBgImage) return dynamic_cast<Image*>(fBgImage->getThis());
    return 0;
}

Image* ProgressBar::zFBgImage() const
{
    return fBgImage;
}

Font* ProgressBar::getFont() const // returns the font
{
    if (textRd) return textRd->getFont();
    return 0;
}

Font* ProgressBar::zFont() const
{
    return textRd ? textRd->zFont() : 0;
}

int ProgressBar::getSColor() const // returns the font color
{
    return fontColor;
}