#include "GridNode.h"

#include "MeshPrimitives.h"

GridNode::GridNode(const DiscretePoint& location)
 : MaterialNode(location)
{

}

void GridNode::setNumX(unsigned numX)
{
    if (mNumberX != numX)
    {
        mNumberX = numX;
        mDataDirty = true;
    }
}

void GridNode::setNumY(unsigned numY)
{
    if (mNumberY != numY)
    {
        mNumberY = numY;
        mDataDirty = true;
    }
}

void GridNode::setWidth(unsigned width)
{
    if (mWidth != width)
    {
        mTransformIsDirty = true;
        mWidth = width;
    }
}

void GridNode::setHeight(unsigned height)
{
    if (mHeight != height)
    {
        mTransformIsDirty = true;
        mHeight = height;
    }
}

void GridNode::setData(const std::vector<Color>& colors)
{
    if (mData != colors)
    {
        mData = colors;
        mDataDirty = true;
    }
}

SceneItem* GridNode::getSceneItem(std::size_t idx) const
{
    if (idx == 0)
    {
        return mBackgroundModel.get();
    }
    else
    {
        return mOutlineModel.get();
    }
}

unsigned GridNode::getNumSceneItems() const
{
    return 2;
}

void GridNode::update(FontsManager* fontsManager)
{
    if (!mBackgroundModel || mDataDirty)
    {
        auto mesh = MeshPrimitives::buildExplodedGridAsTriMesh(mNumberX, mNumberY);

        if (!mBackgroundModel)
        {
            mBackgroundModel = std::make_unique<SceneModel>(std::move(mesh));
            mBackgroundModel->setName(mName + "_BackgroundModel");
        }
        else
        {
            mBackgroundModel.get()->updateMesh(std::move(mesh));
        }
    }

    if (mOutlineModel || mDataDirty)
    {
        auto mesh = MeshPrimitives::buildExplodedGridAsLineMesh(mNumberX, mNumberY);

        if (!mOutlineModel)
        {
            mOutlineModel = std::make_unique<SceneModel>(std::move(mesh));
            mOutlineModel->setName(mName + "_OulineModel");
        }
        else
        {
            mOutlineModel.get()->updateMesh(std::move(mesh));
        }
    }

    if (mDataDirty)
    {
        auto difference = mNumberX*mNumberY - mData.size();
        mData.resize(mNumberX*mNumberY, {});

        auto node_data = std::vector<std::vector<double> >(4*mNumberX*mNumberY);
        for (unsigned idx=0; idx< node_data.size(); idx++)
        {
            if (idx < mData.size())
            {
                node_data[idx] = mData[idx].getAsVectorDouble();
            }

        }
        //mBackgroundModel->getMesh()->addVectorAttribute("Color", mData);

    }

    if (mTransformIsDirty)
    {
        auto size = mHeight > mWidth ? mWidth : mHeight;

        mBackgroundModel->updateTransform({mLocation, static_cast<double>(size), static_cast<double>(size)});
        mOutlineModel->updateTransform({mLocation, static_cast<double>(size), static_cast<double>(size)});
        mTransformIsDirty = false;
    }

    if (mMaterialIsDirty)
    {
        mOutlineModel->updateUniformColor(mStrokeColor);
        mMaterialIsDirty = false;
    }

    mDataDirty = false;
}

