#include "SelectionBox.h"

#include "AlphaField.h"
#include "Border.h"
#include "Button.h"
#include "Font.h"
#include "Image.h"
#include "KeyboardEvent.h"
#include "MouseEvent.h"
#include "Scroll.h"
#include "Text.h"
#include "TextField.h"
#include "ToolTip.h"

using namespace Framework;

// Contents of the SelectionBox class from SelectionBox.h
// Constructor
SelectionBox::SelectionBox()
    : DrawableBackground(),
      textRd(0),
      msStyle(0),
      members(new RCArray<TextField>()),
      ausfahren(new Button()),
      selBorder(new LBorder()),
      selBgF(0xFF000000),
      selBgB(0),
      selAf(new AlphaField()),
      msSelBorder(0),
      msSelBgF(0),
      msSelBgB(0),
      msSelAf(0),
      mouseBorder(new LBorder()),
      mouseBgF(0xFF000000),
      mouseBgB(0),
      mouseAf(new AlphaField()),
      msMouseBorder(0),
      msMouseBgF(0),
      msMouseBgB(0),
      msMouseAf(0),
      anzahl(0),
      selection(0),
      ausgeklappt(0),
      ausklappHeight(0),
      ausklapMaxHeight(200),
      entryHeight(15),
      tickval(0),
      mouseEntry(0),
      scrollAnzeigen(0),
      eAkP(0),
      eAk(0)
{
    vertikalScrollBar = new VScrollBar();
    style = Style::Normal;
    border = new LBorder();
    border->setColor(0xFFFFFFFF);
    border->setBorderWidth(1);
    ausfahren->setStyle(Button::Style::Visible | Button::Style::Allowed
                        | Button::Style::ClickBuffer);
    ausfahren->setKBColor(0xA0000000);
    ausfahren->setKBStrength(10);
    ausfahren->setSize(18, 18);
    ausfahren->setFontColor(0xFFFFFFFF);
    ausfahren->setText("\\/");
    selBorder->setColor(0xFF00FF00);
    selBorder->setBorderWidth(1);
    selAf->setColor(0xA000FF00);
    selAf->setStrength(7);
    mouseBorder->setColor(0xFF00FF00);
    mouseBorder->setBorderWidth(1);
    mouseAf->setColor(0x5000FF00);
    mouseAf->setStrength(7);
    gr.x = 20;
    gr.y = 20;
}

// Destructor
SelectionBox::~SelectionBox()
{
    if (textRd) textRd->release();
    if (msStyle) msStyle->release();
    if (members) members->release();
    if (ausfahren) ausfahren->release();
    if (selBorder) selBorder->release();
    if (selBgB) selBgB->release();
    if (selAf) selAf->release();
    if (msSelBorder) msSelBorder->release();
    if (msSelAf) msSelAf->release();
    if (msSelBgB) msSelBgB->release();
    if (msSelBgF) msSelBgF->release();
    if (mouseBorder) mouseBorder->release();
    if (mouseAf) mouseAf->release();
    if (mouseBgB) mouseBgB->release();
    if (msMouseBorder) msMouseBorder->release();
    if (msMouseAf) msMouseAf->release();
    if (msMouseBgB) msMouseBgB->release();
    if (msMouseBgF) msMouseBgF->release();
}

void SelectionBox::doMouseEvent(MouseEvent& me, bool userRet) // mouse events
{
    if (hasStyleNot(Style::Allowed) || hasStyleNot(Style::Focus)
        || me.processed)
    {
        ausgeklappt = 0;
        me.processed = 1;
        return;
    }
    if (!userRet) return;
    mouseEntry = -1;
    bool insideParent = me.insideParent;
    me.insideParent = me.mx >= 0 && me.mx < gr.x && me.my >= 0
                   && me.my < gr.y + ausklappHeight;
    bool vera = me.processed;
    if (ausfahren)
    {
        int tmpMx = me.mx;
        int tmpMy = me.my;
        if (me.mx >= 0 && me.my >= 0 && me.mx < gr.x && me.my < gr.y)
            me.mx = ausfahren->getX(), me.my = ausfahren->getY() + 1;
        ausfahren->doPublicMouseEvent(me);
        me.mx = tmpMx, me.my = tmpMy;
    }
    if (me.processed && !vera && me.id == ME_RLeft)
    {
        ausgeklappt = !ausgeklappt;
        if (ausgeklappt) mouseEntry = selection;
        if (scrollAnzeigen) scrollToEntry(mouseEntry);
    }
    if (hasStyle(Style::VScroll) && vertikalScrollBar && ausgeklappt
        && scrollAnzeigen)
    {
        int rbr = 0;
        if (border && hasStyle(Style::Border)) rbr = border->getRWidth();
        if ((me.mx > gr.x - 15 - rbr && me.my > gr.y) || me.id == ME_UScroll
            || me.id == ME_DScroll)
        {
            vertikalScrollBar->doMouseMessage(gr.x - rbr - 15,
                gr.y,
                15,
                vertikalScrollBar->getScrollData()->anzeige,
                me);
            me.processed = 1;
        }
    }
    if (!me.processed)
    {
        int eintr = -1;
        int tmp = me.my - gr.y
                + (vertikalScrollBar ? vertikalScrollBar->getScroll() : 0);
        if (hasStyle(Style::MultiStyled))
        {
            for (int i = 0; i < anzahl; ++i)
            {
                if (tmp > 0
                    && tmp < (members->z(i) ? members->z(i)->getHeight() : 0))
                {
                    eintr = i;
                    break;
                }
                tmp -= members->z(i) ? members->z(i)->getHeight() : 0;
            }
        }
        else
        {
            for (int i = 0; i < anzahl; ++i)
            {
                if (tmp > 0 && tmp < entryHeight)
                {
                    eintr = i;
                    break;
                }
                tmp -= entryHeight;
            }
        }
        if (ausgeklappt && me.mx > 0 && me.mx < gr.x && me.my > gr.y
            && me.my < gr.y + ausklappHeight)
        {
            if (eintr >= 0)
            {
                if (me.id == ME_RLeft)
                {
                    if (selection != eintr) rend = 1;
                    selection = eintr;
                    if (eAk) eAk(eAkP, this, 0, selection);
                }
                if (mouseEntry != eintr) rend = 1;
                mouseEntry = eintr;
            }
        }
    }
    me.processed = 1;
    me.insideParent = insideParent;
}

// non-constant
void SelectionBox::setEventParam(void* p) // set event parameter
{
    eAkP = p;
}

void SelectionBox::setEventAktion(
    std::function<void(void*, SelectionBox*, int, int)>
        event) // set event action
{
    this->eAk = event;
}

void SelectionBox::setFontZ(Font* font) // set font
{
    if (!this->textRd)
        textRd = new TextRenderer(font);
    else
        textRd->setFontZ(font);
    ausfahren->setFontZ(dynamic_cast<Font*>(font->getThis()));
    rend = 1;
}

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

void SelectionBox::addEntry(const char* txt) // add entry
{
    TextField* tf = new TextField();
    if (textRd) tf->setFontZ(textRd->getFont());
    tf->addStyle(TextField::Style::Visible | TextField::Style::Center
                 | TextField::Style::Border);
    tf->setText(txt);
    tf->setFontColor(0xFFFFFFFF);
    tf->setBorderColor(0xFFFFFFFF);
    tf->setSize(0, entryHeight);
    members->add(tf, anzahl);
    ++anzahl;
    rend = 1;
}

void SelectionBox::addEntry(Text* txt)
{
    TextField* tf = new TextField();
    if (textRd) tf->setFontZ(textRd->getFont());
    tf->addStyle(TextField::Style::Visible | TextField::Style::Center
                 | TextField::Style::Border);
    tf->setText(txt);
    tf->setFontColor(0xFFFFFFFF);
    tf->setBorderColor(0xFFFFFFFF);
    tf->setSize(0, entryHeight);
    members->add(tf, anzahl);
    ++anzahl;
    rend = 1;
}

void SelectionBox::addEntryZ(TextField* txt)
{
    members->add(txt, anzahl);
    ++anzahl;
    rend = 1;
}

void SelectionBox::setEntry(int i, const char* txt) // set entry text
{
    if (members->z(i)) members->z(i)->setText(txt);
    rend = 1;
}

void SelectionBox::setEntry(int i, Text* txt)
{
    if (members->z(i))
        members->z(i)->setText(txt);
    else
        txt->release();
    rend = 1;
}

