#include "Rahmen.h"

#include "Bild.h"
#include "Punkt.h"
#include "Scroll.h"
#include "Text.h"
#include "ToolTip.h"

using namespace Framework;

// Inhalt der Rahmen Klasse aus Rahmen.h
// Konstruktor
Rahmen::Rahmen()
    : Zeichnung(),
      br(1),
      farbe(0xFF000000),
      alpha(0),
      breaks(0)
{}

// Destruktor
Rahmen::~Rahmen() {}

// nicht constant
void Rahmen::setRamenBreite(int br) // setzt die Breite des Rahmens
{
    this->br = br;
    rend = 1;
}

// wenn dieser Flag gesetzt wird, wird der Rahmen gestrichelt gezeichnet
//  br: 1 -> gestrichelt, 0 -> durchgehend
void Rahmen::setBreaks(bool br, int brOff, int brLength, int lineLength)
{
    breaks = br;
    breakOffset = brOff;
    breakLength = brLength;
    this->lineLength = lineLength;
    rend = 1;
}

void Rahmen::setAlpha(
    bool a) // Legt fest, ob der Alphawert der Farbe berücksichtigt werden soll
{
    alpha = a;
    rend = 1;
}

void Rahmen::setFarbe(int f) // Legt die Farbe des Rahmens fest
{
    farbe = f;
    rend = 1;
}

int Rahmen::getFarbe() const // Gibt die Farbe des Ramens zurück
{
    return farbe;
}

bool Rahmen::hatAlpha()
    const // Gibt zurück, ob der Alphawert der Farbe beachtet wird
{
    return alpha;
}

int Rahmen::getRBreite() const // Gibt die Breite des Rahmens zurück
{
    return br;
}

// Gibt 1 zurück, falls der Rahmen gestrichelt gezeichnet wird
bool Rahmen::hasBreaks() const
{
    return breaks;
}

// startpunkt des ersten linienabschnittes
int Rahmen::getBreakOffset() const
{
    return breakOffset;
}

// länge einer lücke
int Rahmen::getBreakLength() const
{
    return breakLength;
}

// länge einer linie
int Rahmen::getLineLength() const
{
    return lineLength;
}

// Inhalt der LRahmen Klasse aus Rahmen.h
// Konstruktor
LRahmen::LRahmen()
    : Rahmen()
{}

// Destruktor
LRahmen::~LRahmen() {}

