#include "Zeichnung.h"

#include "AlphaFeld.h"
#include "Bild.h"
#include "Bildschirm.h"
#include "Globals.h"
#include "MausEreignis.h"
#include "Rahmen.h"
#include "Schrift.h"
#include "Scroll.h"
#include "TastaturEreignis.h"
#include "Text.h"
#include "TextFeld.h"
#include "ToolTip.h"
#include "UIInitialization.h"
#ifdef WIN32
#    include <Windows.h>
#endif

using namespace Framework;

// Inhalt der Zeichnung Klasse aus Zeichnung.h
// Konstruktor
Zeichnung::Zeichnung()
    : ReferenceCounter(),
      pos(0, 0),
      gr(0, 0),
      makParam(0),
      takParam(0),
      mak(0),
      tak(0),
      nmakParam(0),
      ntakParam(0),
      nMak(0),
      nTak(0),
      mausIn(0),
      toolTip(0),
      style(0),
      rend(0),
      onNeedToolTip(0),
      toolTipRequested(0)
{}

// Destruktor
Zeichnung::~Zeichnung()
{
    if (toolTip) toolTip->release();
}

void Zeichnung::doMausEreignis(MausEreignis& me, bool userRet)
{
    me.verarbeitet = userRet;
}

// Übergibt einen Void Funktionspointer auf eine Aktion die einmalig vom
// Hauptthread ausgeführt werden soll. (Passiert nach dem Tick)
void Zeichnung::postAction(std::function<void()> action)
{
    actions.push(action);
}

// nicht constant
void Zeichnung::setRender()
{
    rend = 1;
}

void Zeichnung::setToolTipText(
    const char* txt, Bildschirm* zScreen, Schrift* zSchrift)
{
    if (!txt)
        toolTip = (ToolTip*)toolTip->release();
    else
    {
        if (!toolTip)
        {
            toolTip = new ToolTip(zScreen);
            toolTip->addStyle(ZeichnungHintergrund::Style::Hintergrund
                              | ZeichnungHintergrund::Style::HAlpha
                              | ZeichnungHintergrund::Style::Rahmen
                              | ZeichnungHintergrund::Style::Sichtbar);
            toolTip->setHintergrundFarbe(0xA0000000);
            toolTip->setRahmenFarbe(0xFFFFFFFF);
            toolTip->setRahmenBreite(1);
            if (mausIn && toolTip) toolTip->setMausIn(1);
        }
        UIInit init = defaultUI(zSchrift, zScreen);
        TextFeld* t = init.createTextFeld(init.initParam);
        t->setText(txt);
        t->setSize(t->zTextRenderer()->getTextBreite(txt),
            t->zTextRenderer()->getTextHeight(txt));
        toolTip->addMember(t);
    }
    toolTipRequested = 0;
}

// setzt eine Funktion, die beim erstmaligen gebrauch des tooltips einen tooltip
// erstellt, falls es noch keinen gibt
//  initToolTip: die Funktion
void Zeichnung::setNeedToolTipEvent(
    std::function<bool(Zeichnung*, Punkt localPos)> onNeedToolTip)
{
    this->onNeedToolTip = onNeedToolTip;
}

// legt den tooltip fest
// tt: der tooltip
void Zeichnung::setToolTipZ(ToolTip* tt)
{
    if (toolTip) toolTip->release();
    toolTip = tt;
    if (mausIn && toolTip) toolTip->setMausIn(1);
    toolTipRequested = 0;
}

void Zeichnung::lockZeichnung()
{
    cs.lock();
}

void Zeichnung::unlockZeichnung()
{
    cs.unlock();
}

void Zeichnung::setMausEreignisParameter(
    void* p) // setzt den Parameter vom Maus Ereignis
{
    makParam = p;
}

void Zeichnung::setTastaturEreignisParameter(
    void* p) // setzt den Parameter vom Tastatur Ereignis
{
    takParam = p;
}

void Zeichnung::setMausEreignis(MausAktion ak) // setzt das Maus Ereignis
{
    mak = ak;
}

void Zeichnung::setTastaturEreignis(
    TastaturAktion ak) // setzt das TastaturEreignis
{
    tak = ak;
}

void Zeichnung::setNMausEreignisParameter(
    void* p) // setzt den Parameter vom Maus Ereignis
{
    nmakParam = p;
}