void SelectionBox::setEntryZ(int i, TextField* txt)
{
    if (i < anzahl)
        members->set(txt, i);
    else
        txt->release();
    rend = 1;
}

void SelectionBox::removeEntry(int i) // remove entry
{
    if (i < anzahl)
    {
        members->remove(i);
        if (msStyle) msStyle->remove(i);
        if (msSelBorder) msSelBorder->remove(i);
        if (msSelBgF) msSelBgF->remove(i);
        if (msSelBgB) msSelBgB->remove(i);
        if (msSelAf) msSelAf->remove(i);
        if (msMouseBorder) msMouseBorder->remove(i);
        if (msMouseBgF) msMouseBgF->remove(i);
        if (msMouseBgB) msMouseBgB->remove(i);
        if (msMouseAf) msMouseAf->remove(i);
        if (selection > i) --selection;
        if (mouseEntry > i) --mouseEntry;
        --anzahl;
        rend = 1;
    }
}

void SelectionBox::setDropDownButtonZ(Button* ausK) // set expand button
{
    if (ausfahren) ausfahren->release();
    ausfahren = ausK;
    rend = 1;
}

void SelectionBox::setEntryBorderZ(int i, Border* border) // set entry border
{
    if (members->z(i))
        members->z(i)->setBorderZ(border);
    else
        border->release();
    rend = 1;
}

void SelectionBox::setEntryBorderColor(int i, int f) // set entry border color
{
    if (members->z(i)) members->z(i)->setBorderColor(f);
    rend = 1;
}

void SelectionBox::setEntryBorderWidth(int i, int rbr) // set entry border width
{
    if (members->z(i)) members->z(i)->setBorderWidth(rbr);
    rend = 1;
}

void SelectionBox::setEntryBackgroundColor(
    int i, int f) // set entry background color
{
    if (members->z(i)) members->z(i)->setBackgroundColor(f);
    rend = 1;
}

void SelectionBox::setEntryBackgroundImageZ(
    int i, Image* bgB) // set entry background image
{
    if (members->z(i))
        members->z(i)->setBackgroundImageZ(bgB);
    else
        bgB->release();
    rend = 1;
}

void SelectionBox::setEntryBackgroundImage(int i, Image* bgB)
{
    if (members->z(i))
        members->z(i)->setBackgroundImage(bgB);
    else
        bgB->release();
    rend = 1;
}

void SelectionBox::setEntryAlphaFieldZ(
    int i, AlphaField* af) // set entry AlphaField
{
    if (members->z(i)) members->z(i)->setAlphaFieldZ(af);
    rend = 1;
}

void SelectionBox::setEntryAlphaFieldColor(
    int i, int afF) // set entry AlphaField color
{
    if (members->z(i)) members->z(i)->setAlphaFieldColor(afF);
    rend = 1;
}

void SelectionBox::setEntryAlphaFieldStrength(
    int i, int afSt) // set entry AlphaField strength
{
    if (members->z(i)) members->z(i)->setAlphaFieldStrength(afSt);
    rend = 1;
}

void SelectionBox::setSelBorderZ(Border* border) // set selection border
{
    if (selBorder) selBorder->release();
    selBorder = border;
    rend = 1;
}

void SelectionBox::setSelBorderColor(int f) // set selection border color
{
    if (!selBorder) selBorder = new LBorder();
    selBorder->setColor(f);
    rend = 1;
}

void SelectionBox::setSelBorderWidth(int rbr) // set selection border width
{
    if (!selBorder) selBorder = new LBorder();
    selBorder->setBorderWidth(rbr);
    rend = 1;
}

void SelectionBox::setSelBackgroundColor(
    int f) // set selection background color
{
    selBgF = f;
    rend = 1;
}

void SelectionBox::setSelBackgroundImageZ(
    Image* bgB) // set selection background image
{
    if (selBgB) selBgB->release();
    selBgB = bgB;
    rend = 1;
}

void SelectionBox::setSelBackgroundImage(Image* bgB)
{
    if (!selBgB) selBgB = new Image();
    selBgB->newImage(bgB->getWidth(), bgB->getHeight(), 0);
    selBgB->drawImage(0, 0, bgB->getWidth(), bgB->getHeight(), *bgB);
    bgB->release();
    rend = 1;
}

void SelectionBox::setSelAlphaFieldZ(AlphaField* af) // set selection AlphaField
{
    if (selAf) selAf->release();
    selAf = af;
    rend = 1;
}

void SelectionBox::setSelAlphaFieldColor(
    int afF) // set selection AlphaField color
{
    if (!selAf) selAf = new AlphaField();
    selAf->setColor(afF);
    rend = 1;
}

void SelectionBox::setSelAlphaFieldStrength(
    int afSt) // set selection AlphaField strength
{
    if (!selAf) selAf = new AlphaField();
    selAf->setStrength(afSt);
    rend = 1;
}

void SelectionBox::setMsSelBorderZ(
    int i, Border* border) // set multistyle selection border
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl)
    {
        border->release();
        return;
    }
    if (!msSelBorder) msSelBorder = new RCArray<Border>();
    msSelBorder->set(border, i);
    rend = 1;
}

void SelectionBox::setMsSelBorderColor(
    int i, int f) // set multistyle selection border color
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msSelBorder) msSelBorder = new RCArray<Border>();
    if (!msSelBorder->z(i)) msSelBorder->set(new LBorder(), i);
    msSelBorder->z(i)->setColor(f);
    rend = 1;
}

void SelectionBox::setMsSelBorderWidth(
    int i, int rbr) // set multistyle selection width
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msSelBorder) msSelBorder = new RCArray<Border>();
    if (!msSelBorder->z(i)) msSelBorder->set(new LBorder(), i);
    msSelBorder->z(i)->setBorderWidth(rbr);
    rend = 1;
}

void SelectionBox::setMsSelBackgroundColor(
    int i, int f) // set multistyle selection background color
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msSelBgF) msSelBgF = new Array<int>();
    msSelBgF->set(f, i);
    rend = 1;
}

void SelectionBox::setMsSelBackgroundImageZ(
    int i, Image* bgB) // set multistyle selection background image
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl)
    {
        bgB->release();
        return;
    }
    if (!msSelBgB) msSelBgB = new RCArray<Image>();
    msSelBgB->set(bgB, i);
    rend = 1;
}

void SelectionBox::setMsSelBackgroundImage(int i, Image* bgB)
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl)
    {
        bgB->release();
        return;
    }
    if (!msSelBgB) msSelBgB = new RCArray<Image>();
    if (!msSelBgB->z(i))
    {
        Image* z = new Image;
        z->newImage(bgB->getWidth(), bgB->getHeight(), 0);
        z->drawImage(0, 0, bgB->getWidth(), bgB->getHeight(), *bgB);
        msSelBgB->set(z, i);
    }
    else
    {
        msSelBgB->z(i)->newImage(bgB->getWidth(), bgB->getHeight(), 0);
        msSelBgB->z(i)->drawImage(
            0, 0, bgB->getWidth(), bgB->getHeight(), *bgB);
    }
    bgB->release();
    rend = 1;
}

void SelectionBox::setMsSelAlphaFieldZ(
    int i, AlphaField* af) // set multistyle selection AlphaField
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl)
    {
        af->release();
        return;
    }
    if (!msSelAf) msSelAf = new RCArray<AlphaField>();
    msSelAf->set(af, i);
    rend = 1;
}

void SelectionBox::setMsSelAlphaFieldColor(
    int i, int afF) // set multistyle selection AlphaField color
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msSelAf) msSelAf = new RCArray<AlphaField>();
    if (!msSelAf->z(i)) msSelAf->set(new AlphaField(), i);
    msSelAf->z(i)->setColor(afF);
    rend = 1;
}

void SelectionBox::setMsSelAlphaFieldStrength(
    int i, int afSt) // set multistyle selection AlphaField strength
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msSelAf) msSelAf = new RCArray<AlphaField>();
    if (!msSelAf->z(i)) msSelAf->set(new AlphaField(), i);
    msSelAf->z(i)->setStrength(afSt);
    rend = 1;
}

void SelectionBox::setMouseBorderZ(Border* border) // set mouse border
{
    if (mouseBorder) mouseBorder->release();
    mouseBorder = border;
    rend = 1;
}