void LRahmen::render(Bild& Obj) // Zeichnet den Rahmen in das RenderZeichnung
{
    Zeichnung::render(Obj);
    int x = 0;
    int y = 0;
    int b = gr.x - 1;
    int h = gr.y - 1;
    if (!Obj.setDrawOptions(pos.x, pos.y, gr.x, gr.y)) return;
    if (!breaks)
    {
        if (alpha)
        {
            for (int i = 0; i < br; ++i)
            {
                Obj.drawLinieHAlpha(x + i + 1, y + i, gr.x - i * 2 - 1, farbe);
                Obj.drawLinieVAlpha(b - i, y + i + 1, gr.y - i * 2 - 2, farbe);
                Obj.drawLinieHAlpha(x + i + 1, h - i, gr.x - i * 2 - 1, farbe);
                Obj.drawLinieVAlpha(x + i, y + i, gr.y - i * 2, farbe);
            }
        }
        else
        {
            for (int i = 0; i < br; ++i)
            {
                Obj.drawLinieH(x + i + 1, y + i, gr.x - i * 2 - 1, farbe);
                Obj.drawLinieV(b - i, y + i + 1, gr.y - i * 2 - 2, farbe);
                Obj.drawLinieH(x + i + 1, h - i, gr.x - i * 2 - 1, farbe);
                Obj.drawLinieV(x + i, y + i, gr.y - i * 2, farbe);
            }
        }
    }
    else
    {
        if (alpha)
        {
            for (int i = 0; i < br; ++i)
            {
                for (int x = breakOffset; x < gr.x;
                     x += lineLength + breakLength)
                    Obj.drawLinieHAlpha(x + i + 1,
                        y + i,
                        lineLength
                            - (x + i + 1 + lineLength > gr.x - i - 1
                                    ? gr.x - i - 1 - (x + i + 1 + lineLength)
                                    : 0),
                        farbe);
                for (int x = gr.x - breakOffset - lineLength; x >= 0;
                     x -= lineLength + breakLength)
                    Obj.drawLinieHAlpha(MAX(x + i + 1, i + 1),
                        h - i,
                        lineLength
                            - (x + i + 1 < i + 1 ? i + 1 - (x + i + 1) : 0),
                        farbe);
                for (int y = breakOffset; y < gr.y;
                     y += lineLength + breakLength)
                    Obj.drawLinieVAlpha(b - i,
                        y + i + 1,
                        lineLength
                            - (y + i + 1 + lineLength > gr.y - i - 1
                                    ? gr.y - i - 1 - (y + i + 1 + lineLength)
                                    : 0),
                        farbe);
                for (int y = gr.y - breakOffset - lineLength; y >= 0;
                     y -= lineLength + breakLength)
                    Obj.drawLinieVAlpha(x + i,
                        MAX(y + i, i),
                        lineLength - (y + i < i ? i - (y + i) : 0),
                        farbe);
            }
        }
        else
        {
            for (int i = 0; i < br; ++i)
            {
                for (int x = breakOffset; x < gr.x;
                     x += lineLength + breakLength)
                    Obj.drawLinieH(x + i + 1,
                        y + i,
                        lineLength
                            - (x + i + 1 + lineLength > gr.x - i - 1
                                    ? gr.x - i - 1 - (x + i + 1 + lineLength)
                                    : 0),
                        farbe);
                for (int x = gr.x - breakOffset - lineLength; x >= 0;
                     x -= lineLength + breakLength)
                    Obj.drawLinieH(MAX(x + i + 1, i + 1),
                        h - i,
                        lineLength
                            - (x + i + 1 < i + 1 ? i + 1 - (x + i + 1) : 0),
                        farbe);
                for (int y = breakOffset; y < gr.y;
                     y += lineLength + breakLength)
                    Obj.drawLinieV(b - i,
                        y + i + 1,
                        lineLength
                            - (y + i + 1 + lineLength > gr.y - i - 1
                                    ? gr.y - i - 1 - (y + i + 1 + lineLength)
                                    : 0),
                        farbe);
                for (int y = gr.y - breakOffset - lineLength; y >= 0;
                     y -= lineLength + breakLength)
                    Obj.drawLinieV(x + i,
                        MAX(y + i, i),
                        lineLength - (y + i < i ? i - (y + i) : 0),
                        farbe);
            }
        }
    }
    Obj.releaseDrawOptions();
}

Zeichnung* LRahmen::dublizieren() const // Kopiert das Zeichnung
{
    Rahmen* obj = new LRahmen();
    obj->setPosition(pos);
    obj->setSize(gr);
    obj->setMausEreignisParameter(makParam);
    obj->setTastaturEreignisParameter(takParam);
    obj->setMausEreignis(mak);
    obj->setTastaturEreignis(tak);
    if (toolTip) obj->setToolTipZ((ToolTip*)toolTip->dublizieren());
    obj->setBreaks(breaks);
    obj->setAlpha(alpha);
    obj->setFarbe(farbe);
    obj->setRamenBreite(br);
    return obj;
}

// Inhalt der Rahmen3D Klasse aus Rahmen.h
// Konstruktor
Rahmen3D::Rahmen3D()
    : Rahmen()
{
    alpha = 1;
    farbe = 0x70FFFFFF;
    br = 5;
}

// Destruktor
Rahmen3D::~Rahmen3D() {}

