#include "Liste.h"

#include "AlphaFeld.h"
#include "Array.h"
#include "Bild.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"

using namespace Framework;

// Inhalt der AuswahlListe Klasse aus Liste.h
// Konstruktor
AuswahlListe::AuswahlListe()
    : ZeichnungHintergrund(),
      tfListe(0),
      auswahl(-1),
      ahFarbe(0xFF000000),
      ahBild(0),
      aBuffer(0),
      aRahmen(0),
      styles(0),
      ahFarbeListe(0),
      ahBildListe(0),
      aBufferListe(0),
      aRahmenListe(0),
      schrift(0)
{
    style = 0;
    this->setMausEreignis(_ret1ME);
    this->setTastaturEreignis(_ret1TE);
}

// Destruktor
AuswahlListe::~AuswahlListe()
{
    if (tfListe) tfListe->release();
    if (ahBild) ahBild->release();
    if (aBuffer) aBuffer->release();
    if (aRahmen) aRahmen->release();
    if (styles) styles->release();
    if (ahFarbeListe) ahFarbeListe->release();
    if (ahBildListe) ahBildListe->release();
    if (aBufferListe) aBufferListe->release();
    if (aRahmenListe) aRahmenListe->release();
    if (schrift) schrift->release();
}

void AuswahlListe::doMausEreignis(MausEreignis& me, bool userRet)
{
    if (!userRet || hatStyleNicht(Style::Erlaubt)) return;
    if (ZeichnungHintergrund::hatStyle(Style::VScroll) && vertikalScrollBar)
    {
        int rbr = 0;
        if (rahmen && ZeichnungHintergrund::hatStyle(Style::Rahmen))
            rbr = rahmen->getRBreite();
        if (((me.mx > gr.x - 15 - rbr) || me.id == ME_UScroll
                || me.id == ME_DScroll)
            && me.id != ME_Betritt && me.id != ME_Leaves)
        {
            vertikalScrollBar->doMausMessage(
                gr.x - rbr - 15, rbr, 15, gr.y - rbr * 2, me);
            me.verarbeitet = 1;
        }
    }
    if (!me.verarbeitet && me.id == ME_RLinks)
    {
        int eintr = getKlickEintrag(me.my);
        if (eintr >= 0)
        {
            if (hatStyleNicht(Style::MultiSelect))
            {
                auswahl = eintr;
                rend = 1;
            }
            else
            {
                bool shift = getTastenStand(T_Shift);
                bool strg = getTastenStand(T_Strg);
                if (strg)
                {
                    setMsStyle(eintr,
                        Style::Selected,
                        hatMsStyleNicht(eintr, Style::Selected));
                    auswahl = eintr;
                }
                else if (shift && auswahl != -1)
                {
                    deSelect();
                    int beg = auswahl, end = eintr;
                    if (beg > end)
                    {
                        int tmp = end;
                        end = beg;
                        beg = tmp;
                    }
                    for (int i = beg; i <= end; ++i)
                    {
                        addMsStyle(i, Style::Selected);
                    }
                }
                else
                {
                    deSelect();
                    addMsStyle(eintr, Style::Selected);
                    auswahl = eintr;
                }
            }
        }
        else
            deSelect();
    }
    me.verarbeitet = 1;
}

bool AuswahlListe::hatStyle(int styleSet, int styleCheck) const
{
    return (styleSet | styleCheck) == styleSet;
}

// nicht constant
void AuswahlListe::update() // aktualisiert die Auswahl Liste
{
    int rbr = 0;
    if (rahmen)
    {
        rbr = rahmen->getRBreite();
        rahmen->setPosition(0, 0);
        rahmen->setSize(gr.x, gr.y);
    }
    if (hintergrundFeld)
    {
        hintergrundFeld->setPosition(rbr, rbr);
        hintergrundFeld->setSize(gr.x - rbr * 2, gr.y - rbr * 2);
    }
    if (hatStyleNicht(Style::MultiStyled) && tfListe)
    {
        bool FeldRahmen = ZeichnungHintergrund::hatStyle(Style::FeldRahmen);
        bool FeldHintergrund
            = ZeichnungHintergrund::hatStyle(Style::FeldHintergrund);
        bool FeldHBild = ZeichnungHintergrund::hatStyle(Style::FeldHBild);
        bool FeldHAlpha = ZeichnungHintergrund::hatStyle(Style::FeldHAlpha);
        bool FeldBuffer = ZeichnungHintergrund::hatStyle(Style::FeldBuffer);
        for (TextFeld* tf : *tfListe)
        {
            tf->setStyle(TextFeld::Style::Rahmen, FeldRahmen);
            tf->setStyle(TextFeld::Style::Hintergrund, FeldHintergrund);
            tf->setStyle(TextFeld::Style::HBild, FeldHBild);
            tf->setStyle(TextFeld::Style::HAlpha, FeldHAlpha);
            tf->setStyle(TextFeld::Style::Buffered, FeldBuffer);
            if (schrift)
                tf->setSchriftZ(dynamic_cast<Schrift*>(schrift->getThis()));
        }
    }
    if (ZeichnungHintergrund::hatStyle(Style::MultiStyled) && tfListe && styles)
    {
        auto style = styles->begin();
        for (auto tf = tfListe->begin(); tf; tf++, style++)
        {
            tf->setStyle(
                TextFeld::Style::Rahmen, hatStyle(style, Style::FeldRahmen));
            tf->setStyle(TextFeld::Style::Hintergrund,
                hatStyle(style, Style::FeldHintergrund));
            tf->setStyle(
                TextFeld::Style::HBild, hatStyle(style, Style::FeldHBild));
            tf->setStyle(
                TextFeld::Style::HAlpha, hatStyle(style, Style::FeldHAlpha));
            tf->setStyle(
                TextFeld::Style::Buffered, hatStyle(style, Style::FeldBuffer));
        }
    }
    rend = 1;
}

