#include "QQuickDetailsViewLayoutBuilder.h"
#include "QQuickDetailsViewMananger.h"

QQuickDetailsViewRowBuilder::QQuickDetailsViewRowBuilder(IDetailsViewRow* inRow, QQuickItem* inRootItem)
	: mRow(inRow)
    , mRootItem(inRootItem)
{
    setHeightProxy(nullptr);
}

QPair<QQuickItem*, QQuickItem*> QQuickDetailsViewRowBuilder::makeNameValueSlot()
{
	QQmlEngine* engine = qmlEngine(mRootItem);
	QQmlContext* context = qmlContext(mRootItem);
	QQmlContext* newContext = new QQmlContext(context, mRootItem);
	QQmlComponent rootComp(newContext->engine());
	rootComp.setData(R"(
        import QtQuick;
        import QtQuick.Controls;
        import Qt5Compat.GraphicalEffects
        import ColorPalette
        Rectangle{
            id: topLevelRect  
            anchors.fill: parent
            color: hoverHandler.hovered ? ColorPalette.theme.rowBackgroundHover : ColorPalette.theme.rowBackground
            border.color: ColorPalette.theme.rowBorder
            border.width: 0.5       
            Behavior on color {
                ColorAnimation { duration: 100 }
            }
            HoverHandler { id: hoverHandler }
            Image {
                id: indicator
                visible: detailsDelegate.isTreeNode && detailsDelegate.hasChildren
                x: padding + (detailsDelegate.depth * detailsDelegate.indent)
                anchors.verticalCenter: parent.verticalCenter
                mipmap: true 
                source: detailsDelegate.expanded 
                    ? "qrc:/resources/Icon/expand.png" 
                    : "qrc:/resources/Icon/unexpand.png"

                width: 12
                height: 12
                ColorOverlay {
                    anchors.fill: parent
                    source: parent
                    color: ColorPalette.theme.rowIndicator  
                    opacity: 1.0 
                }
            }
            Item{
                id: nameEditorContent
                height: parent.height
                anchors.left: parent.left 
                anchors.leftMargin: padding + (detailsDelegate.isTreeNode ? (detailsDelegate.depth + 1) * detailsDelegate.indent : 0)
                anchors.right: splitter.left
                anchors.verticalCenter: parent.verticalCenter
            }
            Item{
                id: valueEditorContent
                implicitHeight: 25
                anchors.left: splitter.left 
                anchors.leftMargin: 10
                anchors.rightMargin: 10
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
            }
            Rectangle{
                id: splitter
                width: 3
                height: parent.height
                color : ColorPalette.theme.rowBackground
                x: detailsView.SpliterPencent * detailsView.width - 1  
    
                Rectangle{
                    id: visibleSplitter
                    width: 1
                    height: parent.height
                    color: ColorPalette.theme.rowSplitter
                    anchors.horizontalCenter: parent.horizontalCenter  
                }
    
                MouseArea {
                    id: dragArea
                    hoverEnabled: true
                    cursorShape: containsMouse ? Qt.SplitHCursor : Qt.ArrowCursor
                    anchors.fill: parent  
                    drag.target: splitter  
                    drag.axis: Drag.XAxis
                    drag.minimumX: 10 + 1  
                    drag.maximumX: detailsView.width - 10 - 1  
                    onPositionChanged: {
                        detailsView.SpliterPencent = (splitter.x + 1) / detailsView.width
                    }
                }
            }
            Rectangle {
                id: gradientBox
                visible: detailsDelegate.depth > 0  
                width: 5
                x: padding + (detailsDelegate.depth * detailsDelegate.indent) - 10
                height: parent.height
                gradient: Gradient {
                    orientation: Gradient.Horizontal 
                    GradientStop { position: 0.0; color: ColorPalette.theme.rowShadowStart }  
                    GradientStop { position: 1.0; color: ColorPalette.theme.rowShadowEnd } 
                }
            }
        }
    )", QUrl());
    QQuickItem* slotItem = qobject_cast<QQuickItem*>(rootComp.create(newContext));
	if (!rootComp.errors().isEmpty()) {
		qDebug() << rootComp.errorString();
	}
    slotItem->setParentItem(mRootItem);
    return { slotItem->childItems()[1] ,slotItem->childItems()[2] };
}