void Rahmen3D::render(Bild& Obj) // Zeichnet den Rahmen in das RenderZeichnung
{
    Zeichnung::render(Obj);
    int x = 0;
    int y = 0;
    int b = gr.x - 1;
    int h = gr.y - 1;
    int fcomp = (farbe & 0xFF000000) | (~farbe & 0x00FFFFFF);
    if (!Obj.setDrawOptions(pos.x, pos.y, gr.x, gr.y)) return;
    if (!breaks)
    {
        if (alpha)
        {
            for (int i = 0; i < br; ++i)
            {
                Obj.drawLinieHAlpha(x + i + 1, y + i, gr.x - i * 2 - 1, farbe);
                Obj.drawLinieVAlpha(b - i, y + i + 1, gr.y - i * 2 - 2, farbe);
                Obj.drawLinieHAlpha(x + i + 1, h - i, gr.x - i * 2 - 1, fcomp);
                Obj.drawLinieVAlpha(x + i, y + i, gr.y - i * 2, fcomp);
            }
        }
        else
        {
            for (int i = 0; i < br; ++i)
            {
                Obj.drawLinieH(x + i + 1, y + i, gr.x - i * 2 - 1, farbe);
                Obj.drawLinieV(b - i, y + i + 1, gr.y - i * 2 - 2, farbe);
                Obj.drawLinieH(x + i + 1, h - i, gr.x - i * 2 - 1, fcomp);
                Obj.drawLinieV(x + i, y + i, gr.y - i * 2, fcomp);
            }
        }
    }
    else
    {
        if (alpha)
        {
            for (int i = 0; i < br; ++i)
            {
                for (int x = breakOffset; x < gr.x;
                     x += lineLength + breakLength)
                    Obj.drawLinieHAlpha(x + i + 1,
                        y + i,
                        lineLength
                            - (x + i + 1 + lineLength > gr.x - i - 1
                                    ? gr.x - i - 1 - (x + i + 1 + lineLength)
                                    : 0),
                        farbe);
                for (int x = gr.x - breakOffset - lineLength; x >= 0;
                     x -= lineLength + breakLength)
                    Obj.drawLinieHAlpha(MAX(x + i + 1, i + 1),
                        h - i,
                        lineLength
                            - (x + i + 1 < i + 1 ? i + 1 - (x + i + 1) : 0),
                        fcomp);
                for (int y = breakOffset; y < gr.y;
                     y += lineLength + breakLength)
                    Obj.drawLinieVAlpha(b - i,
                        y + i + 1,
                        lineLength
                            - (y + i + 1 + lineLength > gr.y - i - 1
                                    ? gr.y - i - 1 - (y + i + 1 + lineLength)
                                    : 0),
                        farbe);
                for (int y = gr.y - breakOffset - lineLength; y >= 0;
                     y -= lineLength + breakLength)
                    Obj.drawLinieVAlpha(x + i,
                        MAX(y + i, i),
                        lineLength - (y + i < i ? i - (y + i) : 0),
                        fcomp);
            }
        }
        else
        {
            for (int i = 0; i < br; ++i)
            {
                for (int x = breakOffset; x < gr.x;
                     x += lineLength + breakLength)
                    Obj.drawLinieH(x + i + 1,
                        y + i,
                        lineLength
                            - (x + i + 1 + lineLength > gr.x - i - 1
                                    ? gr.x - i - 1 - (x + i + 1 + lineLength)
                                    : 0),
                        farbe);
                for (int x = gr.x - breakOffset - lineLength; x >= 0;
                     x -= lineLength + breakLength)
                    Obj.drawLinieH(MAX(x + i + 1, i + 1),
                        h - i,
                        lineLength
                            - (x + i + 1 < i + 1 ? i + 1 - (x + i + 1) : 0),
                        fcomp);
                for (int y = breakOffset; y < gr.y;
                     y += lineLength + breakLength)
                    Obj.drawLinieV(b - i,
                        y + i + 1,
                        lineLength
                            - (y + i + 1 + lineLength > gr.y - i - 1
                                    ? gr.y - i - 1 - (y + i + 1 + lineLength)
                                    : 0),
                        farbe);
                for (int y = gr.y - breakOffset - lineLength; y >= 0;
                     y -= lineLength + breakLength)
                    Obj.drawLinieV(x + i,
                        MAX(y + i, i),
                        lineLength - (y + i < i ? i - (y + i) : 0),
                        fcomp);
            }
        }
    }
    Obj.releaseDrawOptions();
}

Zeichnung* Rahmen3D::dublizieren() const // Kopiert das Zeichnung
{
    Rahmen* obj = new Rahmen3D();
    obj->setPosition(pos);
    obj->setSize(gr);
    obj->setMausEreignisParameter(makParam);
    obj->setTastaturEreignisParameter(takParam);
    obj->setMausEreignis(mak);
    obj->setTastaturEreignis(tak);
    if (toolTip) obj->setToolTipZ((ToolTip*)toolTip->dublizieren());
    obj->setBreaks(breaks);
    obj->setAlpha(alpha);
    obj->setFarbe(farbe);
    obj->setRamenBreite(br);
    return obj;
}