#include "ChatOptions.h"

#include <DateiSystem.h>

#include "Globals.h"
#include "Initialisierung.h"

ChatOptions::ChatOptions()
    : Fenster()
{
    LTDBDatei iconsDat;
    iconsDat.setDatei(new Text("data/bilder/gui_icons.ltdb"));
    iconsDat.leseDaten(0);
    
    setStyle(
        Fenster::Style::Erlaubt | Fenster::Style::Rahmen
        | Fenster::Style::BodyHAlpha | Fenster::Style::Titel
        | Fenster::Style::TitelHAlpha | Fenster::Style::Closable
        | Fenster::Style::ClosingHAlpha | Fenster::Style::ClosingKlickBuffer
        | Fenster::Style::TitelHintergrund | Fenster::Style::BodyHintergrund
        | Fenster::Style::ClosingHintergrund | Fenster::Style::MEIgnoreInside
        | Fenster::Style::Beweglich | Style::ClosingHBild
        | Style::ClosingBuffer);
    removeStyle(Fenster::Style::Sichtbar);
    setTitel("Chat options");
    setClosingMe([this](void* p, void* o, Framework::MausEreignis me) {
        if (me.id == Framework::ME_RLinks)
        {
            removeStyle(Fenster::Style::Sichtbar);
        }
        return 1;
    });
    setSize(262, 367);
    setPosition(5, uiFactory.initParam.bildschirm->getBackBufferSize().y - 680);
    setMausEreignis(Framework::_ret1ME);
    setTastaturEreignis(Framework::_ret1TE);
    setRBreite(1);
    setRFarbe(0xFF52525E);
    setKBgFarbe(0xA0000000);
    setTBgFarbe(0xA0000000);
    setSBgFarbe(0xA0000000);
    setTSchriftZ(
        dynamic_cast<Schrift*>(uiFactory.initParam.schrift->getThis()));
    zTTextFeld()->setSize(0, 20);
    zTTextFeld()->addStyle(TextFeld::Style::Center);
    setSAfStrength(10);
    setSAfFarbe(0x5F9C0A0A);
    setSBgBildZ(iconsDat.laden(0, new Text("close.png")));
    setSKAfFarbe(0xFF9C0A0A);
    setSKAfStrength(10);

    infoChannel = initKontrollKnopf(5,
        5,
        250,
        20,
        Framework::KontrollKnopf::Style::Normal
            & ~Framework::KontrollKnopf::Style::Rahmen,
        "Show info messages");
    infoChannel->setNMausEreignis([this](void* p, void* o, MausEreignis me) {
        if (me.id == ME_RLinks)
        {
            char msg[13];
            msg[0]
                = infoChannel->hatStyle(KontrollKnopf::Style::Selected) ? 1 : 2;
            msg[1] = 11;
            memcpy(msg + 2, "system:INFO", 11);
            World::INSTANCE->zClient()->chatAPIRequest(msg, 13);
        }
        return 1;
    });
    addMember(infoChannel);
    warningChannel = initKontrollKnopf(5,
        30,
        250,
        20,
        Framework::KontrollKnopf::Style::Normal
            & ~Framework::KontrollKnopf::Style::Rahmen,
        "Show warning messages");
    warningChannel->setNMausEreignis([this](void* p, void* o, MausEreignis me) {
        if (me.id == ME_RLinks)
        {
            char msg[16];
            msg[0] = warningChannel->hatStyle(KontrollKnopf::Style::Selected)
                       ? 1
                       : 2;
            msg[1] = 14;
            memcpy(msg + 2, "system:WARNING", 14);
            World::INSTANCE->zClient()->chatAPIRequest(msg, 16);
        }
        return 1;
    });
    addMember(warningChannel);
    errorChannel = initKontrollKnopf(5,
        55,
        250,
        20,
        Framework::KontrollKnopf::Style::Normal
            & ~Framework::KontrollKnopf::Style::Rahmen,
        "Show error messages");
    errorChannel->setNMausEreignis([this](void* p, void* o, MausEreignis me) {
        if (me.id == ME_RLinks)
        {
            char msg[14];
            msg[0] = errorChannel->hatStyle(KontrollKnopf::Style::Selected) ? 1
                                                                            : 2;
            msg[1] = 12;
            memcpy(msg + 2, "system:ERROR", 12);
            World::INSTANCE->zClient()->chatAPIRequest(msg, 14);
        }
        return 1;
    });
    addMember(errorChannel);
    TextFeld* blackListLabel = initTextFeld(5,
        90,
        250,
        20,
        Framework::TextFeld::Style::Text | Framework::TextFeld::Style::VCenter,
        "Ignored players:");
    addMember(blackListLabel);
    
    plus = iconsDat.laden(0, new Text("plus.png"));
    trash = iconsDat.laden(0, new Text("trash.png"));

    playerName = initTextFeld(
        5, 115, 225, 20, Framework::TextFeld::Style::TextFeld, "");
    playerName->setTastaturEreignis(
        [this](void* o, void* p, TastaturEreignis te) {
            if (te.id == TE_Release && te.virtualKey == T_Enter)
            {
                if (playerName->zText()->getLength())
                {
                    addIgnoredPlayer(playerName->zText()->getText(), 1);
                    playerName->setText("");
                }
            }
            return 1;
        });
    addMember(playerName);
    addButton = initKnopf(235,
        115,
        20,
        20,
        Framework::Knopf::Style::HBild | Framework::Knopf::Style::HAlpha
            | Framework::Knopf::Style::Hintergrund,
        "");
    addButton->setAlphaFeldFarbe(0x5F337AB7);
    addButton->setToolTipText("Add player to list of ignored players",
        uiFactory.initParam.bildschirm,
        uiFactory.initParam.schrift);
    addButton->setHintergrundBildZ(dynamic_cast<Bild*>(plus->getThis()));
    addButton->setMausEreignis([this](void* o, void* p, MausEreignis me) {
        if (me.id == ME_RLinks)
        {
            if (playerName->zText()->getLength())
            {
                addIgnoredPlayer(playerName->zText()->getText(), 1);
                playerName->setText("");
            }
        }
        return 1;
    });
    addMember(addButton);
    blackList = initObjTabelle(5,
        140,
        250,
        200,
        Framework::ObjTabelle::Style::normal
            | Framework::ObjTabelle::Style::VScroll,
        {
            {"Player", 212, 212, 212},
            {"Remove", 20,  20,  20 }
    },
        0);
    addMember(blackList);
}