QQuickItem* QQuickDetailsViewRowBuilder::rootItem() const
{
    return mRootItem;
}

IDetailsViewRow* QQuickDetailsViewRowBuilder::row() const
{
    return mRow;
}

QQuickItem* QQuickDetailsViewRowBuilder::setupItem(QQuickItem* inParent, QString inQmlCode)
{
	QQmlEngine* engine = qmlEngine(inParent);
	QQmlContext* context = qmlContext(inParent);
	QQmlComponent comp(engine);
	QQmlComponent nameComp(engine);
	comp.setData(inQmlCode.toLocal8Bit(), QUrl());
	QVariantMap initialProperties;
	initialProperties["parent"] = QVariant::fromValue(inParent);
	auto item = qobject_cast<QQuickItem*>(comp.createWithInitialProperties(initialProperties, context));
    if (!comp.errors().isEmpty()) {
        qDebug() << comp.errorString();
    }
	item->setParentItem(inParent);
    return item;
}

void QQuickDetailsViewRowBuilder::setupLabel(QQuickItem* inParent, QString inText)
{
    QQuickItem* lableItem = setupItem(inParent, R"(
	    import QtQuick;
	    import QtQuick.Controls;
	    import ColorPalette;
	    Item{
            property string lableText
		    implicitHeight: 25
		    width: parent.width
		    anchors.verticalCenter: parent.verticalCenter
		    Text {
			    anchors.fill: parent
			    verticalAlignment: Text.AlignVCenter
			    clip: true
			    elide: Text.ElideRight
			    text: lableText
			    color: ColorPalette.theme.labelPrimary
		    }
	    }
    )");
    lableItem->setProperty("lableText", inText);
}

void QQuickDetailsViewRowBuilder::setHeightProxy(QQuickItem* inProxyItem)
{
	QQmlEngine* engine = qmlEngine(mRootItem);
	QQmlContext* context = qmlContext(mRootItem);
    context->parentContext()->setContextProperty("heightProxy", inProxyItem);
}

void QQuickDetailsViewRowBuilder::makePropertyRow(QPropertyHandle* inHandle)
{
	QQmlEngine* engine = qmlEngine(mRootItem);
	QQmlContext* context = qmlContext(mRootItem);
    QPair<QQuickItem*, QQuickItem*> slotItem = makeNameValueSlot();
	QQuickItem* nameEditor = inHandle->setupNameEditor(slotItem.first);
	QQuickItem* valueEditor = inHandle->steupValueEditor(slotItem.second);
	context->parentContext()->setContextProperty("heightProxy", valueEditor ? valueEditor : nameEditor);
}

QQuickDetailsViewLayoutBuilder::QQuickDetailsViewLayoutBuilder(IDetailsViewRow* inRow)
	: mRootRow(inRow)
{
}

IDetailsViewRow* QQuickDetailsViewLayoutBuilder::row() const
{
    return mRootRow;
}

void QQuickDetailsViewLayoutBuilder::addCustomRow(std::function<void(QQuickDetailsViewRowBuilder*)> creator, QString inOverrideName)
{
	QSharedPointer<IDetailsViewRow> child(new QDetailsViewRow_Custom(creator));
    child->setName(inOverrideName);
	mRootRow->addChild(child);
	child->attachChildren();
}

void QQuickDetailsViewLayoutBuilder::addProperty(QPropertyHandle* inPropertyHandle, QString inOverrideName)
{
	QSharedPointer<IDetailsViewRow> child(new QDetailsViewRow_Property(inPropertyHandle));
    child->setName(inOverrideName.isEmpty() ? inPropertyHandle->getName() : inOverrideName);
	mRootRow->addChild(child);
	child->attachChildren();
}

void QQuickDetailsViewLayoutBuilder::addObject(QObject* inObject)
{
    addProperty(QPropertyHandle::FindOrCreate(inObject));
}