void AuswahlListe::addEintrag(Text* txt) // fügt einen Eintrag hinzu
{
    TextFeld* tf = new TextFeld();
    tf->setStyle(TextFeld::Style::Center | TextFeld::Style::Sichtbar
                 | TextFeld::Style::Rahmen);
    tf->setSchriftFarbe(0xFFFFFFFF);
    tf->setRahmenBreite(1);
    tf->setRahmenFarbe(0xFFFFFFFF);
    tf->setTextZ(txt);
    tf->setSize(0, 20);
    addEintragZ(tf);
    rend = 1;
}

void AuswahlListe::addEintrag(const char* txt)
{
    Text* tx = new Text(txt);
    addEintrag(tx);
    rend = 1;
}

void AuswahlListe::addEintragZ(TextFeld* tf)
{
    if (!tfListe) tfListe = new RCArray<TextFeld>();
    if (schrift && (!tf->zSchrift() || hatStyleNicht(Style::MultiStyled)))
        tf->setSchriftZ(dynamic_cast<Schrift*>(schrift->getThis()));
    tfListe->add(tf);
    rend = 1;
}

void AuswahlListe::addEintrag(
    int pos, Text* txt) // fügt einen Eintrag bei position pos ein
{
    TextFeld* tf = new TextFeld();
    tf->setStyle(TextFeld::Style::Center | TextFeld::Style::Sichtbar
                 | TextFeld::Style::Rahmen);
    tf->setSchriftFarbe(0xFFFFFFFF);
    tf->setRahmenBreite(1);
    tf->setRahmenFarbe(0xFFFFFFFF);
    tf->setTextZ(txt);
    tf->setSize(0, 20);
    addEintragZ(pos, tf);
    rend = 1;
}

void AuswahlListe::addEintrag(int pos, const char* txt)
{
    Text* tx = new Text(txt);
    addEintrag(pos, tx);
    rend = 1;
}

void AuswahlListe::addEintragZ(int pos, TextFeld* tf)
{
    if (!tfListe) tfListe = new RCArray<TextFeld>();
    if (schrift && (!tf->zSchrift() || hatStyleNicht(Style::MultiStyled)))
        tf->setSchriftZ(dynamic_cast<Schrift*>(schrift->getThis()));
    tfListe->add(tf, pos);
    rend = 1;
}

void AuswahlListe::setEintrag(
    int pos, Text* txt) // ändert den pos - ten Eintrag
{
    TextFeld* tf = 0;
    if (tfListe) tf = tfListe->z(pos);
    if (!tf)
    {
        tf = new TextFeld();
        tf->setStyle(TextFeld::Style::Center | TextFeld::Style::Sichtbar
                     | TextFeld::Style::Rahmen);
        tf->setSchriftFarbe(0xFFFFFFFF);
        tf->setRahmenFarbe(0xFFFFFFFF);
        tf->setRahmenBreite(1);
        tf->setTextZ(txt);
        tf->setSize(0, 20);
        setEintragZ(pos, tf);
        rend = 1;
        return;
    }
    tf->setTextZ(txt);
    rend = 1;
}

void AuswahlListe::setEintrag(int pos, const char* txt)
{
    Text* tx = new Text(txt);
    setEintrag(pos, tx);
    rend = 1;
}

void AuswahlListe::setEintragZ(int pos, TextFeld* tf)
{
    if (!tfListe) tfListe = new RCArray<TextFeld>();
    if (schrift && (!tf->zSchrift() || hatStyleNicht(Style::MultiStyled)))
        tf->setSchriftZ(dynamic_cast<Schrift*>(schrift->getThis()));
    tfListe->set(tf, pos);
    rend = 1;
}

void AuswahlListe::tauschEintragPos(
    int vpos, int npos) // taucht den Eintrag vpos mit dem Eintrag npos
{
    if (tfListe)
    {
        tfListe->tausch(vpos, npos);
        if (styles) styles->tausch(vpos, npos);
        if (ahFarbeListe) ahFarbeListe->tausch(vpos, npos);
        if (ahBildListe) ahBildListe->tausch(vpos, npos);
        if (aBufferListe) aBufferListe->tausch(vpos, npos);
        if (aRahmenListe) aRahmenListe->tausch(vpos, npos);
        rend = 1;
    }
}

void AuswahlListe::removeEintrag(int pos) // löscht den Eintrag pos
{
    tfListe->remove(pos);
    rend = 1;
}

void AuswahlListe::setSchriftZ(
    Schrift* schrift) // legt die Schrift der Einträge fest
{
    if (this->schrift) this->schrift->release();
    this->schrift = schrift;
    rend = 1;
}

void AuswahlListe::setVScrollZuEintrag(int eintrag) // scrollt zum Eintrag
{
    if (vertikalScrollBar)
    {
        if (eintrag > tfListe->getLastIndex())
            eintrag = tfListe->getLastIndex();
        int y = 0;
        for (int i = 0; i < eintrag; i++)
            y += tfListe->z(i) ? tfListe->z(i)->getHeight() : 0;
        vertikalScrollBar->scroll(y);
    }
}

void AuswahlListe::updateVScroll() // scrollt zur Curser Position oder nach
                                   // Unten
{
    if (vertikalScrollBar)
    {
        int y = 0;
        for (TextFeld* tf : *tfListe)
            y += (TextFeld*)tf ? tf->getHeight() : 0;
        vertikalScrollBar->update(y,
            gr.y
                - ((rahmen
                       && ZeichnungHintergrund::hatStyle(
                           TextFeld::Style::Rahmen))
                        ? rahmen->getRBreite()
                        : 0));
    }
}