void SelectionBox::setMouseBorderColor(int f) // set mouse border color
{
    if (!mouseBorder) mouseBorder = new LBorder();
    mouseBorder->setColor(f);
    rend = 1;
}

void SelectionBox::setMouseBorderWidth(int rbr) // set mouse border width
{
    if (!mouseBorder) mouseBorder = new LBorder();
    mouseBorder->setBorderWidth(rbr);
    rend = 1;
}

void SelectionBox::setMouseBackgroundColor(int f) // set mouse background color
{
    mouseBgF = f;
    rend = 1;
}

void SelectionBox::setMouseBackgroundImageZ(
    Image* bgB) // set mouse background image
{
    if (mouseBgB) mouseBgB->release();
    mouseBgB = bgB;
    rend = 1;
}

void SelectionBox::setMouseBackgroundImage(Image* bgB)
{
    if (!mouseBgB) mouseBgB = new Image();
    mouseBgB->newImage(bgB->getWidth(), bgB->getHeight(), 0);
    mouseBgB->drawImage(0, 0, bgB->getWidth(), bgB->getHeight(), *bgB);
    bgB->release();
    rend = 1;
}

void SelectionBox::setMouseAlphaFieldZ(AlphaField* af) // set mouse AlphaField
{
    if (mouseAf) mouseAf->release();
    mouseAf = af;
    rend = 1;
}

void SelectionBox::setMouseAlphaFieldColor(
    int afF) // set mouse AlphaField color
{
    if (!mouseAf) mouseAf = new AlphaField();
    mouseAf->setColor(afF);
    rend = 1;
}

void SelectionBox::setMouseAlphaFieldStrength(
    int afSt) // set mouse AlphaField strength
{
    if (!mouseAf) mouseAf = new AlphaField();
    mouseAf->setStrength(afSt);
    rend = 1;
}

void SelectionBox::setMsMouseBorderZ(
    int i, Border* border) // set multistyle mouse border
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl)
    {
        border->release();
        return;
    }
    if (!msMouseBorder) msMouseBorder = new RCArray<Border>();
    msMouseBorder->set(border, i);
    rend = 1;
}

void SelectionBox::setMsMouseBorderColor(
    int i, int f) // set multistyle mouse border color
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msMouseBorder) msMouseBorder = new RCArray<Border>();
    if (!msMouseBorder->z(i)) msMouseBorder->set(new LBorder(), i);
    msMouseBorder->z(i)->setColor(f);
    rend = 1;
}

void SelectionBox::setMsMouseBorderWidth(
    int i, int rbr) // set multistyle mouse border width
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msMouseBorder) msMouseBorder = new RCArray<Border>();
    if (!msMouseBorder->z(i)) msMouseBorder->set(new LBorder(), i);
    msMouseBorder->z(i)->setBorderWidth(rbr);
    rend = 1;
}

void SelectionBox::setMsMouseBackgroundColor(
    int i, int f) // set multistyle mouse background color
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msMouseBgF) msMouseBgF = new Array<int>();
    msMouseBgF->set(f, i);
    rend = 1;
}

void SelectionBox::setMsMouseBackgroundImageZ(
    int i, Image* bgB) // set multistyle mouse background image
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl)
    {
        bgB->release();
        return;
    }
    if (!msMouseBgB) msMouseBgB = new RCArray<Image>();
    msMouseBgB->set(bgB, i);
    rend = 1;
}

void SelectionBox::setMsMouseBackgroundImage(int i, Image* bgB)
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl)
    {
        bgB->release();
        return;
    }
    if (!msMouseBgB) msMouseBgB = new RCArray<Image>();
    if (!msMouseBgB->z(i))
    {
        Image* z = new Image;
        z->newImage(bgB->getWidth(), bgB->getHeight(), 0);
        z->drawImage(0, 0, bgB->getWidth(), bgB->getHeight(), *bgB);
        msMouseBgB->set(z, i);
    }
    else
    {
        msMouseBgB->z(i)->newImage(bgB->getWidth(), bgB->getHeight(), 0);
        msMouseBgB->z(i)->drawImage(
            0, 0, bgB->getWidth(), bgB->getHeight(), *bgB);
    }
    bgB->release();
    rend = 1;
}

void SelectionBox::setMsMouseAlphaFieldZ(
    int i, AlphaField* af) // set multistyle mouse AlphaField
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl)
    {
        af->release();
        return;
    }
    if (!msMouseAf) msMouseAf = new RCArray<AlphaField>();
    msMouseAf->set(af, i);
    rend = 1;
}

void SelectionBox::setMsMouseAlphaFieldColor(
    int i, int afF) // set multistyle mouse AlphaField color
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msMouseAf) msMouseAf = new RCArray<AlphaField>();
    if (!msMouseAf->z(i)) msMouseAf->set(new AlphaField(), i);
    msMouseAf->z(i)->setColor(afF);
    rend = 1;
}

void SelectionBox::setMsMouseAlphaFieldStrength(
    int i, int afSt) // set multistyle mouse AlphaField strength
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msMouseAf) msMouseAf = new RCArray<AlphaField>();
    if (!msMouseAf->z(i)) msMouseAf->set(new AlphaField(), i);
    msMouseAf->z(i)->setStrength(afSt);
    rend = 1;
}

void SelectionBox::setSelection(int i) // select entry
{
    if (i < anzahl && i != selection)
    {
        selection = i;
        if (eAk) eAk(eAkP, this, 0, selection);
        rend = 1;
    }
}

void SelectionBox::expand() // expand list
{
    ausgeklappt = 1;
}

void SelectionBox::collapse() // collapse list
{
    ausgeklappt = 0;
}

void SelectionBox::scrollToEntry(int i) // scroll list
{
    if (hasStyle(Style::VScroll) && vertikalScrollBar && i < anzahl)
    {
        int scrollPos = 0;
        if (hasStyle(Style::MultiStyled))
        {
            for (int j = 0; j < i; ++j)
                scrollPos += members->z(j) ? members->z(j)->getHeight() : 0;
        }
        else
            scrollPos += i * entryHeight;
        vertikalScrollBar->scroll(scrollPos);
        rend = 1;
    }
}

void SelectionBox::setMaxAuskappHeight(
    int maxHeight) // height of the list when expanded
{
    ausklapMaxHeight = maxHeight;
}

void SelectionBox::setEntryHeight(int height) // sets the height of the entries
{
    entryHeight = height;
}

void SelectionBox::addMsStyle(int i, __int64 abStyle) // add multistyle style
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msStyle) msStyle = new Array<__int64>();
    msStyle->set(msStyle->get(i) | abStyle, i);
    rend = 1;
}

void SelectionBox::setMsStyle(
    int i, __int64 abStyle, bool add) // set multistyle style
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msStyle) msStyle = new Array<__int64>();
    if (add)
        msStyle->set(msStyle->get(i) | abStyle, i);
    else
        msStyle->set(msStyle->get(i) & ~abStyle, i);
    rend = 1;
}

void SelectionBox::setMsStyle(int i, __int64 abStyle)
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msStyle) msStyle = new Array<__int64>();
    msStyle->set(abStyle, i);
    rend = 1;
}

void SelectionBox::removeMsStyle(
    int i, __int64 abStyle) // remove multistyle style
{
    if (hasStyleNot(Style::MultiStyled) || i >= anzahl) return;
    if (!msStyle) msStyle = new Array<__int64>();
    msStyle->set(msStyle->get(i) & ~abStyle, i);
    rend = 1;
}