void Zeichnung::setNTastaturEreignisParameter(
    void* p) // setzt den Parameter vom Tastatur Ereignis
{
    ntakParam = p;
}

void Zeichnung::setNMausEreignis(MausAktion ak) // setzt das Maus Ereignis
{
    nMak = ak;
}

void Zeichnung::setNTastaturEreignis(
    TastaturAktion ak) // setzt das TastaturEreignis
{
    nTak = ak;
}

void Zeichnung::doPublicMausEreignis(MausEreignis& me) // ruft Mak auf
{
    bool lock = hatStyle(Style::MELockZeichnung);
    if (lock) lockZeichnung();
    bool inside = istPunktInnen(me.mx, me.my);
    if (!me.insideParent || me.verarbeitet || !inside)
    {
        if (mausIn)
        {
            mausIn = 0;
            if (toolTip) toolTip->setMausIn(0);
            MausEreignis me2;
            me2.id = ME_Leaves;
            me2.mx = me.mx - pos.x;
            me2.my = me.my - pos.y;
            me2.verarbeitet = 0;
            me2.insideParent = me.insideParent;
            bool userRet = mak && mak(makParam, this, me2);
            doMausEreignis(me2, userRet);
        }
    }
    if (!inside && me.id == ME_PLinks) removeStyle(Style::Fokus);
    if ((me.verarbeitet && hatStyleNicht(Style::MEIgnoreVerarbeitet))
        || (!inside && hatStyleNicht(Style::MEIgnoreInside))
        || (hatStyleNicht(Style::Sichtbar)
            && hatStyleNicht(Style::MEIgnoreSichtbar)))
    {
        if (lock) unlockZeichnung();
        return;
    }
    if (inside && me.id == ME_PLinks) addStyle(Style::Fokus);
    if (me.insideParent && !mausIn && me.id != ME_Leaves && inside
        && !me.verarbeitet && hatStyle(Style::Sichtbar))
    {
        mausIn = 1;
        if (toolTip)
            toolTip->setMausIn(1);
        else if (onNeedToolTip && !toolTipRequested)
        {
            toolTipRequested
                = onNeedToolTip(this, Punkt(me.mx - pos.x, me.my - pos.y));
        }
        MausEreignis me2;
        me2.id = ME_Betritt;
        me2.mx = me.mx - pos.x;
        me2.my = me.my - pos.y;
        me2.verarbeitet = 0;
        me2.insideParent = 1;
        bool userRet = mak && mak(makParam, this, me2);
        doMausEreignis(me2, userRet);
    }
    else if (me.insideParent && mausIn && me.id != ME_Leaves && inside
             && !me.verarbeitet && hatStyle(Style::Sichtbar) && !toolTip
             && onNeedToolTip && !toolTipRequested)
    {
        toolTipRequested
            = onNeedToolTip(this, Punkt(me.mx - pos.x, me.my - pos.y));
    }
    Punkt old = Punkt(me.mx, me.my);
    me.mx -= pos.x, me.my -= pos.y;
    if (me.insideParent || hatStyle(Style::MEIgnoreParentInside))
    {
        bool userRet = hatStyle(Style::Erlaubt)
                    && (me.verarbeitet || !me.insideParent
                        || (inside && mak && mak(makParam, this, me)));
        bool vera = me.verarbeitet;
        doMausEreignis(me, userRet);
        if (nMak && me.verarbeitet && !vera && hatStyle(Style::Erlaubt)
            && me.insideParent && inside)
            me.verarbeitet = nMak(nmakParam, this, me);
    }
    me.mx = old.x, me.my = old.y;
    if (lock) unlockZeichnung();
}

void Zeichnung::doTastaturEreignis(TastaturEreignis& te) // ruft Tak auf
{
    if (te.verarbeitet) return;
    if (tak) te.verarbeitet |= tak(takParam, this, te);
    if (nTak && te.verarbeitet) te.verarbeitet = nTak(ntakParam, this, te);
}

void Zeichnung::setPosition(const Punkt& pos) // setzt die position
{
    lockZeichnung();
    if (this->pos != pos) rend = 1;
    this->pos = pos;
    unlockZeichnung();
}

void Zeichnung::setX(int xPos)
{
    lockZeichnung();
    if (pos.x != xPos)
    {
        rend = 1;
        pos.x = xPos;
    }
    unlockZeichnung();
}

