#include "RectBase.hpp"

#include "elements/Transformable.hpp"

TSE::RectBase::RectBase()
{
    meshCach = Mesh::GetQuadMesh();
}

TSE::Mesh *TSE::RectBase::GetMesh()
{
    return &meshCach;
}

void TSE::RectBase::SetCustomUVs(const std::vector<Vector2> &uvs)
{
    meshCach.uvs = uvs;
}

void TSE::RectBase::OnParentChanged(RectBase *parent)
{
    if(anchors != Rect(0.5f,0.5f, 0.5f, 0.5f))
        RecalculateMesh(parent);
}

bool IsTransformableRect(TSE::Transformable* trans)
{
    if(trans == nullptr || !trans->HasBehaviourScript(RECT_BASE)) return false;
    return true;
}

void TSE::RectBase::RecalculateMesh(RectBase *parent)
{
    // Determin parent size, or fallback to 1x1
        Vector2 psize (1,1);
        if(parent != nullptr)
            psize = parent->tmpSize;
        Vector2 phsize = psize * 0.5f;
        

        Vector2 pposoffset (0,0);
        if(parent != nullptr)
        {
            pposoffset = ((parent->pivit * 2) - Vector2::one) * phsize;
        }

        Vector2 mappedAnchor = (Vector2::Midpoint(anchors.p1,anchors.p2) * 2 - Vector2::one) * phsize;
        pposoffset = pposoffset + mappedAnchor;

        Vector2 strechscaler = anchors.p2 - anchors.p1;

        tmpSize = psize * strechscaler + size;

        Vector2 hs = tmpSize * 0.5f;

        Vector2 mappedPivit = pivit * 2 - Vector2::one;
        Vector2 pivitOffset = hs * mappedPivit;

        meshCach.vertecies.clear();
        meshCach.vertecies.push_back(Vector2(-hs.x,  -hs.y) + pivitOffset);
        meshCach.vertecies.push_back(Vector2( hs.x,  -hs.y) + pivitOffset);
        meshCach.vertecies.push_back(Vector2( hs.x,   hs.y) + pivitOffset);
        meshCach.vertecies.push_back(Vector2(-hs.x,   hs.y) + pivitOffset);


        baseObject->position = pposoffset;

        lastSize = size;
        lastAnchors = anchors;
        lastPivit = pivit;

        // Notify children of change
        auto children = baseObject->GetChildren();
        for(auto child : children)
        {
            if(IsTransformableRect(child))
            {
                ((RectBase*)child->GetBehaviourScript(RECT_BASE))->OnParentChanged(this);
            }
        }
}

void TSE::RectBase::OnUpdate()
{
    if(lastSize != size || lastAnchors != anchors || pivit != lastPivit){
        //local change
        RectBase* parent = nullptr;
        if(baseObject->GetParent() != nullptr)
            parent = (RectBase*)baseObject->GetParent()->GetBehaviourScript(RECT_BASE);
        RecalculateMesh(parent);
    }
}