bool SelectionBox::tick(double tickVal) // tick
{
    if (ausgeklappt && ausfahren && !ausfahren->zText()->isEqual("/\\"))
    {
        ausfahren->setText("/\\");
        rend = 1;
    }
    else if (!ausgeklappt && ausfahren && !ausfahren->zText()->isEqual("\\/"))
    {
        ausfahren->setText("\\/");
        rend = 1;
    }
    if (hasStyleNot(Style::Visible) || hasStyleNot(Style::Allowed))
        ausgeklappt = 0;
    rend |= ausfahren->tick(tickVal);
    this->tickval += tickVal * 300;
    int val = (int)this->tickval;
    if (val < 1) return DrawableBackground::tick(tickVal);
    this->tickval -= val;
    int maxHeight = border ? border->getRWidth() : 0;
    if (hasStyleNot(Style::MultiStyled))
        maxHeight += anzahl * entryHeight;
    else
        for (int i = 0; i < anzahl; ++i)
            maxHeight += members->z(i) ? members->z(i)->getHeight() : 0;
    if (maxHeight > ausklapMaxHeight)
    {
        if (hasStyle(Style::VScroll) && vertikalScrollBar)
        {
            scrollAnzeigen = 1;
            vertikalScrollBar->update(maxHeight, ausklapMaxHeight);
        }
        maxHeight = ausklapMaxHeight;
    }
    else
        scrollAnzeigen = 0;
    if (ausgeklappt)
    {
        if (ausklappHeight < maxHeight)
        {
            ausklappHeight += val;
            if (ausklappHeight > maxHeight) ausklappHeight = maxHeight;
            rend = 1;
        }
    }
    else
    {
        if (ausklappHeight > 0)
        {
            ausklappHeight -= val;
            if (ausklappHeight < 0) ausklappHeight = 0;
            rend = 1;
        }
    }
    for (int i = 0; i < anzahl; ++i)
    {
        if (i != selection)
            rend |= members->z(i)->tick(tickVal);
        else
            members->z(i)->tick(tickVal);
    }
    return DrawableBackground::tick(tickVal);
}

void SelectionBox::doKeyboardEvent(KeyboardEvent& te) // Keyboard
{
    if (te.processed || hasStyleNot(Style::Focus)
        || hasStyleNot(Style::Allowed))
        return;
    if (te.id == TE_Release)
    {
        switch (te.virtualKey)
        {
        case T_Oben:
            if (selection > 0)
                --selection;
            else
                selection = anzahl - 1;
            if (eAk) eAk(eAkP, this, 0, selection);
            scrollToEntry(selection);
            rend = 1;
            break;
        case T_Unten:
            if (selection < anzahl - 1)
                ++selection;
            else
                selection = 0;
            if (eAk) eAk(eAkP, this, 0, selection);
            scrollToEntry(selection);
            rend = 1;
            break;
        }
    }
    if (te.processed && nTak) te.processed = nTak(ntakParam, this, te);
}