void Zeichnung::setY(int yPos)
{
    lockZeichnung();
    if (pos.y != yPos)
    {
        rend = 1;
        pos.y = yPos;
    }
    unlockZeichnung();
}

void Zeichnung::setSize(const Punkt& gr) // setzt die Größe
{
    lockZeichnung();
    if (this->gr != gr) rend = 1;
    this->gr = gr;
    unlockZeichnung();
}

void Zeichnung::setPosition(int x, int y) // setzt die position
{
    setPosition(Punkt(x, y));
}

void Zeichnung::setSize(int x, int y) // setzt die Größe
{
    setSize(Punkt(x, y));
}

void Zeichnung::setWidth(int width)
{
    lockZeichnung();
    if (this->gr.x != width) rend = 1;
    gr.x = width;
    unlockZeichnung();
}

void Zeichnung::setHeight(int height)
{
    lockZeichnung();
    if (this->gr.y != height) rend = 1;
    gr.y = height;
    unlockZeichnung();
}

bool Zeichnung::tick(double tickval)
{
    while (!actions.empty())
    {
        actions.front()();
        actions.pop();
    }
    bool r = rend;
    rend = 0;
    return r;
}

void Zeichnung::setStyle(__int64 style) // setzt den Style des Text Feldes
{
    if (this->style != style)
    {
        this->style = style;
        rend = 1;
    }
}

void Zeichnung::setStyle(__int64 style, bool add_remove)
{
    if (add_remove && (this->style | style) != this->style)
    {
        this->style |= style;
        rend = 1;
    }
    else if (!add_remove && (this->style & ~style) != this->style)
    {
        if (toolTip && (style | Style::Sichtbar) == style)
            toolTip->setMausIn(0);
        this->style &= ~style;
        rend = 1;
    }
}

void Zeichnung::addStyle(__int64 style)
{
    if ((this->style | style) != this->style)
    {
        this->style |= style;
        rend = 1;
    }
}

void Zeichnung::removeStyle(__int64 style)
{
    if ((this->style & ~style) != this->style)
    {
        if (toolTip && (style | Style::Sichtbar) == style)
            toolTip->setMausIn(0);
        this->style &= ~style;
        rend = 1;
    }
}

void Zeichnung::render(Bild& zRObj)
{
    if (toolTip && (style | Style::Sichtbar) == style) toolTip->setZeichnen();
}

// constant
bool Zeichnung::hatMausEreignis() const // prüft, ob Mak gesetzt ist
{
    return mak != 0;
}

bool Zeichnung::hatTastaturEreignis() const // prüft, ob Tak gesetzt ist
{
    return tak != 0;
}

const Punkt& Zeichnung::getPosition() const // gibt die Position zurück
{
    return pos;
}

const Punkt& Zeichnung::getSize() const // gibt die Größe zurück
{
    return gr;
}

int Zeichnung::getBreite() const // gibt die Breite zurück
{
    return gr.x;
}

int Zeichnung::getHeight() const // gibt die Höhe zurück
{
    return gr.y;
}

// Gibt die Breite des Innenraumes in der Zeichnung in Pixeln zurück
int Zeichnung::getInnenBreite() const
{
    return gr.x;
}

// Gibt die Höhe des Innenraumes in der Zeichnung in Pixeln zurück
int Zeichnung::getInnenHeight() const
{
    return gr.y;
}

int Zeichnung::getX() const // gibt X zurück
{
    return pos.x;
}

int Zeichnung::getY() const // gibt Y zurück
{
    return pos.y;
}

// Prüft, ob ein Punkt in diesem Objekt liegt
//  p: der Punkt
//  return: 1, wenn der punkt innen ist, 0 sonst
bool Zeichnung::istPunktInnen(Punkt p) const
{
    return istPunktInnen(p.x, p.y);
}

// Prüft, ob ein Punkt in diesem Objekt liegt
//  x: die x koordinate des punktes
//  y: die y koordinate des punktes
//  return: 1, wenn der punkt innen ist, 0 sonst
bool Zeichnung::istPunktInnen(int x, int y) const
{
    return x >= pos.x && x <= pos.x + gr.x && y >= pos.y && y <= pos.y + gr.y;
}

ToolTip* Zeichnung::getToolTip() const // gibt den ToolTip Text
{
    return dynamic_cast<ToolTip*>(toolTip->getThis());
}

