#include "canvas.h"
#include <QPainter>
#include <QVariant>
#include "logger.h"
#include "appcontext.h"
#include "abstractwidget.h"

Canvas::Canvas(const xmlNodePtr canvasNodePtr, QWidget *parent)
    : QWidget{parent}
    , m_backgroundColor(Qt::black)
{
    load(canvasNodePtr);
}

Canvas::~Canvas()
{

}

const QColor &Canvas::backgroundColor() const
{
    return m_backgroundColor;
}

void Canvas::setBackgroundColor(const QColor &newBackgroundColor)
{
    m_backgroundColor = newBackgroundColor;
}

bool Canvas::load(const xmlNodePtr canvasNodePtr)
{
    if(!canvasNodePtr) {
        LOG_INFO("null canvas node");
        return false;
    }
    if(xmlStrcmp(canvasNodePtr->name, BAD_CAST "canvas") == 0) {
        // 导入前清空画布
        // m_pCanvas->clear();

        PluginManager &pluginMgr = AppContext::instance().pluginManager();
        auto customWidgets = pluginMgr.customWidgets();

        QString propertyName;
        QString propertyValue;
        xmlChar *value;

        int canvasWidth = 1280;
        int canvasHeight = 720;

        value = xmlGetProp(canvasNodePtr, BAD_CAST "backgroundColor");
        if(value) {
            QString canvasColor = QString("%1").arg((char *)value);
            m_backgroundColor = QColor(canvasColor);
            xmlFree(value);
        }

        value = xmlGetProp(canvasNodePtr, BAD_CAST "width");
        if (value) {
            canvasWidth = QString((char *)value).toInt();
            xmlFree(value);
        }

        value = xmlGetProp(canvasNodePtr, BAD_CAST "height");
        if (value) {
            canvasHeight = QString((char *)value).toInt();
            xmlFree(value);
        }

        resize(canvasWidth, canvasHeight);

        xmlNodePtr child = canvasNodePtr->children;
        while(child)    // 遍历控件节点
        {
            QList<QPair<QString, QVariant> > propertys;
            QStringList parameters;
            if (child->type == XML_ELEMENT_NODE)
            {
                int x = 0;
                int y = 0;
                int w = 0;
                int h = 0;
                QString widgetName = (char *)child->name;

                
                xmlNodePtr node = child->children;
                LOG_DEBUG("widget: {}", (char *)child->name);
                while(node)
                {
                    if(xmlStrcmp(node->name, BAD_CAST "property") == 0)
                    {
                        // 遍历 property 下的每个子节点
                        xmlNodePtr propChild = node->children;
                        LOG_DEBUG("\tproperty:");
                        while(propChild)
                        {
                            if(propChild->type == XML_ELEMENT_NODE)
                            {
                                xmlChar* content = xmlNodeGetContent(propChild);
                                if(content) {
                                    propertyName = QString("%1").arg((char*)propChild->name);
                                    propertyValue = QString("%1").arg((char*)content);
                                    LOG_DEBUG("\t\t{}:{}", propertyName.toUtf8().data(), propertyValue.toUtf8().data());

                                    if(propertyName == "x")
                                    {
                                        x = propertyValue.toInt();
                                    }
                                    else if(propertyName == "y")
                                    {
                                        y = propertyValue.toInt();
                                    }
                                    else if(propertyName == "width")
                                    {
                                        w = propertyValue.toInt();
                                    }
                                    else if(propertyName == "height")
                                    {
                                        h = propertyValue.toInt();
                                    }
                                    else
                                    {
                                        QVariant propertyVariantValue = QVariant(propertyValue);
                                        if (propertyValue.startsWith("#") && propertyValue.length() == 9)
                                        {
                                            propertyVariantValue = QColor(propertyValue);
                                        }
                                        propertys.append(qMakePair(propertyName, propertyVariantValue));
                                    }

                                    xmlFree(content);
                                }
                            }
                            propChild = propChild->next;
                        }
                    }
                    else if(xmlStrcmp(node->name, BAD_CAST "parameter") == 0)
                    {
                        xmlNodePtr paramChild = node->children;
                        LOG_DEBUG("\tparameter:");
                        while(paramChild)
                        {
                            if(paramChild->type == XML_ELEMENT_NODE) {
                                xmlChar* content = xmlNodeGetContent(paramChild);
                                if(content) {
                                    parameters << (char *)content;
                                    LOG_DEBUG("\t\t{}", (char *)content);
                                    xmlFree(content);
                                }
                            }
                            paramChild = paramChild->next;
                        }
                    }
                    node = node->next;
                }

                //根据不同的控件类型实例化控件
                int countWidget = customWidgets.count();
                int countProperty = propertys.count();

                for(int i = 0; i < countWidget; ++i)
                {
                    QString className = customWidgets.at(i)->name();
                    if(widgetName == className)
                    {
                        //生成对应的控件
                        QWidget *widget = customWidgets.at(i)->createWidget(this);
                        // 设置绑定参数
                        AbstractWidget *pAbstractWidget = static_cast<AbstractWidget *>(widget);
                        if(pAbstractWidget) {
                            QMetaObject::invokeMethod(pAbstractWidget,
                                                      "setParameters",
                                                      Qt::AutoConnection,
                                                      Q_ARG(QStringList, parameters));

                            m_widgetList << widget;
                            m_parameterList << parameters;
                        }


                        //逐个设置自定义控件的属性
                        for(int j = 0; j < countProperty; j++)
                        {
                            QPair<QString, QVariant> property = propertys.at(j);
                            QString name = property.first;
                            QVariant value = property.second;
                            widget->setProperty(name.toUtf8().data(), value);
                        }

                        //设置控件坐标及宽高
                        widget->setGeometry(x, y, w, h);
                        break;
                    }
                }

            }
            child = child->next;
        }

        return true;
    }
    else {
        LOG_ERROR("err node name: {}", (char *)canvasNodePtr->name);
        return false;
    }
}

QList<QWidget *> Canvas::widgetList() const
{
    return m_widgetList;
}

QList<QStringList> Canvas::parameterList() const
{
    return m_parameterList;
}

void Canvas::paintEvent(QPaintEvent *event)
{
    // 绘制背景颜色
    QPainter painter(this);
    painter.fillRect(rect(), m_backgroundColor);
}