void SelectionBox::render(Image& zRObj) // renders into zRObj
{
    if (hasStyle(Style::Visible))
    {
        rwLock.lockRead();
        int br = gr.x;
        int hi = gr.y + ausklappHeight;
        if ((ausklappHeight
                && !zRObj.setDrawOptionsErzwingen(pos.x, pos.y, br, hi))
            || (!ausklappHeight && !zRObj.setDrawOptions(pos.x, pos.y, br, hi)))
        {
            rwLock.unlockRead();
            return;
        }
        int rbr = 0;
        if (hasStyle(Style::Border) && border) // Draw border
        {
            border->setSize(br, hi);
            border->render(zRObj);
            rbr = border->getRWidth();
        }
        if ((ausklappHeight
                && !zRObj.setDrawOptionsErzwingen(
                    rbr, rbr, br - rbr * 2, hi - rbr * 2))
            || (!ausklappHeight
                && !zRObj.setDrawOptions(rbr, rbr, br - rbr * 2, hi - rbr * 2)))
        {
            zRObj.releaseDrawOptions();
            rwLock.unlockRead();
            return;
        }
        if (hasStyle(Style::Background))
        {
            if (hasStyle(Style::BAlpha))
                zRObj.alphaRegion(0, 0, br, hi, backgroundColor);
            else
                zRObj.fillRegion(0, 0, br, hi, backgroundColor);
            if (hasStyle(Style::BImage) && backgroundImage)
            {
                if (hasStyle(Style::BAlpha))
                    zRObj.alphaImage(0, 0, br, hi, *backgroundImage);
                else
                    zRObj.drawImage(0, 0, br, hi, *backgroundImage);
            }
        }
        if (hasStyle(Style::Buffered) && backgroundFeld)
        {
            backgroundFeld->setSize(br - rbr * 2, hi - rbr * 2);
            backgroundFeld->render(zRObj);
        }
        if (ausfahren) // Draw expand button
        {
            ausfahren->setSize(gr.y - rbr * 2, gr.y - rbr * 2);
            ausfahren->setPosition(gr.x - rbr - ausfahren->getWidth(), rbr);
            ausfahren->render(zRObj);
        }
        if (members) // Draw selected text field
        {
            if (selection < 0)
            {
                selection = 0;
                if (eAk) eAk(eAkP, this, 0, selection);
            }
            if (selection >= anzahl)
            {
                selection = anzahl - 1;
                if (eAk) eAk(eAkP, this, 0, selection);
            }
            TextField* tf = selection >= 0 ? members->z(selection) : 0;
            if (tf)
            {
                AlphaField* tmpBuffer = 0;
                bool tmpB = 0;
                int tmpHColor = 0;
                bool tmpH = 0;
                Image* tmpHImage = 0;
                bool tmpHB = 0;
                bool tmpHAlpha = 0;
                Border* tmpBorder = 0;
                bool tmpR = 0;
                if (hasStyleNot(Style::MultiStyled) || !msStyle)
                {
                    if (hasStyle(Style::SelectionBuffer))
                    {
                        tmpBuffer = tf->getAlphaField();
                        tf->setAlphaFieldZ(
                            dynamic_cast<AlphaField*>(selAf->getThis()));
                        tmpB = tf->hasStyle(TextField::Style::Buffered);
                        tf->setStyle(TextField::Style::Buffered,
                            hasStyle(Style::SelectionBuffer));
                    }
                    if (hasStyle(Style::SelectionBackground))
                    {
                        tmpH = tf->hasStyle(TextField::Style::Background);
                        tmpHColor = tf->getBackgroundColor();
                        tf->setBackgroundColor(selBgF);
                        tf->setStyle(TextField::Style::Background,
                            hasStyle(Style::Background));
                        if (hasStyle(Style::SelectionHImage))
                        {
                            tmpHImage = tf->getBackgroundImage();
                            tf->setBackgroundImageZ(
                                dynamic_cast<Image*>(selBgB->getThis()));
                            tmpHB = tf->hasStyle(TextField::Style::BImage);
                            tf->setStyle(TextField::Style::BImage,
                                hasStyle(Style::BImage));
                        }
                        if (hasStyle(Style::SelectionHAlpha))
                        {
                            tmpHAlpha = tf->hasStyle(TextField::Style::BAlpha);
                            tf->setStyle(TextField::Style::BAlpha,
                                hasStyle(Style::SelectionHAlpha));
                        }
                    }
                    if (hasStyle(Style::SelectionBorder))
                    {
                        tmpBorder = tf->getBorder();
                        tf->setBorderZ(
                            dynamic_cast<Border*>(selBorder->getThis()));
                        tmpR = tf->hasStyle(TextField::Style::Border);
                        tf->setStyle(TextField::Style::Border,
                            hasStyle(Style::SelectionBorder));
                    }
                }
                else
                {
                    if (hasMsStyle(selection, Style::SelectionBuffer)
                        && msSelAf)
                    {
                        tmpBuffer = tf->getAlphaField();
                        tf->setAlphaFieldZ(msSelAf->get(selection));
                        tmpB = tf->hasStyle(TextField::Style::Buffered);
                        tf->setStyle(TextField::Style::Buffered,
                            hasMsStyle(selection, Style::SelectionBuffer));
                    }
                    if (hasMsStyle(selection, Style::SelectionBackground))
                    {
                        tmpH = tf->hasStyle(Style::Background);
                        tf->setStyle(TextField::Style::Background,
                            hasMsStyle(selection, Style::SelectionBackground));
                        if (msSelBgF && msSelBgF->has(selection))
                        {
                            tmpHColor = tf->getBackgroundColor();
                            tf->setBackgroundColor(msSelBgF->get(selection));
                        }
                        if (hasMsStyle(selection, Style::SelectionHImage)
                            && msSelBgB)
                        {
                            tmpHImage = tf->getBackgroundImage();
                            tf->setBackgroundImageZ(msSelBgB->get(selection));
                            tmpHB = tf->hasStyle(TextField::Style::BImage);
                            tf->setStyle(TextField::Style::BImage,
                                hasMsStyle(selection, Style::BImage));
                        }
                        if (hasMsStyle(selection, Style::SelectionHAlpha))
                        {
                            tmpHAlpha = tf->hasStyle(TextField::Style::BAlpha);
                            tf->setStyle(TextField::Style::BAlpha,
                                hasMsStyle(selection, Style::SelectionHAlpha));
                        }
                    }
                    if (hasMsStyle(selection, Style::SelectionBorder)
                        && msSelBorder)
                    {
                        tmpBorder = tf->getBorder();
                        tf->setBorderZ(msSelBorder->get(selection));
                        tmpR = tf->hasStyle(TextField::Style::Border);
                        tf->setStyle(TextField::Style::Border,
                            hasMsStyle(selection, Style::SelectionBorder));
                    }
                }
                int tmpHi = tf->getHeight();
                tf->setPosition(0, 0);
                tf->setSize(
                    gr.x - rbr * 2 - (ausfahren ? ausfahren->getWidth() : 0),
                    gr.y - rbr * 2);
                tf->render(zRObj);
                tf->setSize(tf->getWidth(), tmpHi);
                if (hasStyleNot(Style::MultiStyled) || !msStyle)
                {
                    if (hasStyle(Style::SelectionBuffer))
                    {
                        tf->setAlphaFieldZ(tmpBuffer);
                        tf->setStyle(TextField::Style::Buffered, tmpB);
                    }
                    if (hasStyle(Style::SelectionBackground))
                    {
                        tf->setBackgroundColor(tmpHColor);
                        tf->setStyle(TextField::Style::Background, tmpH);
                        if (hasStyle(Style::SelectionHImage))
                        {
                            tf->setBackgroundImageZ(tmpHImage);
                            tf->setStyle(TextField::Style::BImage, tmpHB);
                        }
                        if (hasStyle(Style::SelectionHAlpha))
                            tf->setStyle(TextField::Style::BAlpha, tmpHAlpha);
                    }
                    if (hasStyle(Style::SelectionBorder))
                    {
                        tf->setBorderZ(tmpBorder);
                        tf->setStyle(TextField::Style::Border, tmpR);
                    }
                }
                else
                {
                    if (hasMsStyle(selection, Style::SelectionBuffer)
                        && msSelAf)
                    {
                        tf->setAlphaFieldZ(tmpBuffer);
                        tf->setStyle(TextField::Style::Buffered, tmpB);
                    }
                    if (hasMsStyle(selection, Style::SelectionBackground))
                    {
                        tf->setStyle(TextField::Style::Background, tmpH);
                        if (msSelBgF && msSelBgF->has(selection))
                            tf->setBackgroundColor(tmpHColor);
                        if (hasMsStyle(selection, Style::SelectionHImage)
                            && msSelBgB)
                        {
                            tf->setBackgroundImageZ(tmpHImage);
                            tf->setStyle(TextField::Style::BImage, tmpHB);
                        }
                        if (hasMsStyle(selection, Style::SelectionHAlpha))
                            tf->setStyle(TextField::Style::BAlpha, tmpHAlpha);
                    }
                    if (hasMsStyle(selection, Style::SelectionBorder)
                        && msSelBorder)
                    {
                        tf->setBorderZ(tmpBorder);
                        tf->setStyle(TextField::Style::Border, tmpR);
                    }
                }
            }
        }
        bool vsb
            = hasStyle(Style::VScroll) && vertikalScrollBar; // Draw scroll bar
        if (selection >= anzahl)
        {
            selection = 0;
            if (eAk) eAk(eAkP, this, 0, selection);
        }
        if (members)
        {
            if (vsb && ausklappHeight)
            {
                br -= 15;
                vertikalScrollBar->getScrollData()->anzeige
                    = ausklappHeight - rbr;
                vertikalScrollBar->render(
                    br - rbr, gr.y, 15, ausklappHeight - rbr, zRObj);
            }
            if ((ausklappHeight
                    && !zRObj.setDrawOptionsErzwingen(
                        0, gr.y, br - rbr, hi - rbr - gr.y))
                || (!ausklappHeight
                    && !zRObj.setDrawOptions(
                        0, gr.y, br - rbr, hi - rbr - gr.y)))
            {
                zRObj.releaseDrawOptions();
                zRObj.releaseDrawOptions();
                rwLock.unlockRead();
                return;
            }
            int maxHeight = 0;
            int dy = 0;
            if (vsb) dy -= vertikalScrollBar->getScroll();
            int mdy = hi - rbr;
            anzahl = members->getEntryCount();
            for (int i = 0; i < anzahl; ++i)
            {
                TextField* tf = members->z(i);
                if (dy >= mdy && !vsb) break;
                tf->setPosition(0, dy);
                tf->setSize(br - rbr * 2, tf->getHeight());
                maxHeight += tf->getHeight();
                bool selected = selection == i;
                AlphaField* tmpBuffer = 0;
                bool tmpB = 0;
                int tmpHColor = 0;
                bool tmpH = 0;
                Image* tmpHImage = 0;
                bool tmpHB = 0;
                bool tmpHAlpha = 0;
                Border* tmpBorder = 0;
                bool tmpR = 0;
                if (selected)
                {
                    if (hasStyleNot(Style::MultiStyled) || !msStyle)
                    {
                        if (hasStyle(Style::SelectionBuffer))
                        {
                            tmpBuffer = tf->getAlphaField();
                            tf->setAlphaFieldZ(
                                dynamic_cast<AlphaField*>(selAf->getThis()));
                            tmpB = tf->hasStyle(TextField::Style::Buffered);
                            tf->setStyle(TextField::Style::Buffered,
                                hasStyle(Style::SelectionBuffer));
                        }
                        if (hasStyle(Style::SelectionBackground))
                        {
                            tmpH = tf->hasStyle(TextField::Style::Background);
                            tmpHColor = tf->getBackgroundColor();
                            tf->setBackgroundColor(selBgF);
                            tf->setStyle(TextField::Style::Background,
                                hasStyle(Style::Background));
                            if (hasStyle(Style::SelectionHImage))
                            {
                                tmpHImage = tf->getBackgroundImage();
                                tf->setBackgroundImageZ(
                                    dynamic_cast<Image*>(selBgB->getThis()));
                                tmpHB = tf->hasStyle(TextField::Style::BImage);
                                tf->setStyle(TextField::Style::BImage,
                                    hasStyle(Style::BImage));
                            }
                            if (hasStyle(Style::SelectionHAlpha))
                            {
                                tmpHAlpha
                                    = tf->hasStyle(TextField::Style::BAlpha);
                                tf->setStyle(TextField::Style::BAlpha,
                                    hasStyle(Style::SelectionHAlpha));
                            }
                        }
                        if (hasStyle(Style::SelectionBorder))
                        {
                            tmpBorder = tf->getBorder();
                            tf->setBorderZ(
                                dynamic_cast<Border*>(selBorder->getThis()));
                            tmpR = tf->hasStyle(TextField::Style::Border);
                            tf->setStyle(TextField::Style::Border,
                                hasStyle(Style::SelectionBorder));
                        }
                    }
                    else
                    {
                        if (hasMsStyle(i, Style::SelectionBuffer) && msSelAf)
                        {
                            tmpBuffer = tf->getAlphaField();
                            tf->setAlphaFieldZ(msSelAf->get(i));
                            tmpB = tf->hasStyle(TextField::Style::Buffered);
                            tf->setStyle(TextField::Style::Buffered,
                                hasMsStyle(i, Style::SelectionBuffer));
                        }
                        if (hasMsStyle(i, Style::SelectionBackground))
                        {
                            tmpH = tf->hasStyle(Style::Background);
                            tf->setStyle(TextField::Style::Background,
                                hasMsStyle(i, Style::SelectionBackground));
                            if (msSelBgF && msSelBgF->has(i))
                            {
                                tmpHColor = tf->getBackgroundColor();
                                tf->setBackgroundColor(msSelBgF->get(i));
                            }
                            if (hasMsStyle(i, Style::SelectionHImage)
                                && msSelBgB)
                            {
                                tmpHImage = tf->getBackgroundImage();
                                tf->setBackgroundImageZ(msSelBgB->get(i));
                                tmpHB = tf->hasStyle(TextField::Style::BImage);
                                tf->setStyle(TextField::Style::BImage,
                                    hasMsStyle(i, Style::BImage));
                            }
                            if (hasMsStyle(i, Style::SelectionHAlpha))
                            {
                                tmpHAlpha
                                    = tf->hasStyle(TextField::Style::BAlpha);
                                tf->setStyle(TextField::Style::BAlpha,
                                    hasMsStyle(i, Style::SelectionHAlpha));
                            }
                        }
                        if (hasMsStyle(i, Style::SelectionBorder)
                            && msSelBorder)
                        {
                            tmpBorder = tf->getBorder();
                            tf->setBorderZ(msSelBorder->get(i));
                            tmpR = tf->hasStyle(TextField::Style::Border);
                            tf->setStyle(TextField::Style::Border,
                                hasMsStyle(i, Style::SelectionBorder));
                        }
                    }
                }
                else if (mouseEntry == i)
                {
                    if (hasStyleNot(Style::MultiStyled) || !msStyle)
                    {
                        if (hasStyle(Style::MouseBuffer))
                        {
                            tmpBuffer = tf->getAlphaField();
                            tf->setAlphaFieldZ(
                                dynamic_cast<AlphaField*>(mouseAf->getThis()));
                            tmpB = tf->hasStyle(TextField::Style::Buffered);
                            tf->setStyle(TextField::Style::Buffered,
                                hasStyle(Style::MouseBuffer));
                        }
                        if (hasStyle(Style::MouseBackground))
                        {
                            tmpH = tf->hasStyle(TextField::Style::Background);
                            tmpHColor = tf->getBackgroundColor();
                            tf->setBackgroundColor(mouseBgF);
                            tf->setStyle(TextField::Style::Background,
                                hasStyle(Style::Background));
                            if (hasStyle(Style::MouseHImage))
                            {
                                tmpHImage = tf->getBackgroundImage();
                                tf->setBackgroundImageZ(
                                    dynamic_cast<Image*>(mouseBgB->getThis()));
                                tmpHB = tf->hasStyle(TextField::Style::BImage);
                                tf->setStyle(TextField::Style::BImage,
                                    hasStyle(Style::BImage));
                            }
                            if (hasStyle(Style::MouseHAlpha))
                            {
                                tmpHAlpha
                                    = tf->hasStyle(TextField::Style::BAlpha);
                                tf->setStyle(TextField::Style::BAlpha,
                                    hasStyle(Style::MouseHAlpha));
                            }
                        }
                        if (hasStyle(Style::MouseBorder))
                        {
                            tmpBorder = tf->getBorder();
                            tf->setBorderZ(
                                dynamic_cast<Border*>(mouseBorder->getThis()));
                            tmpR = tf->hasStyle(TextField::Style::Border);
                            tf->setStyle(TextField::Style::Border,
                                hasStyle(Style::MouseBorder));
                        }
                    }
                    else
                    {
                        if (hasMsStyle(i, Style::MouseBuffer) && msSelAf)
                        {
                            tmpBuffer = tf->getAlphaField();
                            tf->setAlphaFieldZ(msMouseAf->get(i));
                            tmpB = tf->hasStyle(TextField::Style::Buffered);
                            tf->setStyle(TextField::Style::Buffered,
                                hasMsStyle(i, Style::MouseBuffer));
                        }
                        if (hasMsStyle(i, Style::MouseBackground))
                        {
                            tmpH = tf->hasStyle(Style::Background);
                            tf->setStyle(TextField::Style::Background,
                                hasMsStyle(i, Style::MouseBackground));
                            if (msMouseBgF && msMouseBgF->has(i))
                            {
                                tmpHColor = tf->getBackgroundColor();
                                tf->setBackgroundColor(msMouseBgF->get(i));
                            }
                            if (hasMsStyle(i, Style::MouseHImage) && msMouseBgB)
                            {
                                tmpHImage = tf->getBackgroundImage();
                                tf->setBackgroundImageZ(msMouseBgB->get(i));
                                tmpHB = tf->hasStyle(TextField::Style::BImage);
                                tf->setStyle(TextField::Style::BImage,
                                    hasMsStyle(i, Style::BImage));
                            }
                            if (hasMsStyle(i, Style::MouseHAlpha))
                            {
                                tmpHAlpha
                                    = tf->hasStyle(TextField::Style::BAlpha);
                                tf->setStyle(TextField::Style::BAlpha,
                                    hasMsStyle(i, Style::MouseHAlpha));
                            }
                        }
                        if (hasMsStyle(i, Style::MouseBorder) && msMouseBorder)
                        {
                            tmpBorder = tf->getBorder();
                            tf->setBorderZ(msMouseBorder->get(i));
                            tmpR = tf->hasStyle(TextField::Style::Border);
                            tf->setStyle(TextField::Style::Border,
                                hasMsStyle(i, Style::MouseBorder));
                        }
                    }
                }
                tf->render(zRObj);
                if (selected)
                {
                    if (hasStyleNot(Style::MultiStyled) || !msStyle)
                    {
                        if (hasStyle(Style::SelectionBuffer))
                        {
                            tf->setAlphaFieldZ(tmpBuffer);
                            tf->setStyle(TextField::Style::Buffered, tmpB);
                        }
                        if (hasStyle(Style::SelectionBackground))
                        {
                            tf->setBackgroundColor(tmpHColor);
                            tf->setStyle(TextField::Style::Background, tmpH);
                            if (hasStyle(Style::SelectionHImage))
                            {
                                tf->setBackgroundImageZ(tmpHImage);
                                tf->setStyle(TextField::Style::BImage, tmpHB);
                            }
                            if (hasStyle(Style::SelectionHAlpha))
                                tf->setStyle(
                                    TextField::Style::BAlpha, tmpHAlpha);
                        }
                        if (hasStyle(Style::SelectionBorder))
                        {
                            tf->setBorderZ(tmpBorder);
                            tf->setStyle(TextField::Style::Border, tmpR);
                        }
                    }
                    else
                    {
                        if (hasMsStyle(i, Style::SelectionBuffer) && msSelAf)
                        {
                            tf->setAlphaFieldZ(tmpBuffer);
                            tf->setStyle(TextField::Style::Buffered, tmpB);
                        }
                        if (hasMsStyle(i, Style::SelectionBackground))
                        {
                            tf->setStyle(TextField::Style::Background, tmpH);
                            if (msSelBgF && msSelBgF->has(i))
                                tf->setBackgroundColor(tmpHColor);
                            if (hasMsStyle(i, Style::SelectionHImage)
                                && msSelBgB)
                            {
                                tf->setBackgroundImageZ(tmpHImage);
                                tf->setStyle(TextField::Style::BImage, tmpHB);
                            }
                            if (hasMsStyle(i, Style::SelectionHAlpha))
                                tf->setStyle(
                                    TextField::Style::BAlpha, tmpHAlpha);
                        }
                        if (hasMsStyle(i, Style::SelectionBorder)
                            && msSelBorder)
                        {
                            tf->setBorderZ(tmpBorder);
                            tf->setStyle(TextField::Style::Border, tmpR);
                        }
                    }
                }
                else if (mouseEntry == i)
                {
                    if (hasStyleNot(Style::MultiStyled) || !msStyle)
                    {
                        if (hasStyle(Style::MouseBuffer))
                        {
                            tf->setAlphaFieldZ(tmpBuffer);
                            tf->setStyle(TextField::Style::Buffered, tmpB);
                        }
                        if (hasStyle(Style::MouseBackground))
                        {
                            tf->setBackgroundColor(tmpHColor);
                            tf->setStyle(TextField::Style::Background, tmpH);
                            if (hasStyle(Style::MouseHImage))
                            {
                                tf->setBackgroundImageZ(tmpHImage);
                                tf->setStyle(TextField::Style::BImage, tmpHB);
                            }
                            if (hasStyle(Style::MouseHAlpha))
                                tf->setStyle(
                                    TextField::Style::BAlpha, tmpHAlpha);
                        }
                        if (hasStyle(Style::MouseBorder))
                        {
                            tf->setBorderZ(tmpBorder);
                            tf->setStyle(TextField::Style::Border, tmpR);
                        }
                    }
                    else
                    {
                        if (hasMsStyle(i, Style::MouseBuffer) && msSelAf)
                        {
                            tf->setAlphaFieldZ(tmpBuffer);
                            tf->setStyle(TextField::Style::Buffered, tmpB);
                        }
                        if (hasMsStyle(i, Style::MouseBackground))
                        {
                            tf->setStyle(TextField::Style::Background, tmpH);
                            if (msSelBgF && msSelBgF->has(i))
                                tf->setBackgroundColor(tmpHColor);
                            if (hasMsStyle(i, Style::MouseHImage) && msSelBgB)
                            {
                                tf->setBackgroundImageZ(tmpHImage);
                                tf->setStyle(TextField::Style::BImage, tmpHB);
                            }
                            if (hasMsStyle(i, Style::MouseHAlpha))
                                tf->setStyle(
                                    TextField::Style::BAlpha, tmpHAlpha);
                        }
                        if (hasMsStyle(i, Style::MouseBorder) && msSelBorder)
                        {
                            tf->setBorderZ(tmpBorder);
                            tf->setStyle(TextField::Style::Border, tmpR);
                        }
                    }
                }
                dy += tf->getHeight();
            }
            if (vertikalScrollBar)
                vertikalScrollBar->getScrollData()->max = maxHeight;
            zRObj.releaseDrawOptions();
        }
        zRObj.releaseDrawOptions();
        zRObj.releaseDrawOptions();
        rwLock.unlockRead();
    }
}