void AuswahlListe::setALRZ(Rahmen*
        rahmen) // setzt einen Zeiger zum Auswahl Rahmen (nur ohne MulitStyled)
{
    if (aRahmen) aRahmen->release();
    aRahmen = rahmen;
    rend = 1;
}

void AuswahlListe::setALRBreite(
    int br) // setzt die Breite des Auswahl Rahmens (nur ohne MultiStyled)
{
    if (!aRahmen) aRahmen = new LRahmen();
    aRahmen->setRamenBreite(br);
    rend = 1;
}

void AuswahlListe::setALRFarbe(
    int fc) // setzt die Farbe des Auswahl Rahmens (nur ohne MultiStyled)
{
    if (!aRahmen) aRahmen = new LRahmen();
    aRahmen->setFarbe(fc);
    rend = 1;
}

void AuswahlListe::setAAFZ(AlphaFeld* buffer) // setzt einen Zeiger zum Auswahl
                                              // AlpaFeld (nur ohne MultiStyled)
{
    if (aBuffer) aBuffer->release();
    aBuffer = buffer;
    rend = 1;
}

void AuswahlListe::setAAFStrength(
    int st) // setzt die Stärke des Auswahl Hintergrund Buffers (nur ohne
            // MultiStyled)
{
    if (!aBuffer) aBuffer = new AlphaFeld();
    aBuffer->setStrength(st);
    rend = 1;
}

void AuswahlListe::setAAFFarbe(
    int fc) // setzt die Farbe des Auswahl Hintergrund Buffers (nur ohne
            // MultiStyled)
{
    if (!aBuffer) aBuffer = new AlphaFeld();
    aBuffer->setFarbe(fc);
    rend = 1;
}

void AuswahlListe::setAHBild(
    Bild* bild) // setzt das Auswahl Hintergrund Bild (nur ohne MultiStyled)
{
    if (!ahBild) ahBild = new Bild();
    ahBild->neuBild(bild->getBreite(), bild->getHeight(), 0);
    int* buff1 = ahBild->getBuffer();
    int* buff2 = bild->getBuffer();
    for (int i = 0; i < bild->getBreite() * bild->getHeight(); ++i)
        buff1[i] = buff2[i];
    bild->release();
    rend = 1;
}

void AuswahlListe::setAHFarbe(int f) // setzt einen Zeiger zur Auswahl
                                     // Hintergrund Farbe (nur ohne MultiStyled)
{
    ahFarbe = f;
    rend = 1;
}

void AuswahlListe::setAHBildZ(
    Bild* b) // setzt einen Zeiger zum Hintergrund Bild (nur ohne MultiStyled)
{
    if (ahBild) ahBild->release();
    ahBild = b;
    rend = 1;
}

void AuswahlListe::setALRZ(int pos,
    Rahmen*
        rahmen) // setzt einen Zeiger zum Auswahl Rahmen (nur mit MulitStyled)
{
    if (!aRahmenListe) aRahmenListe = new RCArray<Rahmen>();
    aRahmenListe->set(rahmen, pos);
    rend = 1;
}

void AuswahlListe::setALRBreite(int pos,
    int br) // setzt die Breite des Auswahl Rahmens (nur mit MultiStyled)
{
    if (!aRahmenListe) aRahmenListe = new RCArray<Rahmen>();
    if (!aRahmenListe->z(pos)) aRahmenListe->set(new LRahmen(), pos);
    aRahmenListe->z(pos)->setRamenBreite(br);
    rend = 1;
}

void AuswahlListe::setALRFarbe(int pos,
    int fc) // setzt die Farbe des Auswahl Rahmens (nur mit MultiStyled)
{
    if (!aRahmenListe) aRahmenListe = new RCArray<Rahmen>();
    if (!aRahmenListe->z(pos)) aRahmenListe->set(new LRahmen(), pos);
    aRahmenListe->z(pos)->setFarbe(fc);
    rend = 1;
}

void AuswahlListe::setAAFZ(int pos,
    AlphaFeld*
        buffer) // setzt einen Zeiger zum Auswahl AlpaFeld (nur mit MultiStyled)
{
    if (!aBufferListe) aBufferListe = new RCArray<AlphaFeld>();
    aBufferListe->set(buffer, pos);
    rend = 1;
}

void AuswahlListe::setAAFStrength(
    int pos, int st) // setzt die Stärke des Auswahl Hintergrund Buffers (nur
                     // mit MultiStyled)
{
    if (!aBufferListe) aBufferListe = new RCArray<AlphaFeld>();
    if (!aBufferListe->z(pos)) aBufferListe->set(new AlphaFeld(), pos);
    aBufferListe->z(pos)->setStrength(st);
    rend = 1;
}

void AuswahlListe::setAAFFarbe(
    int pos, int fc) // setzt die Farbe des Auswahl Hintergrund Buffers (nur mit
                     // MultiStyled)
{
    if (!aBufferListe) aBufferListe = new RCArray<AlphaFeld>();
    if (!aBufferListe->z(pos)) aBufferListe->set(new AlphaFeld(), pos);
    aBufferListe->z(pos)->setFarbe(fc);
    rend = 1;
}

void AuswahlListe::setAHBild(int pos,
    Bild* bild) // setzt das Auswahl Hintergrund Bild (nur mit MultiStyled)
{
    if (ahBildListe) ahBildListe = new RCArray<Bild>();
    if (!ahBildListe->z(pos)) ahBildListe->set(new Bild(), pos);
    ahBildListe->z(pos)->neuBild(bild->getBreite(), bild->getHeight(), 0);
    int* buff1 = ahBildListe->z(pos)->getBuffer();
    int* buff2 = bild->getBuffer();
    for (int i = 0; i < bild->getBreite() * bild->getHeight(); ++i)
        buff1[i] = buff2[i];
    bild->release();
    rend = 1;
}

