#include "TextBox.h"

#include "TextElement.h"
#include "VisualLayer.h"
#include "GeometryElement.h"
#include "KeyboardEvent.h"

#include <sstream>

TextBox::TextBox()
    : Widget(),
      mContent(),
      mCaps(false)
{
    mBackgroundColor = Color::Create(250, 250, 250);
    mPadding = {10, 0, 10, 0};
}

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

void TextBox::SetContent(const std::string& text)
{
    mContent = text;
}

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

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

bool TextBox::OnMyKeyboardEvent(const KeyboardEvent* event)
{
    if(!event) return false;

    const auto keyString = event->GetKeyString();
    if (keyString == "KEY_RETURN")
    {
        AppendContent("\n");
    }
    else if (keyString == "KEY_BACK")
    {
        mContent = mContent.substr(0, mContent.size()-1);
    }
    else if (keyString == "KEY_SPACE")
    {
        AppendContent(" ");
    }
    else if (keyString == "KEY_CAPS")
    {
        mCaps = !mCaps;
    }
    else
    {
        if (mCaps && !keyString.empty())
        {
            const char c = std::toupper(keyString[0]);
            AppendContent(std::string(&c));
        }
        else
        {
            AppendContent(keyString);
        }
    }
    return true;
}

void TextBox::OnPaintEvent(const PaintEvent* event)
{
    mMyLayers.clear();
    AddBackground(event);

    double offset = 0;
    if(!mContent.empty())
    {
        std::stringstream stream(mContent);
        std::string segment;
        std::vector<std::string> seglist;
        while(std::getline(stream, segment, '\n'))
        {
           seglist.push_back(segment);
        }
        for(const auto& line : seglist)
        {
            auto loc = DiscretePoint(mLocation.GetX() + mPadding.mLeft,
                    mLocation.GetY() + mPadding.mTop + unsigned(offset));
            auto textLayer = VisualLayer::Create();
            auto textElement = TextElement::Create(line, loc);
            textElement->SetFillColor(Color::Create(*mBackgroundColor));
            textLayer->SetText(std::move(textElement));
            mMyLayers.push_back(std::move(textLayer));
            offset += 20;
        }
    }
    CopyMyLayers();
}