// constant
int SelectionBox::getEntryPos(
    const char* txt) const // returns the entry position
{
    for (int i = 0; i < anzahl; ++i)
        if (members->z(i) && members->z(i)->zText()->isEqual(txt)) return i;
    return -1;
}

int SelectionBox::getEntryPos(Text* txt) const
{
    for (int i = 0; i < anzahl; ++i)
    {
        if (members->z(i) && members->z(i)->zText()->isEqual(txt->getText()))
        {
            txt->release();
            return i;
        }
    }
    txt->release();
    return -1;
}

Text* SelectionBox::getEntryText(int i) const // returns the entry text
{
    if (i >= anzahl) return 0;
    return members->z(i) ? members->z(i)->getText() : 0;
}

Text* SelectionBox::zEntryText(int i) const
{
    if (i >= anzahl) return 0;
    return members->z(i) ? members->z(i)->zText() : 0;
}

TextField* SelectionBox::getEntry(int i) const // returns the entry
{
    if (i >= anzahl) return 0;
    return members->get(i);
}

TextField* SelectionBox::zEntry(int i) const
{
    if (i >= anzahl) return 0;
    return members->z(i);
}

int SelectionBox::getSelection()
    const // returns the position of the selected entry
{
    return selection;
}

int SelectionBox::getEntryCount() const // returns the number of entries
{
    return anzahl;
}

