#include "TextBox.h"

#include "TextNode.h"
#include "GeometryNode.h"
#include "KeyboardEvent.h"
#include "TransformNode.h"

#include "ThemeManager.h"
#include "PaintEvent.h"

#include <sstream>

TextBox::TextBox()
    : Widget(),
      mContent()
{
    mBackground = Theme::Sys::Color::Background;
    mPadding = {20, 0, 20, 0};
}

std::unique_ptr<TextBox> TextBox::Create()
{
    return std::make_unique<TextBox>();
}

void TextBox::setContent(const std::string& text)
{
    mContent = text;
    mContentDirty = true;
}

std::string TextBox::getContent() const
{
    return mContent;
}

void TextBox::appendContent(const std::string& text)
{
    mContent += text;
    mContentDirty = true;
}

bool TextBox::onMyKeyboardEvent(const KeyboardEvent* event)
{
    if(!event || !mVisible) return false;

    if(event->isFunctionKey())
    {
        if (event->getFunction() == Keyboard::Function::ENTER)
        {
            appendContent("\n");
        }
        else if(event->getFunction() == Keyboard::Function::BACKSPACE)
        {
            mContent = mContent.substr(0, mContent.size()-1);
            mContentDirty = true;
        }
    }
    else
    {
        const auto keyString = event->getKeyString();
        if (keyString.length() < 2)
        {
            appendContent(keyString);
        }
        else
        {
            appendContent("?");
        }

    }
    return true;
}

bool TextBox::isDirty() const
{
    return Widget::isDirty() || mContentDirty;
}

void TextBox::doPaint(const PaintEvent* event)
{
    updateBackground(event);
    updateLabel(event);
}

void TextBox::updateLabel(const PaintEvent* event)
{
    if (!mTextNode)
    {
        mTextNode = TextNode::Create(mContent, Transform());
        mTextNode->setWidth(mSize.mWidth);
        mTextNode->setHeight(mSize.mHeight);
        mRootNode->addChild(mTextNode.get());
    }

    if (mMaterialDirty)
    {
        mTextNode->setFillColor(event->getThemesManager()->getColor(mBackground));
    }

    if (mTransformDirty)
    {
        mTextNode->setWidth(mSize.mWidth);
        mTextNode->setHeight(mSize.mHeight);
    }

    if (mContentDirty)
    {
        mTextNode->setContent(mContent);
        mContentDirty = false;
    }
}