ToolTip* Zeichnung::zToolTip() const
{
    return toolTip;
}

bool Zeichnung::hatStyle(__int64 style) const // prüft, ob style vorhanden
{
    return (this->style | style) == this->style;
}

bool Zeichnung::hatStyleNicht(
    __int64 style) const // prüft, ob style nicht vorhanden
{
    return (this->style | style) != this->style;
}

Zeichnung* Zeichnung::dublizieren() const // Erzeugt eine Kopie des Zeichnungs
{
    Zeichnung* obj = new Zeichnung();
    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());
    return obj;
}

// Inhalt der ZeichnungHintergrund Klasse aus Zeichnung.h
// Konstruktor
ZeichnungHintergrund::ZeichnungHintergrund()
    : Zeichnung()
{
    hintergrundFarbe = 0xFF000000;
    rahmen = 0;
    hintergrundBild = 0;
    hintergrundFeld = 0;
    horizontalScrollBar = 0;
    vertikalScrollBar = 0;
    innenPosition.x = 0;
    innenPosition.y = 0;
    innenSize.x = 0;
    innenSize.y = 0;
}

// Destruktor
ZeichnungHintergrund::~ZeichnungHintergrund()
{
    if (rahmen) rahmen->release();
    if (hintergrundBild) hintergrundBild->release();
    if (hintergrundFeld) hintergrundFeld->release();
    if (horizontalScrollBar) horizontalScrollBar->release();
    if (vertikalScrollBar) vertikalScrollBar->release();
}

void ZeichnungHintergrund::setHintergrundBild(
    Bild* bild) // setzt das Hintergrund Bild
{
    if (!hintergrundBild) hintergrundBild = new Bild();
    hintergrundBild->neuBild(bild->getBreite(), bild->getHeight(), 0);
    int* buff1 = hintergrundBild->getBuffer();
    int* buff2 = bild->getBuffer();
    for (int i = 0; i < bild->getBreite() * bild->getHeight(); ++i)
        buff1[i] = buff2[i];
    bild->release();
    rend = 1;
}

void ZeichnungHintergrund::setHintergrundBildZ(
    Bild* bild) // setzt einen Zeiger zum Hintergrund Bild
{
    if (hintergrundBild != bild)
    {
        if (hintergrundBild) hintergrundBild->release();
        hintergrundBild = bild;
        rend = 1;
    }
}

void ZeichnungHintergrund::setHintergrundFarbe(
    int fc) // setzt die Hintergrundfarbe
{
    if (hintergrundFarbe != fc)
    {
        hintergrundFarbe = fc;
        rend = 1;
    }
}

void ZeichnungHintergrund::setAlphaFeldZ(
    AlphaFeld* buff) // setzt einen Zeiger zum Hintergrund Buffer
{
    if (hintergrundFeld != buff)
    {
        if (hintergrundFeld) hintergrundFeld->release();
        hintergrundFeld = buff;
        rend = 1;
    }
}

void ZeichnungHintergrund::setAlphaFeldStrength(
    int st) // setzt die Stärke des Hintergrund Buffers
{
    if (!hintergrundFeld)
    {
        hintergrundFeld = new AlphaFeld();
        rend = 1;
    }
    if (hintergrundFeld->getStrength() != st)
    {
        hintergrundFeld->setStrength(st);
        rend = 1;
    }
}

void ZeichnungHintergrund::setAlphaFeldFarbe(
    int fc) // setzt die Farbe des Hintergrund Buffers
{
    if (!hintergrundFeld)
    {
        hintergrundFeld = new AlphaFeld();
        rend = 1;
    }
    if (hintergrundFeld->getFarbe() != fc)
    {
        hintergrundFeld->setFarbe(fc);
        rend = 1;
    }
}

void ZeichnungHintergrund::setRahmenZ(
    Rahmen* ram) // setzt einen Zeiger zum Rahmen
{
    if (rahmen != ram)
    {
        if (rahmen) rahmen->release();
        rahmen = ram;
        rend = 1;
    }
}

void ZeichnungHintergrund::setRahmenBreite(
    int br) // setzt die Breite des Rahmens
{
    if (!rahmen)
    {
        rahmen = new LRahmen();
        rend = 1;
    }
    if (rahmen->getRBreite() != br)
    {
        rahmen->setRamenBreite(br);
        rend = 1;
    }
}