bool SelectionBox::isExpanded() const // checks if the list is expanded
{
    return ausgeklappt;
}

int SelectionBox::getMaxHeight() const // returns the maximum list height
{
    if (!hasStyle(Style::MaxHeight)) return 0;
    return ausklapMaxHeight;
}

int SelectionBox::getEntryHeight() const // returns the height of the entries
{
    return entryHeight;
}

Button*
SelectionBox::getDropDownButton() const // returns the expand/collapse button
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return ausfahren ? dynamic_cast<Button*>(ausfahren->getThis()) : 0;
}

Button* SelectionBox::zDropDownButton() const
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return ausfahren;
}

Border* SelectionBox::getEntryBorder(int i) const // returns the entry border
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!members->z(i)) return 0;
    return members->z(i)->getBorder();
}

Border* SelectionBox::zEntryBorder(int i) const
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!members->z(i)) return 0;
    return members->z(i)->zBorder();
}

int SelectionBox::getEntryBorderColor(
    int i) const // returns the entry border color
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!members->z(i)) return 0;
    return members->z(i)->getBorderColor();
}

int SelectionBox::getEntryBorderWidth(
    int i) const // returns the entry border width
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!members->z(i)) return 0;
    return members->z(i)->getBorderWidth();
}

AlphaField* SelectionBox::getEntryAlphaField(
    int i) const // returns the entry AlphaField
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!members->z(i)) return 0;
    return members->z(i)->getAlphaField();
}

AlphaField* SelectionBox::zEntryAlphaField(int i) const
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!members->z(i)) return 0;
    return members->z(i)->zAlphaField();
}

int SelectionBox::getEntryAlphaFieldColor(
    int i) const // returns the entry AlphaField color
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!members->z(i)) return 0;
    return members->z(i)->getAlphaFieldColor();
}

int SelectionBox::getEntryAlphaFieldStrength(
    int i) const // returns the entry AlphaField strength
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!members->z(i)) return 0;
    return members->z(i)->getAlphaFieldStrength();
}

int SelectionBox::getEntryBackgroundColor(
    int i) const // returns the entry background color
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!members->z(i)) return 0;
    return members->z(i)->getBackgroundColor();
}

Image* SelectionBox::getEntryBackgroundImage(
    int i) const // returns the entry background image
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!members->z(i)) return 0;
    return members->z(i)->getBackgroundImage();
}

Image* SelectionBox::zEntryBackgroundImage(int i) const
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!members->z(i)) return 0;
    return members->z(i)->zBackgroundImage();
}

Border* SelectionBox::getSelBorder() const // returns the selection border
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return selBorder ? dynamic_cast<Border*>(selBorder->getThis()) : 0;
}

Border* SelectionBox::zSelBorder() const
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return selBorder;
}

int SelectionBox::getSelBorderColor()
    const // returns the selection border color
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return selBorder ? selBorder->getColor() : 0;
}

int SelectionBox::getSelBorderWidth()
    const // returns the selection border width
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return selBorder ? selBorder->getRWidth() : 0;
}

AlphaField*
SelectionBox::getSelAlphaField() const // returns the selection AlphaField
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return selAf ? dynamic_cast<AlphaField*>(selAf->getThis()) : 0;
}

AlphaField* SelectionBox::zSelAlphaField() const
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return selAf;
}

int SelectionBox::getSelAlphaFieldColor()
    const // returns the selection AlphaField color
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return selAf ? selAf->getColor() : 0;
}

int SelectionBox::getSelAlphaFieldStrength()
    const // returns the selection AlphaField strength
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return selAf ? selAf->getStrength() : 0;
}

int SelectionBox::getSelBackgroundColor()
    const // returns the selection background color
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return selBgF;
}

Image* SelectionBox::getSelBackgroundImage()
    const // returns the selection background image
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return selBgB ? dynamic_cast<Image*>(selBgB->getThis()) : 0;
}

Image* SelectionBox::zSelBackgroundImage() const
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return selBgB;
}

Border* SelectionBox::getMsSelBorder(
    int i) const // returns the multistyle selection border
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msSelBorder) return 0;
    return msSelBorder->z(i)
             ? dynamic_cast<Border*>(msSelBorder->z(i)->getThis())
             : 0;
}

Border* SelectionBox::zMsSelBorder(int i) const
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msSelBorder) return 0;
    return msSelBorder->z(i);
}

int SelectionBox::getMsSelBorderColor(
    int i) const // returns the multistyle selection border color
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msSelBorder) return 0;
    return msSelBorder->z(i) ? msSelBorder->z(i)->getColor() : 0;
}

int SelectionBox::getMsSelBorderWidth(
    int i) const // returns the multistyle selection border width
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msSelBorder) return 0;
    return msSelBorder->z(i) ? msSelBorder->z(i)->getRWidth() : 0;
}

AlphaField* SelectionBox::getMsSelAlphaField(
    int i) const // returns the multistyle selection AlphaField
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msSelAf) return 0;
    return msSelAf->z(i) ? dynamic_cast<AlphaField*>(msSelAf->z(i)->getThis())
                         : 0;
}

AlphaField* SelectionBox::zMsSelAlphaField(int i) const
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msSelAf) return 0;
    return msSelAf->z(i);
}

int SelectionBox::getMsSelAlphaFieldColor(
    int i) const // returns the multistyle selection AlphaField color
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msSelAf) return 0;
    return msSelAf->z(i) ? msSelAf->z(i)->getColor() : 0;
}

int SelectionBox::getMsSelAlphaFieldStrength(
    int i) const // returns the multistyle selection AlphaField strength
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msSelAf) return 0;
    return msSelAf->z(i) ? msSelAf->z(i)->getStrength() : 0;
}

int SelectionBox::getMsSelBackgroundColor(
    int i) const // returns the multistyle selection background color
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msSelBgF || !msSelBgF->has(i)) return 0;
    return msSelBgF->get(i);
}

Image* SelectionBox::getMsSelBackgroundImage(
    int i) const // returns the multistyle selection background image
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msSelBgB) return 0;
    return msSelBgB->get(i);
}

Image* SelectionBox::zMsSelBackgroundImage(int i) const
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msSelBgB) return 0;
    return msSelBgB->z(i);
}

