#include "QQuickDetailsViewRow.h"
#include "QQuickDetailsViewLayoutBuilder.h"
#include "QQuickDetailsViewMananger.h"
#include "QQuickDetailsViewModel.h"

void IDetailsViewRow::setName(QString inName)
{
	mName = inName;
}

QString IDetailsViewRow::name()
{
	return mName;
}

void IDetailsViewRow::addChild(QSharedPointer<IDetailsViewRow> inChild)
{
	mChildren << inChild;
	inChild->mModel = mModel;
	inChild->mParent = this;
}

void IDetailsViewRow::clear()
{
	mChildren.clear();
}

QQuickDetailsViewModel* IDetailsViewRow::model()
{
	return mModel;
}

void IDetailsViewRow::notifyChildrenInserted()
{
	if (!mModel)
		return;
	const int count = mChildren.size();
	if (count == 0)
		return;
	QModelIndex parentIndex = mModel->indexForRow(this);
	if (!parentIndex.isValid())
		parentIndex = QModelIndex();
	mModel->beginInsertRows(parentIndex, 0, count - 1);
	for (int i = 0; i < count; ++i) {
		mChildren[i]->mParent = this;
		mChildren[i]->mModel = mModel;
	}
	mModel->endInsertRows();
}

void IDetailsViewRow::invalidateChildren()
{
	if (!mModel) {
		mChildren.clear();
		return;
	}

	QModelIndex parentIndex = mModel->indexForRow(this);
	if (!parentIndex.isValid()) {
		parentIndex = QModelIndex();
	}

	const int oldChildCount = mChildren.size();
	if (oldChildCount > 0) {
		mModel->beginRemoveRows(parentIndex, 0, oldChildCount - 1);
		mChildren.clear();
		mModel->endRemoveRows();
	}

	attachChildren();

	const int newChildCount = mChildren.size();
	if (newChildCount > 0) {
		mModel->beginInsertRows(parentIndex, 0, newChildCount - 1);
		for (auto& child : mChildren) {
			child->mParent = this;
			child->mModel = mModel;
		}
		mModel->endInsertRows();
	}
}

QDetailsViewRow_Property::QDetailsViewRow_Property(QPropertyHandle* inHandle)
{
	setHandle(inHandle);
}

QDetailsViewRow_Property::~QDetailsViewRow_Property()
{
	if (mStructureChangedConnection) {
		QObject::disconnect(mStructureChangedConnection);
	}
}

void QDetailsViewRow_Property::setupItem(QQuickItem* inParent)
{
	QQuickDetailsViewRowBuilder builder(this, inParent);
    if (mPropertyTypeCustomization) {
        mPropertyTypeCustomization->customizeHeaderRow(mHandle, &builder);
        return;
    }
	builder.makePropertyRow(mHandle);
}

void QDetailsViewRow_Property::attachChildren()
{
	if (mPropertyTypeCustomization){
		QQuickDetailsViewLayoutBuilder builder(this);
		mPropertyTypeCustomization->customizeChildren(mHandle, &builder);
	}
}

void QDetailsViewRow_Property::setHandle(QPropertyHandle* inHandle)
{
	mHandle = inHandle;
	if (!inHandle)
		return;
	mPropertyTypeCustomization = QQuickDetailsViewManager::Get()->getCustomPropertyType(inHandle);
	mStructureChangedConnection = QObject::connect(inHandle, &QPropertyHandle::asStructureChanged, [this]() {
		invalidateChildren();
	});
}

QDetailsViewRow_Custom::QDetailsViewRow_Custom(std::function<void(QQuickDetailsViewRowBuilder*)> inRowCreator)
	: mRowCreator(inRowCreator)
{

}

void QDetailsViewRow_Custom::setupItem(QQuickItem* inParent)
{
	if (mRowCreator) {
		QQuickDetailsViewRowBuilder builder(this, inParent);
		mRowCreator(&builder);
	}
}

QDetailsViewRow_Group::QDetailsViewRow_Group(const QString& groupName)
{
	setName(groupName);
}

void QDetailsViewRow_Group::setupItem(QQuickItem* inParent)
{
	QQuickDetailsViewRowBuilder builder(this, inParent);
	auto slotPair = builder.makeNameValueSlot();
	QQuickItem* groupLabel = builder.setupItem(slotPair.first, 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
				font.bold: true
				color: ColorPalette.theme.labelPrimary
			}
		}
	)");
	groupLabel->setProperty("lableText", mName);

	int childCount = mChildren.size();
	QQuickItem* countLabel = builder.setupItem(slotPair.second, R"qml(
		import QtQuick;
		import QtQuick.Controls;
		import ColorPalette;
		Item{
			property int groupChildCount: 0
			implicitHeight: 25
			width: parent.width
			anchors.verticalCenter: parent.verticalCenter
			visible: !detailsDelegate.expanded
			Text {
				anchors.right: parent.right
				anchors.verticalCenter: parent.verticalCenter
				text: "(" + groupChildCount + ")"
				color: ColorPalette.theme.textPrimary
			}
		}
	)qml");
	countLabel->setProperty("groupChildCount", childCount);

	builder.setHeightProxy(groupLabel);
}