void AuswahlListe::setAHFarbe(
    int pos, int f) // setzt einen Zeiger zur Auswahl Hintergrund Farbe (nur miz
                    // MultiStyled)
{
    if (ahFarbeListe) ahFarbeListe = new Array<int>();
    ahFarbeListe->set(f, pos);
    rend = 1;
}

void AuswahlListe::setAHBildZ(int pos,
    Bild* b) // setzt einen Zeiger zum Hintergrund Bild (nur mit MultiStyled)
{
    if (ahBildListe) ahBildListe = new RCArray<Bild>();
    ahBildListe->set(b, pos);
    rend = 1;
}

void AuswahlListe::setMsStyle(int pos,
    __int64 style) // setzt den Style des Eintrags (nur mit MultiStyled)
{
    if (!styles) styles = new Array<__int64>();
    styles->set(style, pos);
    rend = 1;
}

void AuswahlListe::setMsStyle(int pos, __int64 style, bool add_remove)
{
    if (!styles) styles = new Array<__int64>();
    if (add_remove)
        styles->set(styles->get(pos) | style, pos);
    else
        styles->set(styles->get(pos) & ~style, pos);
    rend = 1;
}

void AuswahlListe::addMsStyle(int pos, __int64 style)
{
    if (!styles) styles = new Array<__int64>();
    styles->set(styles->get(pos) | style, pos);
    rend = 1;
}

void AuswahlListe::removeMsStyle(int pos, __int64 style)
{
    if (!styles) styles = new Array<__int64>();
    styles->set(styles->get(pos) & ~style, pos);
    rend = 1;
}

void AuswahlListe::doTastaturEreignis(TastaturEreignis& te)
{
    bool ntakc = !te.verarbeitet;
    if (hatStyleNicht(Style::Fokus) || !tak || te.verarbeitet) return;
    getThis();
    if (tak(takParam, this, te))
    {
        if (te.id == TE_Press)
        {
            if (hatStyleNicht(Style::MultiSelect))
            {
                switch (te.virtualKey)
                {
                case T_Unten:
                    ++auswahl;
                    if (auswahl > tfListe->getEintragAnzahl())
                        auswahl = tfListe->getEintragAnzahl();
                    rend = 1;
                    break;
                case T_Oben:
                    --auswahl;
                    if (auswahl < -1) auswahl = -1;
                    rend = 1;
                    break;
                }
            }
            else
            {
                switch (te.virtualKey)
                {
                case T_Unten:
                    deSelect();
                    ++auswahl;
                    if (auswahl > tfListe->getEintragAnzahl())
                        auswahl = tfListe->getEintragAnzahl();
                    if (auswahl >= 0) addMsStyle(auswahl, Style::Selected);
                    rend = 1;
                    break;
                case T_Oben:
                    deSelect();
                    --auswahl;
                    if (auswahl < -1) auswahl = -1;
                    if (auswahl >= 0) addMsStyle(auswahl, Style::Selected);
                    rend = 1;
                    break;
                }
            }
        }
        te.verarbeitet = 1;
    }
    if (ntakc && te.verarbeitet && nTak)
        te.verarbeitet = nTak(ntakParam, this, te);
    release();
}