Border* SelectionBox::getMouseBorder() const // returns the mouse border
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return mouseBorder ? dynamic_cast<Border*>(mouseBorder->getThis()) : 0;
}

Border* SelectionBox::zMouseBorder() const
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return mouseBorder;
}

int SelectionBox::getMouseBorderColor() const // returns the mouse border color
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return mouseBorder ? mouseBorder->getColor() : 0;
}

int SelectionBox::getMouseBorderWidth() const // returns the mouse border width
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return mouseBorder ? mouseBorder->getRWidth() : 0;
}

AlphaField*
SelectionBox::getMouseAlphaField() const // returns the mouse AlphaField
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return mouseAf ? dynamic_cast<AlphaField*>(mouseAf->getThis()) : 0;
}

AlphaField* SelectionBox::zMouseAlphaField() const
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return mouseAf;
}

int SelectionBox::getMouseAlphaFieldColor()
    const // returns the mouse AlphaField color
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return mouseAf ? mouseAf->getColor() : 0;
}

int SelectionBox::getMouseAlphaFieldStrength()
    const // returns the mouse AlphaField strength
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return mouseAf ? mouseAf->getStrength() : 0;
}

int SelectionBox::getMouseBackgroundColor()
    const // returns the mouse background color
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return mouseBgF;
}

Image* SelectionBox::getMouseBackgroundImage()
    const // returns the mouse background image
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return mouseBgB ? dynamic_cast<Image*>(mouseBgB->getThis()) : 0;
}

Image* SelectionBox::zMouseBackgroundImage() const
{
    if (hasStyle(Style::MultiStyled)) return 0;
    return mouseBgB;
}

Border* SelectionBox::getMsMouseBorder(
    int i) const // returns the multistyle mouse border
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msMouseBorder) return 0;
    return msMouseBorder->get(i);
}

Border* SelectionBox::zMsMouseBorder(int i) const
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msMouseBorder) return 0;
    return msMouseBorder->z(i);
}

int SelectionBox::getMsMouseBorderColor(
    int i) const // returns the multistyle mouse border color
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msMouseBorder) return 0;
    return msMouseBorder->z(i) ? msMouseBorder->z(i)->getColor() : 0;
}

int SelectionBox::getMsMouseBorderWidth(
    int i) const // returns the multistyle mouse border width
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msMouseBorder) return 0;
    return msMouseBorder->z(i) ? msMouseBorder->z(i)->getRWidth() : 0;
}

AlphaField* SelectionBox::getMsMouseAlphaField(
    int i) const // returns the multistyle mouse AlphaField
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msMouseAf) return 0;
    return msMouseAf->get(i);
}

AlphaField* SelectionBox::zMsMouseAlphaField(int i) const
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msMouseAf) return 0;
    return msMouseAf->z(i);
}

int SelectionBox::getMsMouseAlphaFieldColor(
    int i) const // returns the multistyle mouse AlphaField color
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msMouseAf) return 0;
    return msMouseAf->z(i) ? msMouseAf->z(i)->getColor() : 0;
}

int SelectionBox::getMsMouseAlphaFieldStrength(
    int i) const // returns the multistyle mouse AlphaField strength
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msMouseAf) return 0;
    return msMouseAf->z(i) ? msMouseAf->z(i)->getStrength() : 0;
}

int SelectionBox::getMsMouseBackgroundColor(
    int i) const // returns the multistyle mouse background color
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msMouseBgF || !msMouseBgF->has(i)) return 0;
    return msMouseBgF->get(i);
}

Image* SelectionBox::getMsMouseBackgroundImage(
    int i) const // returns the multistyle mouse background image
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msMouseBgB) return 0;
    return msMouseBgB->get(i);
}

Image* SelectionBox::zMsMouseBackgroundImage(int i) const
{
    if (!hasStyle(Style::MultiStyled)) return 0;
    if (!msMouseBgB) return 0;
    return msMouseBgB->z(i);
}

// Checks if a point is inside this object
//  x: the x coordinate of the point
//  y: the y coordinate of the point
//  return: 1 if the point is inside, 0 otherwise
bool SelectionBox::isPointInside(int x, int y) const
{
    return x >= pos.x && x < pos.x + gr.x && y >= pos.y
        && y < pos.y + gr.y + ausklappHeight;
}

bool SelectionBox::hasMsStyle(
    int i, __int64 abStyle) const // checks if multistyle style is present
{
    if ((style | Style::MultiStyled) != style || !msStyle || !msStyle->has(i))
        return 0;
    return (msStyle->get(i) | abStyle) == msStyle->get(i);
}

bool SelectionBox::hasMsStyleNot(
    int i, __int64 abStyle) const // checks if multistyle style is not present
{
    if ((style | Style::MultiStyled) != style || !msStyle || !msStyle->has(i))
        return 1;
    return (msStyle->get(i) | abStyle) != msStyle->get(i);
}

Drawable* SelectionBox::duplicate() const // Creates a copy of the drawing
{
    SelectionBox* obj = new SelectionBox();
    obj->setPosition(pos);
    obj->setSize(gr);
    obj->setMouseEventParameter(makParam);
    obj->setKeyboardEventParameter(takParam);
    obj->setMouseEvent(mak);
    obj->setKeyboardEvent(tak);
    if (toolTip) obj->setToolTipZ((ToolTip*)toolTip->duplicate());
    obj->setStyle(style);
    if (textRd)
        obj->setTextRendererZ(dynamic_cast<TextRenderer*>(textRd->getThis()));
    if (border) obj->setBorderZ((Border*)border->duplicate());
    if (ausfahren) obj->setDropDownButtonZ((Button*)ausfahren->duplicate());
    obj->setBackgroundColor(backgroundColor);
    if (backgroundImage)
        obj->setBackgroundImage(
            dynamic_cast<Image*>(backgroundImage->getThis()));
    if (backgroundFeld)
        obj->setAlphaFieldZ((AlphaField*)backgroundFeld->duplicate());
    if (selBorder) obj->setSelBorderZ((Border*)selBorder->duplicate());
    obj->setSelBackgroundColor(selBgF);
    if (selBgB)
        obj->setSelBackgroundImage(dynamic_cast<Image*>(selBgB->getThis()));
    if (selAf) obj->setSelAlphaFieldZ((AlphaField*)selAf->duplicate());
    if (mouseBorder) obj->setMouseBorderZ((Border*)mouseBorder->duplicate());
    obj->setMouseBackgroundColor(mouseBgF);
    if (mouseBgB)
        obj->setMouseBackgroundImage(dynamic_cast<Image*>(mouseBgB->getThis()));
    if (mouseAf) obj->setMouseAlphaFieldZ((AlphaField*)mouseAf->duplicate());
    obj->setMaxAuskappHeight(ausklapMaxHeight);
    obj->setEntryHeight(entryHeight);
    for (int i = 0; i < anzahl; ++i)
    {
        if (members->z(i))
        {
            obj->addEntry("a");
            obj->setEntryZ(i, (TextField*)members->z(i)->duplicate());
            if (msStyle && msStyle->has(i)) obj->setMsStyle(i, msStyle->get(i));
            if (msSelBorder && msSelBorder->z(i))
                obj->setMsSelBorderZ(
                    i, (Border*)msSelBorder->z(i)->duplicate());
            if (msSelBgF && msSelBgF->has(i))
                obj->setMsSelBackgroundColor(i, msSelBgF->get(i));
            if (msSelBgB && msSelBgB->z(i))
                obj->setMsSelBackgroundImage(i, msSelBgB->get(i));
            if (msSelAf && msSelAf->z(i))
                obj->setMsSelAlphaFieldZ(
                    i, (AlphaField*)msSelAf->z(i)->duplicate());
            if (msMouseBorder && msMouseBorder->z(i))
                obj->setMsMouseBorderZ(
                    i, (Border*)msMouseBorder->z(i)->duplicate());
            if (msMouseBgF && msMouseBgF->has(i))
                obj->setMsMouseBackgroundColor(i, msMouseBgF->get(i));
            if (msMouseBgB && msMouseBgB->z(i))
                obj->setMsMouseBackgroundImage(i, msMouseBgB->get(i));
            if (msMouseAf && msMouseAf->z(i))
                obj->setMsMouseAlphaFieldZ(
                    i, (AlphaField*)msMouseAf->z(i)->duplicate());
        }
    }
    obj->setAlphaFieldColor(selection);
    return obj;
}