void ZeichnungHintergrund::setRahmenFarbe(int fc) // setzt die Farbe des Rahmens
{
    if (!rahmen)
    {
        rahmen = new LRahmen();
        rend = 1;
    }
    if (rahmen->getFarbe() != fc)
    {
        rahmen->setFarbe(fc);
        rend = 1;
    }
}

void ZeichnungHintergrund::setVertikalKlickScroll(
    int ks) // setzt die vertikale Scroll geschwindigkeit
{
    if (!vertikalScrollBar)
    {
        vertikalScrollBar = new VScrollBar();
        rend = 1;
    }
    if (vertikalScrollBar->getKlickScroll() != ks)
    {
        vertikalScrollBar->setKlickScroll(ks);
        rend = 1;
    }
}

void ZeichnungHintergrund::setVertikalScrollPos(
    int pos) // setzt die vertikale Scroll Position
{
    if (!vertikalScrollBar)
    {
        vertikalScrollBar = new VScrollBar();
        rend = 1;
    }
    if (vertikalScrollBar && vertikalScrollBar->getScroll() != pos)
    {
        vertikalScrollBar->scroll(pos);
        rend = 1;
    }
}

void ZeichnungHintergrund::setVertikalScrollFarbe(
    int f, int bgF) // setzt die scroll Farbe
{
    if (!vertikalScrollBar)
    {
        vertikalScrollBar = new VScrollBar();
        rend = 1;
    }
    if (vertikalScrollBar
        && (vertikalScrollBar->getFarbe() != f
            || vertikalScrollBar->getBgFarbe() != bgF))
    {
        vertikalScrollBar->setFarbe(f);
        vertikalScrollBar->setBgFarbe(bgF, bgF != 0);
        rend = 1;
    }
}

void ZeichnungHintergrund::setHorizontalKlickScroll(
    int ks) // setzt die horizontale Scroll geschwindigkeit
{
    if (!horizontalScrollBar)
    {
        horizontalScrollBar = new HScrollBar();
        rend = 1;
    }
    if (horizontalScrollBar && horizontalScrollBar->getKlickScroll() != ks)
    {
        horizontalScrollBar->setKlickScroll(ks);
        rend = 1;
    }
}

void ZeichnungHintergrund::setHorizontalScrollPos(
    int pos) // setzt die horizontale Scroll Position
{
    if (!horizontalScrollBar)
    {
        horizontalScrollBar = new HScrollBar();
        rend = 1;
    }
    if (horizontalScrollBar && horizontalScrollBar->getScroll() != pos)
    {
        horizontalScrollBar->scroll(pos);
        rend = 1;
    }
}

void ZeichnungHintergrund::setHorizontalScrollFarbe(
    int f, int bgF) // setzt die scroll Farbe
{
    if (!horizontalScrollBar)
    {
        horizontalScrollBar = new HScrollBar();
        rend = 1;
    }
    if (horizontalScrollBar
        && (horizontalScrollBar->getFarbe() != f
            || horizontalScrollBar->getBgFarbe() != bgF))
    {
        horizontalScrollBar->setFarbe(f);
        horizontalScrollBar->setBgFarbe(bgF, bgF != 0);
        rend = 1;
    }
}

bool ZeichnungHintergrund::tick(double tickVal)
{
    if (vertikalScrollBar && hatStyle(Style::VScroll))
        rend |= vertikalScrollBar->getRend();
    if (horizontalScrollBar && hatStyle(Style::HScroll))
        rend |= horizontalScrollBar->getRend();
    return Zeichnung::tick(tickVal);
}