void AuswahlListe::render(Bild& zRObj) // zeichnet nach zRObj
{
    if (!ZeichnungHintergrund::hatStyle(Style::Sichtbar)) return;
    removeStyle(Style::HScroll);
    ZeichnungHintergrund::render(zRObj);
    lockZeichnung();
    if (!zRObj.setDrawOptions(innenPosition, innenSize))
    {
        unlockZeichnung();
        return;
    }
    int rbr = 0;
    if (rahmen && ZeichnungHintergrund::hatStyle(Style::Rahmen))
        rbr = rahmen->getRBreite();
    if (tfListe)
    {
        int maxHeight = 0;
        int dx = 0, dy = 0;
        if (vertikalScrollBar && ZeichnungHintergrund::hatStyle(Style::VScroll))
            dy -= vertikalScrollBar->getScroll();
        int mdy = innenSize.y + rbr;
        auto style = styles->begin();
        int i = 0;
        for (auto tf = tfListe->begin(); tf; tf++, style++, i++)
        {
            if (dy + tf->getHeight() > mdy
                && !(vertikalScrollBar
                     && ZeichnungHintergrund::hatStyle(Style::VScroll)))
                break;
            tf->setPosition(dx, dy);
            tf->setSize(innenSize.x, tf->getHeight());
            maxHeight += tf->getHeight();
            bool selected = 0;
            if (ZeichnungHintergrund::hatStyle(Style::MultiSelect) && styles)
                selected = hatStyle(style, Style::Selected);
            else
                selected = auswahl == i;
            AlphaFeld* tmpBuffer = 0;
            bool tmpB = 0;
            int tmpHFarbe = 0;
            bool tmpH = 0;
            Bild* tmpHBild = 0;
            bool tmpHB = 0;
            bool tmpHAlpha = 0;
            Rahmen* tmpRahmen = 0;
            bool tmpR = 0;
            if (selected)
            {
                if (hatStyleNicht(Style::MultiStyled) || !styles)
                {
                    if (ZeichnungHintergrund::hatStyle(Style::AuswahlBuffer)
                        && aBuffer)
                    {
                        tmpBuffer = tf->getAlphaFeld();
                        tf->setAlphaFeldZ(
                            dynamic_cast<AlphaFeld*>(aBuffer->getThis()));
                        tmpB = tf->hatStyle(TextFeld::Style::Buffered);
                        tf->setStyle(TextFeld::Style::Buffered,
                            ZeichnungHintergrund::hatStyle(
                                Style::AuswahlBuffer));
                    }
                    if (ZeichnungHintergrund::hatStyle(
                            Style::AuswahlHintergrund))
                    {
                        tmpH = tf->hatStyle(TextFeld::Style::Hintergrund);
                        tmpHFarbe = tf->getHintergrundFarbe();
                        tf->setHintergrundFarbe(ahFarbe);
                        tf->setStyle(TextFeld::Style::Hintergrund,
                            ZeichnungHintergrund::hatStyle(Style::Hintergrund));
                        if (ZeichnungHintergrund::hatStyle(Style::AuswahlHBild)
                            && ahBild)
                        {
                            tmpHBild = tf->getHintergrundBild();
                            tf->setHintergrundBildZ(
                                dynamic_cast<Bild*>(ahBild->getThis()));
                            tmpHB = tf->hatStyle(TextFeld::Style::HBild);
                            tf->setStyle(TextFeld::Style::HBild,
                                ZeichnungHintergrund::hatStyle(Style::HBild));
                        }
                        if (ZeichnungHintergrund::hatStyle(
                                Style::AuswahlHAlpha))
                        {
                            tmpHAlpha = tf->hatStyle(TextFeld::Style::HAlpha);
                            tf->setStyle(TextFeld::Style::HAlpha,
                                ZeichnungHintergrund::hatStyle(
                                    Style::AuswahlHAlpha));
                        }
                    }
                    if (ZeichnungHintergrund::hatStyle(Style::AuswahlRahmen)
                        && aRahmen)
                    {
                        tmpRahmen = tf->getRahmen();
                        tf->setRahmenZ(
                            dynamic_cast<Rahmen*>(aRahmen->getThis()));
                        tmpR = tf->hatStyle(TextFeld::Style::Rahmen);
                        tf->setStyle(TextFeld::Style::Rahmen,
                            ZeichnungHintergrund::hatStyle(
                                Style::AuswahlRahmen));
                    }
                }
                else
                {
                    if (hatStyle(style, Style::AuswahlBuffer) && aBufferListe)
                    {
                        tmpBuffer = tf->getAlphaFeld();
                        tf->setAlphaFeldZ(aBufferListe->get(i));
                        tmpB = tf->hatStyle(TextFeld::Style::Buffered);
                        tf->setStyle(TextFeld::Style::Buffered,
                            hatStyle(style, Style::AuswahlBuffer));
                    }
                    if (hatStyle(style, Style::AuswahlHintergrund))
                    {
                        tmpH = tf->hatStyle(Style::Hintergrund);
                        tf->setStyle(TextFeld::Style::Hintergrund,
                            hatStyle(style, Style::AuswahlHintergrund));
                        if (ahFarbeListe && ahFarbeListe->hat(i))
                        {
                            tmpHFarbe = tf->getHintergrundFarbe();
                            tf->setHintergrundFarbe(ahFarbeListe->get(i));
                        }
                        if (hatStyle(style, Style::AuswahlHBild) && ahBildListe)
                        {
                            tmpHBild = tf->getHintergrundBild();
                            tf->setHintergrundBildZ(ahBildListe->get(i));
                            tmpHB = tf->hatStyle(TextFeld::Style::HBild);
                            tf->setStyle(TextFeld::Style::HBild,
                                hatStyle(style, Style::HBild));
                        }
                        if (hatStyle(style, Style::AuswahlHAlpha))
                        {
                            tmpHAlpha = tf->hatStyle(TextFeld::Style::HAlpha);
                            tf->setStyle(TextFeld::Style::HAlpha,
                                hatStyle(style, Style::AuswahlHAlpha));
                        }
                    }
                    if (hatStyle(style, Style::AuswahlRahmen) && aRahmenListe)
                    {
                        tmpRahmen = tf->getRahmen();
                        tf->setRahmenZ(aRahmenListe->get(i));
                        tmpR = tf->hatStyle(TextFeld::Style::Rahmen);
                        tf->setStyle(TextFeld::Style::Rahmen,
                            hatStyle(style, Style::AuswahlRahmen));
                    }
                }
            }
            tf->render(zRObj);
            if (selected)
            {
                if (hatStyleNicht(Style::MultiStyled) || !styles)
                {
                    if (ZeichnungHintergrund::hatStyle(Style::AuswahlBuffer))
                    {
                        tf->setAlphaFeldZ(tmpBuffer);
                        tf->setStyle(TextFeld::Style::Buffered, tmpB);
                    }
                    if (ZeichnungHintergrund::hatStyle(
                            Style::AuswahlHintergrund))
                    {
                        tf->setHintergrundFarbe(tmpHFarbe);
                        tf->setStyle(TextFeld::Style::Hintergrund, tmpH);
                        if (ZeichnungHintergrund::hatStyle(Style::AuswahlHBild))
                        {
                            tf->setHintergrundBildZ(tmpHBild);
                            tf->setStyle(TextFeld::Style::HBild, tmpHB);
                        }
                        if (ZeichnungHintergrund::hatStyle(
                                Style::AuswahlHAlpha))
                            tf->setStyle(TextFeld::Style::HAlpha, tmpHAlpha);
                    }
                    if (ZeichnungHintergrund::hatStyle(Style::AuswahlRahmen))
                    {
                        tf->setRahmenZ(tmpRahmen);
                        tf->setStyle(TextFeld::Style::Rahmen, tmpR);
                    }
                }
                else
                {
                    if (hatMsStyle(i, Style::AuswahlBuffer) && aBufferListe)
                    {
                        tf->setAlphaFeldZ(tmpBuffer);
                        tf->setStyle(TextFeld::Style::Buffered, tmpB);
                    }
                    if (hatMsStyle(i, Style::AuswahlHintergrund))
                    {
                        tf->setStyle(TextFeld::Style::Hintergrund, tmpH);
                        if (ahFarbeListe && ahFarbeListe->hat(i))
                            tf->setHintergrundFarbe(tmpHFarbe);
                        if (hatMsStyle(i, Style::AuswahlHBild) && ahBildListe)
                        {
                            tf->setHintergrundBildZ(tmpHBild);
                            tf->setStyle(TextFeld::Style::HBild, tmpHB);
                        }
                        if (hatMsStyle(i, Style::AuswahlHAlpha))
                            tf->setStyle(TextFeld::Style::HAlpha, tmpHAlpha);
                    }
                    if (hatMsStyle(i, Style::AuswahlRahmen) && aRahmenListe)
                    {
                        tf->setRahmenZ(tmpRahmen);
                        tf->setStyle(TextFeld::Style::Rahmen, tmpR);
                    }
                }
            }
            dy += tf->getHeight();
        }
        if (vertikalScrollBar)
            vertikalScrollBar->getScrollData()->max = maxHeight;
    }
    zRObj.releaseDrawOptions();
    unlockZeichnung();
}

