#include "Button.h"

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

#include "MouseEvent.h"

#include <iostream>

Button::Button()
    : Widget(),
      mLabel(),
      mCachedColor(255, 255, 255),
      mClickedColor(Color(180, 180, 180)),
      mClickFunc()
{
    mName = "Button";
}

Button::~Button()
{

}

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

void Button::setOnClickFunction(clickFunc func)
{
    mClickFunc = func;
}

void Button::setLabel(const std::string& text)
{
    if (text != mLabel)
    {
        mLabel = text;
        mContentDirty = true;
    }
}

void Button::onMyMouseEvent(const MouseEvent* event)
{
    if(event->GetAction() == MouseEvent::Action::Pressed)
    {
        mCachedColor = mBackgroundColor;
        setBackgroundColor(mClickedColor);
        if(mClickFunc)
        {
            mClickFunc(this);
        }
    }
    else if(event->GetAction() == MouseEvent::Action::Released)
    {
        setBackgroundColor(mCachedColor);
    }
}

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

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

void Button::updateLabel(const PaintEvent* event)
{
    unsigned fontOffset = unsigned(mLabel.size()) * 4;
    auto middle = DiscretePoint(mLocation.GetX() + mSize.mWidth/2 - fontOffset, mLocation.GetY() + mSize.mHeight/2 + 4);

    if (!mTextNode)
    {
        mTextNode = TextNode::Create(mLabel, middle);
        mTextNode->setName(mName + "_TextNode");
        mTextNode->setContent(mLabel);
        mTextNode->setWidth(mSize.mWidth);
        mTextNode->setHeight(mSize.mHeight);
        mRootNode->addChild(mTextNode.get());
    }

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

    if (mMaterialDirty)
    {
        mTextNode->setFillColor(mBackgroundColor);
    }

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

    if (mVisibilityDirty)
    {
        mTextNode->setIsVisible(mVisible);
    }
}