void ZeichnungHintergrund::render(Bild& rObj)
{
    innenPosition.x = pos.x;
    innenPosition.y = pos.y;
    innenSize.x = gr.x;
    innenSize.y = gr.y;
    if (hatStyleNicht(Style::Sichtbar)) return;
    lockZeichnung();
    if (!rObj.setDrawOptions(pos.x, pos.y, gr.x, gr.y))
    {
        unlockZeichnung();
        return;
    }
    Zeichnung::render(rObj);
    int rbr = 0;
    if (hatStyle(Style::Rahmen) && rahmen)
    {
        rahmen->setSize(gr);
        rahmen->render(rObj);
        rbr = rahmen->getRBreite();
    }
    innenPosition.x += rbr;
    innenPosition.y += rbr;
    innenSize.x -= rbr * 2;
    innenSize.y -= rbr * 2;
    if (!rObj.setDrawOptions(rbr, rbr, gr.x - rbr * 2, gr.y - rbr * 2))
    {
        rObj.releaseDrawOptions();
        unlockZeichnung();
        return;
    }
    bool vs = vertikalScrollBar && hatStyle(Style::VScroll);
    bool hs = horizontalScrollBar && hatStyle(Style::HScroll);
    if (vs)
    {
        vertikalScrollBar->render(
            gr.x - rbr * 2 - 15, 0, 15, gr.y - rbr * 2, rObj);
        innenSize.x -= 15;
        if (hs)
        {
            horizontalScrollBar->render(
                0, gr.y - rbr * 2 - 15, gr.x - rbr * 2 - 15, 15, rObj);
            innenSize.y -= 15;
            if (!rObj.setDrawOptions(
                    0, 0, gr.x - rbr * 2 - 15, gr.y - rbr * 2 - 15))
            {
                rObj.releaseDrawOptions();
                rObj.releaseDrawOptions();
                unlockZeichnung();
                return;
            }
            horizontalScrollBar->update(
                horizontalScrollBar->getScrollData()->max, innenSize.x);
        }
        else
        {
            if (!rObj.setDrawOptions(0, 0, gr.x - rbr * 2 - 15, gr.y - rbr * 2))
            {
                rObj.releaseDrawOptions();
                rObj.releaseDrawOptions();
                unlockZeichnung();
                return;
            }
        }
        vertikalScrollBar->update(
            vertikalScrollBar->getScrollData()->max, innenSize.y);
    }
    else if (hs)
    {
        horizontalScrollBar->render(
            rbr, gr.y - rbr * 2 - 15, gr.x - rbr * 2, 15, rObj);
        innenSize.y -= 15;
        if (!rObj.setDrawOptions(0, 0, gr.x - rbr * 2, gr.y - rbr * 2 - 15))
        {
            rObj.releaseDrawOptions();
            rObj.releaseDrawOptions();
            unlockZeichnung();
            return;
        }
    }
    if (hatStyle(Style::Hintergrund))
    {
        if (hatStyle(Style::HAlpha))
            rObj.alphaRegion(
                0, 0, gr.x - rbr * 2, gr.y - rbr * 2, hintergrundFarbe);
        else
            rObj.fillRegion(
                0, 0, gr.x - rbr * 2, gr.y - rbr * 2, hintergrundFarbe);
        if (hatStyle(Style::HBild) && hintergrundBild)
        {
            if (hatStyle(Style::HAlpha))
                rObj.alphaBildSkall(
                    0, 0, gr.x - rbr * 2, gr.y - rbr * 2, *hintergrundBild);
            else
                rObj.drawBildSkall(
                    0, 0, gr.x - rbr * 2, gr.y - rbr * 2, *hintergrundBild);
        }
    }
    if (hatStyle(Style::Buffered) && hintergrundFeld)
    {
        hintergrundFeld->setSize(gr.x - rbr * 2, gr.y - rbr * 2);
        hintergrundFeld->render(rObj);
    }
    if (vs || hs) rObj.releaseDrawOptions();
    rObj.releaseDrawOptions();
    rObj.releaseDrawOptions();
    unlockZeichnung();
}

// Gibt die Breite des Innenraumes in der Zeichnung in Pixeln zurück
int ZeichnungHintergrund::getInnenBreite() const
{
    return getBreite() - 2 * getRahmenBreite();
}

// Gibt die Höhe des Innenraumes in der Zeichnung in Pixeln zurück
int ZeichnungHintergrund::getInnenHeight() const
{
    return getHeight() - 2 * getRahmenBreite();
}

Bild* ZeichnungHintergrund::getHintergrundBild()
    const // gibt getThis vom Hintergrund Bild zurück
{
    if (!hintergrundBild) return 0;
    return dynamic_cast<Bild*>(hintergrundBild->getThis());
}

Bild* ZeichnungHintergrund::zHintergrundBild()
    const // gibt das Hintergrund Bild zurück
{
    return hintergrundBild;
}

int ZeichnungHintergrund::getHintergrundFarbe()
    const // giebt getThis der Hintergrundfarbe zurück
{
    return hintergrundFarbe;
}