int AuswahlListe::getKlickEintrag(int my)
{
    if (!tfListe) return -1;
    int y = 0;
    if (ZeichnungHintergrund::hatStyle(Style::VScroll) && vertikalScrollBar)
        y -= vertikalScrollBar->getScroll();
    int i = 0;
    for (auto tf = tfListe->begin(); tf; tf++, i++)
    {
        y += tf->getHeight();
        if (y > my) return i;
    }
    return -1;
}

void AuswahlListe::setAuswahl(int ausw) // setzt die Auswahl
{
    if (hatStyleNicht(Style::MultiSelect))
        auswahl = ausw;
    else if (styles)
    {
        for (int i = 0; i < styles->getEintragAnzahl(); ++i)
            removeMsStyle(i, Style::Selected);
        addMsStyle(ausw, Style::Selected);
    }
}

void AuswahlListe::deSelect()
{
    if (hatStyleNicht(Style::MultiSelect))
        auswahl = -1;
    else if (styles)
    {
        for (int i = 0; i < styles->getEintragAnzahl(); ++i)
            removeMsStyle(i, Style::Selected);
    }
}

// constant
int AuswahlListe::getEintragAnzahl()
    const // gibt die Anzahl der Einträge zurück
{
    return tfListe ? tfListe->getEintragAnzahl() : 0;
}

int AuswahlListe::getAuswahl()
    const // gibt den ersten ausgewählten Eintrag zurück
{
    return auswahl;
}

int AuswahlListe::getEintragPos(
    Text* eintragText) // gibt die Position des eintrages mit dem entsprechenden
                       // Textes zurück
{
    int i = 0;
    for (auto tf = tfListe->begin(); tf; tf++, i++)
    {
        if (tf->zText()->istGleich(eintragText->getText()))
        {
            eintragText->release();
            return i;
        }
    }
    return -1;
}

TextFeld* AuswahlListe::getEintrag(
    int pos) const // gibt den pos- ten Eintrag zurück
{
    if (!tfListe) return 0;
    TextFeld* ret = (TextFeld*)tfListe->get(pos);
    if (ret) return dynamic_cast<TextFeld*>(ret->getThis());
    return 0;
}

TextFeld* AuswahlListe::zEintrag(int pos) const
{
    if (!tfListe) return 0;
    return (TextFeld*)tfListe->z(pos);
}

Rahmen* AuswahlListe::getARahmen()
    const // gibt den Auswahl Rahmen zurück (ohne MultiStyled)
{
    if (aRahmen) return dynamic_cast<Rahmen*>(aRahmen->getThis());
    return 0;
}

Rahmen* AuswahlListe::zARahmen() const
{
    return aRahmen;
}

int AuswahlListe::getAHFarbe()
    const // gibt die Auswahl Hintergrund Farbe zurück (ohne MultiStyled)
{
    return ahFarbe;
}

Bild* AuswahlListe::getAHBild()
    const // gibt das Auswahl Hintergrund Bild zurück (ohne MultiStyled)
{
    if (ahBild) return dynamic_cast<Bild*>(ahBild->getThis());
    return 0;
}

Bild* AuswahlListe::zAHBild() const
{
    return ahBild;
}

AlphaFeld* AuswahlListe::getABuffer()
    const // gibt den Auswahl Buffer zurück (ohne MultiStyled)
{
    if (aBuffer) return dynamic_cast<AlphaFeld*>(aBuffer->getThis());
    return 0;
}

AlphaFeld* AuswahlListe::zABuffer() const
{
    return aBuffer;
}

Rahmen* AuswahlListe::getARahmen(
    int pos) const // gibt den Auswahl Rahmen zurück (mit MultiStyled)
{
    Rahmen* ret = 0;
    if (aRahmenListe) ret = (Rahmen*)aRahmenListe->get(pos);
    if (ret) return dynamic_cast<Rahmen*>(ret->getThis());
    return 0;
}

Rahmen* AuswahlListe::zARahmen(int pos) const
{
    Rahmen* ret = 0;
    if (aRahmenListe) ret = (Rahmen*)aRahmenListe->z(pos);
    return ret;
}

int AuswahlListe::getAHFarbe(int pos)
    const // gibt die Auswahl Hintergrund Farbe zurück (mit MultiStyled)
{
    if (ahFarbeListe && ahFarbeListe->hat(pos)) return ahFarbeListe->get(pos);
    return 0;
}

Bild* AuswahlListe::getAHBild(
    int pos) const // gibt das Auswahl Hintergrund Bild zurück (mit MultiStyled)
{
    Bild* ret = 0;
    if (ahBildListe) ret = (Bild*)ahBildListe->get(pos);
    if (ret) return dynamic_cast<Bild*>(ret->getThis());
    return 0;
}