ChatOptions::~ChatOptions()
{
    if (plus) plus->release();
    if (trash) trash->release();
}

void ChatOptions::init(char* data)
{
    infoChannel->removeStyle(KontrollKnopf::Style::Selected);
    warningChannel->removeStyle(KontrollKnopf::Style::Selected);
    errorChannel->removeStyle(KontrollKnopf::Style::Selected);
    int len = *(int*)data;
    data += 4;
    for (int i = 0; i < len; i++)
    {
        char len = *(data++);
        data += len;
        if (len == 11)
        {
            infoChannel->addStyle(KontrollKnopf::Style::Selected);
        }
        if (len == 12)
        {
            errorChannel->addStyle(KontrollKnopf::Style::Selected);
        }
        if (len == 14)
        {
            warningChannel->addStyle(KontrollKnopf::Style::Selected);
        }
    }
    uiFactory.initParam.bildschirm->postAction([this]() {
        while (blackList->getZeilenAnzahl())
        {
            blackList->removeZeile(0);
        }
    });
    len = *(int*)data;
    data += 4;
    for (int i = 0; i < len; i++)
    {
        char len = *(data++);
        char* name = new char[len + 1];
        memcpy(name, data, len);
        name[len] = 0;
        data += len;
        addIgnoredPlayer(name, 0);
        delete[] name;
    }
}

void ChatOptions::addIgnoredPlayer(Framework::Text playerName, bool msg)
{
    if (blackList->getZeilenNummer(playerName) >= 0) return;
    if (msg)
    {
        char* msg = new char[2 + playerName.getLength()];
        msg[0] = 3;
        msg[1] = (char)playerName.getLength();
        memcpy(msg + 2, playerName, playerName.getLength());
        World::INSTANCE->zClient()->chatAPIRequest(
            msg, 2 + playerName.getLength());
        delete[] msg;
    }
    uiFactory.initParam.bildschirm->postAction([this, playerName]() {
        if (blackList->getZeilenNummer(playerName) >= 0) return;
        blackList->addZeile(playerName);
        blackList->setZeichnungZ("Player",
            playerName,
            initTextFeld(0,
                0,
                0,
                0,
                TextFeld::Style::Text | TextFeld::Style::VCenter,
                playerName.getText()));
        Knopf* removeButton = initKnopf(0,
            0,
            0,
            0,
            Framework::Knopf::Style::HBild | Framework::Knopf::Style::HAlpha
                | Framework::Knopf::Style::Hintergrund,
            "");
        removeButton->removeStyle(Knopf::Style::Rahmen);
        removeButton->setAlphaFeldFarbe(0x5F337AB7);
        removeButton->setToolTipText(
            "Remove player from list of ignored players",
            uiFactory.initParam.bildschirm,
            uiFactory.initParam.schrift);
        removeButton->setHintergrundBildZ(
            dynamic_cast<Bild*>(trash->getThis()));
        removeButton->setMausEreignis(
            [this, playerName](void* o, void* p, MausEreignis me) {
                if (me.id == ME_RLinks)
                {
                    uiFactory.initParam.bildschirm->postAction(
                        [this, playerName]() {
                            char* msg = new char[2 + playerName.getLength()];
                            msg[0] = 4;
                            msg[1] = (char)playerName.getLength();
                            memcpy(msg + 2, playerName, playerName.getLength());
                            World::INSTANCE->zClient()->chatAPIRequest(
                                msg, 2 + playerName.getLength());
                            delete[] msg;
                            blackList->removeZeile(playerName);
                        });
                }
                return 1;
            });
        blackList->setZeichnungZ("Remove", playerName, removeButton);
    });
}