AlphaFeld* ZeichnungHintergrund::getAlphaFeld()
    const // gibt getThir vom Hintergrund Buffer zurück
{
    if (!hintergrundFeld) return 0;
    return dynamic_cast<AlphaFeld*>(hintergrundFeld->getThis());
}

AlphaFeld*
ZeichnungHintergrund::zAlphaFeld() const // gibt den Hintergrund Buffer zurück
{
    return hintergrundFeld;
}

int ZeichnungHintergrund::getAlphaFeldStrength()
    const // gibt die Stärke des Hintergrund Buffers zurück
{
    if (!hintergrundFeld) return 0;
    return hintergrundFeld->getStrength();
}

int ZeichnungHintergrund::getAlphaFeldFarbe()
    const // gibt getThis von der Farbe des Hintergrund Buffers zurück
{
    return hintergrundFeld->getFarbe();
}

Rahmen*
ZeichnungHintergrund::getRahmen() const // gibt getThis des Rahmens zurück
{
    if (!rahmen) return 0;
    return dynamic_cast<Rahmen*>(rahmen->getThis());
}

Rahmen* ZeichnungHintergrund::zRahmen() const // gibt den Rahmen zurück
{
    return rahmen;
}

int ZeichnungHintergrund::getRahmenBreite()
    const // gibt die Breite des Rahmens zurück
{
    if (!rahmen || hatStyleNicht(Style::Rahmen)) return 0;
    return rahmen->getRBreite();
}

int ZeichnungHintergrund::getRahmenFarbe()
    const // gibt getThis der Farbe des Rahmens zurück
{
    return rahmen->getFarbe();
}

int ZeichnungHintergrund::getVertikalKlickScroll() const
{
    return vertikalScrollBar ? vertikalScrollBar->getKlickScroll() : 0;
}

int ZeichnungHintergrund::getVertikalScrollPos() const
{
    return vertikalScrollBar ? vertikalScrollBar->getScroll() : 0;
}

int ZeichnungHintergrund::getVertikalScrollFarbe() const
{
    return vertikalScrollBar ? vertikalScrollBar->getFarbe() : 0;
}

int ZeichnungHintergrund::getVertikalScrollHintergrund() const
{
    return vertikalScrollBar ? vertikalScrollBar->getBgFarbe() : 0;
}

int ZeichnungHintergrund::getHorizontalKlickScroll() const
{
    return horizontalScrollBar ? horizontalScrollBar->getKlickScroll() : 0;
}

int ZeichnungHintergrund::getHorizontalScrollPos() const
{
    return horizontalScrollBar ? horizontalScrollBar->getScroll() : 0;
}

int ZeichnungHintergrund::getHorizontalScrollFarbe() const
{
    return horizontalScrollBar ? horizontalScrollBar->getFarbe() : 0;
}

int ZeichnungHintergrund::getHorizontalScrollHintergrund() const
{
    return horizontalScrollBar ? horizontalScrollBar->getBgFarbe() : 0;
}

Zeichnung*
ZeichnungHintergrund::dublizieren() const // Erzeugt eine Kopie des Zeichnungs
{
    ZeichnungHintergrund* obj = new ZeichnungHintergrund();
    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->setStyle(style);
    obj->setHintergrundFarbe(hintergrundFarbe);
    if (hintergrundFeld)
        obj->setAlphaFeldZ((AlphaFeld*)hintergrundFeld->dublizieren());
    if (rahmen) obj->setRahmenZ((Rahmen*)rahmen->dublizieren());
    if (hintergrundBild)
        obj->setHintergrundBild(
            dynamic_cast<Bild*>(hintergrundBild->getThis()));
    if (vertikalScrollBar)
    {
        obj->setVertikalKlickScroll(vertikalScrollBar->getKlickScroll());
        obj->setVertikalScrollPos(vertikalScrollBar->getScroll());
        obj->setVertikalScrollFarbe(
            vertikalScrollBar->getFarbe(), vertikalScrollBar->getBgFarbe());
    }
    if (horizontalScrollBar)
    {
        obj->setHorizontalKlickScroll(horizontalScrollBar->getKlickScroll());
        obj->setHorizontalScrollPos(horizontalScrollBar->getScroll());
        obj->setHorizontalScrollFarbe(
            horizontalScrollBar->getFarbe(), horizontalScrollBar->getBgFarbe());
    }
    return obj;
}