Bild* AuswahlListe::zAHBild(int pos) const
{
    Bild* ret = 0;
    if (ahBildListe) ret = (Bild*)ahBildListe->z(pos);
    return ret;
}

AlphaFeld* AuswahlListe::getABuffer(
    int pos) const // gibt den Auswahl Buffer zurück (mit MultiStyled)
{
    AlphaFeld* ret = 0;
    if (aBufferListe) ret = (AlphaFeld*)aBufferListe->get(pos);
    if (ret) return dynamic_cast<AlphaFeld*>(ret->getThis());
    return 0;
}

AlphaFeld* AuswahlListe::zABuffer(int pos) const
{
    AlphaFeld* ret = 0;
    if (aBufferListe) ret = (AlphaFeld*)aBufferListe->z(pos);
    return ret;
}

bool AuswahlListe::hatMsStyle(
    int pos, __int64 style) const // prüft ob style vorhanden (mit MultiStyled)
{
    __int64 st = 0;
    if (styles) st = styles->get(pos);
    return (st | style) == st;
}

bool AuswahlListe::hatMsStyleNicht(int pos,
    __int64 style) const // prüft obt style nicht vorhanden (mit MultiStyled)
{
    __int64 st = 0;
    if (styles) st = styles->get(pos);
    return (st | style) != st;
}

//! Konstruktor
ZListe::ZListe()
    : ZeichnungHintergrund()
{
    entrySeperatorSize = 1;
    entrySeperatorColor = 0xFFFFFFFF;
    setRahmenBreite(1);
    setRahmenFarbe(0xFFFFFFFF);
    setHintergrundFarbe(0xFF000000);
}

//! Destruktor
ZListe::~ZListe() {}

//! Verarbeitet Tastatur Nachrichten
//! \param me Das Ereignis, was durch die Tastatureingabe ausgelößt wurde
void ZListe::doMausEreignis(MausEreignis& me, bool userRet)
{
    if (ZeichnungHintergrund::hatStyle(Style::VScroll) && vertikalScrollBar)
    {
        int rbr = 0;
        if (rahmen && ZeichnungHintergrund::hatStyle(Style::Rahmen))
            rbr = rahmen->getRBreite();
        if (((me.mx > gr.x - 15 - rbr) || me.id == ME_UScroll
                || me.id == ME_DScroll)
            && me.id != ME_Betritt && me.id != ME_Leaves)
        {
            vertikalScrollBar->doMausMessage(
                gr.x - rbr - 15, rbr, 15, gr.y - rbr * 2, me);
            me.verarbeitet = 1;
        }
        me.my += vertikalScrollBar->getScroll();
    }
    me.my -= (rahmen && ZeichnungHintergrund::hatStyle(TextFeld::Style::Rahmen))
               ? rahmen->getRBreite() * 2
               : 0;
    me.mx -= (rahmen && ZeichnungHintergrund::hatStyle(TextFeld::Style::Rahmen))
               ? rahmen->getRBreite() * 2
               : 0;
    int ySum = 0;
    int index = 0;
    for (Zeichnung* entry : list)
    {
        entry->doPublicMausEreignis(me);
        ySum += entry->getHeight();
        me.my -= entry->getHeight();
        if (index < list.getLastIndex())
        {
            ySum
                += ZeichnungHintergrund::hatStyle(ZListe::Style::EntrySeperator)
                     ? entrySeperatorSize
                     : 0;
            me.my
                -= ZeichnungHintergrund::hatStyle(ZListe::Style::EntrySeperator)
                     ? entrySeperatorSize
                     : 0;
        }
        index++;
    }
    me.my
        += ySum
                 + (rahmen
                     && ZeichnungHintergrund::hatStyle(TextFeld::Style::Rahmen))
             ? rahmen->getRBreite() * 2
             : 0;
    me.mx += (rahmen && ZeichnungHintergrund::hatStyle(TextFeld::Style::Rahmen))
               ? rahmen->getRBreite() * 2
               : 0;
    if (ZeichnungHintergrund::hatStyle(Style::VScroll) && vertikalScrollBar)
        me.my -= vertikalScrollBar->getScroll();
}

//! Fügt einen Eintrag hinzu
//! \param entry Die Zeichnung die hinzugefügt werden soll
void ZListe::addEintrag(Zeichnung* entry)
{
    rend = 1;
    list.add(entry);
}

//! Ändert einen Eintrag
//! \param pos Der Index des Eintrags
//! \param entry Die neue Zeichnung
void ZListe::setEintrag(int pos, Zeichnung* entry)
{
    rend = 1;
    list.set(entry, pos);
}

//! Vertauscht die Positionen zweier Einträge
//! \param vpos Der Index des ersten Eintrags
//! \param npos Der Index des zweiten Eintrags
void ZListe::tauschEintragPos(int vPos, int nPos)
{
    rend = 1;
    list.tausch(vPos, nPos);
}

//! Löscht einen Eintrag
//! pos: Der Index des Eintrags
void ZListe::removeEintrag(int pos)
{
    rend = 1;
    list.remove(pos);
}

//! Scrollt zu einem bestimmen Eintrag
//! \param eintrag Der Index des Eintrags
void ZListe::setVScrollZuEintrag(int eintrag)
{
    if (vertikalScrollBar)
    {
        if (eintrag > list.getLastIndex()) eintrag = list.getLastIndex();
        int y = 0;
        int index = 0;
        for (Zeichnung* entry : list)
        {
            y += entry->getHeight();
            if (index < list.getLastIndex())
                y += ZeichnungHintergrund::hatStyle(
                         ZListe::Style::EntrySeperator)
                       ? entrySeperatorSize
                       : 0;
            index++;
        }
        vertikalScrollBar->scroll(y);
    }
}

//! Aktualisiert die maximale Scroll Höhe indem die Höhe aller Einträge addiert
//! wird
void ZListe::updateVScroll()
{
    if (vertikalScrollBar)
    {
        int y = 0;
        int index = 0;
        for (Zeichnung* entry : list)
        {
            y += entry->getHeight();
            if (index < list.getLastIndex())
                y += ZeichnungHintergrund::hatStyle(
                         ZListe::Style::EntrySeperator)
                       ? entrySeperatorSize
                       : 0;
            index++;
        }
        vertikalScrollBar->update(y,
            gr.y
                - ((rahmen
                       && ZeichnungHintergrund::hatStyle(
                           TextFeld::Style::Rahmen))
                        ? rahmen->getRBreite() * 2
                        : 0));
    }
}

//! sets the size of the entry seperator
void ZListe::setEntrySeperatorSize(int size)
{
    entrySeperatorSize = size;
}

//! sets the color of the entry seperator
void ZListe::setEntrySeperatorColor(int color)
{
    entrySeperatorColor = color;
}

//! Verarbeitet ein Tastatur Ereignis. Wird vom Framework automatisch aufgerufen
//! \param te Das Ereignis
void ZListe::doTastaturEreignis(TastaturEreignis& te)
{
    for (Zeichnung* entry : list)
        entry->doTastaturEreignis(te);
}

//! Aktualisiert die zeichnung
//! \param tickVal Die vergangene Zeit in Sekunden, die seit dem Letzten Aufruf
//! dieser Funktion verstrichen ist \return 1, wenn sich die Zeichnung seit dem
//! letzten aufruf verändert hat
bool ZListe::tick(double tickVal)
{
    bool ret = ZeichnungHintergrund::tick(tickVal);
    for (Zeichnung* entry : list)
        ret |= entry->tick(tickVal);
    return ret;
}

//! Zeichnet das Objekt nach zRObj, falls es sichtbar ist
//! \param zRObj Das Bild, in welches gezeichnet werden soll
void ZListe::render(Bild& rObj)
{
    ZeichnungHintergrund::render(rObj);
    int index = 0;
    int rbr = rahmen && ZeichnungHintergrund::hatStyle(TextFeld::Style::Rahmen)
                ? rahmen->getRBreite()
                : 0;
    bool vs = vertikalScrollBar && hatStyle(Style::VScroll);
    if (rObj.setDrawOptions(pos + Punkt(rbr, rbr),
            gr - Punkt(rbr, rbr) * 2 - Punkt(vs ? 15 : 0, 0)))
    {
        if (vs) rObj.addScrollOffset(0, vertikalScrollBar->getScroll());
        for (Zeichnung* entry : list)
        {
            entry->setWidth(gr.x - rbr * 2 - (vs ? 15 : 0));
            entry->render(rObj);
            rObj.addScrollOffset(0, -entry->getHeight());
            if (index < list.getLastIndex()
                && ZeichnungHintergrund::hatStyle(
                    ZListe::Style::EntrySeperator))
            {
                for (int i = 0; i < entrySeperatorSize; i++)
                {
                    rObj.drawLinieHAlpha(
                        0, 0, gr.x - rbr - (vs ? 15 : 0), entrySeperatorColor);
                    rObj.addScrollOffset(0, -1);
                }
            }
            index++;
        }
        rObj.releaseDrawOptions();
    }
}

//! Gibt den Index eines Eintrags zurück, auf den die Maus zeigt
//! \param my Die Position der Maus auf der Y Achse basierend auf dem oberend
//! Rand der Liste
int ZListe::getKlickEintrag(int my)
{
    if (my < 0) return -1;
    int index = 0;
    int y = 0;
    for (Zeichnung* entry : list)
    {
        if (my < y) return index;
        y += entry->getHeight();
        if (index < list.getLastIndex())
            y += ZeichnungHintergrund::hatStyle(ZListe::Style::EntrySeperator)
                   ? entrySeperatorSize
                   : 0;
        index++;
    }
    return -1;
}

//! Gibt die Anzahl an Einträgen zurück
int ZListe::getEintragAnzahl() const
{
    return list.getEintragAnzahl();
}

//! Gibt den Index eines Eintrags zurück
//! \param zEntry Die Zeichnung
int ZListe::getEintragPos(Zeichnung* zEntry)
{
    int index = 0;
    for (Zeichnung* entry : list)
    {
        if (zEntry == entry) return index;
        index++;
    }
    return -1;
}

//! Gibt einen Eintrag zurück
//! \param pos Der Index des Eintrags
Zeichnung* ZListe::getEintrag(int pos) const
{
    return list.get(pos);
}

//! Gibt einen Eintrag ohne erhöhten reference Counter zurück
//! \param pos Der Index des Eintrags
Zeichnung* ZListe::zEintrag(int pos) const
{
    return list.get(pos);
}

//! Gibt die benötigte Höhe zurück
int ZListe::getNeededHeight() const
{
    int y = (rahmen && ZeichnungHintergrund::hatStyle(TextFeld::Style::Rahmen))
              ? rahmen->getRBreite() * 2
              : 0;
    int index = 0;
    for (Zeichnung* entry : list)
    {
        y += entry->getHeight();
        if (index < list.getLastIndex())
            y += ZeichnungHintergrund::hatStyle(ZListe::Style::EntrySeperator)
                   ? entrySeperatorSize
                   : 0;
        index++;
    }
    return y;
}

//! returns the size of the entry seperator
int ZListe::getEntrySeperatorSize() const
{
    return entrySeperatorSize;
}

//! returns the color of the entry seperator
int ZListe::getEntrySeperatorColor() const
{
    return entrySeperatorColor;
}