#ifndef IXWIDGETUTIL_H
#define IXWIDGETUTIL_H

#include <QGridLayout>
#include <QScrollArea>
#include <QLabel>
#include <QListView>
#include <QPushButton>
#include <QMessageBox>

#include "QxOrm.h"
#include "IxWidgetFactory.h"
#include "WidgetFactory.h"

class FormBuilder : public QObject
{
    Q_OBJECT
public:
    FormBuilder(QObject * parent = nullptr);
    ~FormBuilder();

	//************************************
	// Method:    build
    // FullName:  FormBuilder::build 根据实体类的各数据成员的属性构造输入界面
	// Access:    public 
	// Returns:   QWidget*
	// Qualifier:
	// Parameter: const QString & title 界面标题
	// Parameter: quint32 minWidth 最大宽度
	// Parameter: T t 实体类对象，非智能指针
	//************************************
	template<typename T>
    QWidget* build(const QString &title, quint32 minWidth = 1000);

    //************************************
    // Method:    getValue
    // FullName:  FormBuilder::getValue   获取用户输入数据的实体类对象
    // Access:    public 
    // Returns:   返回实体类的智能指针
    // Qualifier:
    //************************************
    template<typename T>
	std::shared_ptr<T> getValue()
	{
		std::shared_ptr<T> pOwner = std::make_shared<T>();
		foreach(auto &item, ixWidgets)
		{
			item.first->fromVariant(pOwner.get(), item.second->getValue());
		}
		return pOwner;
	}

	//************************************
	// Method:    fill
    // FullName:  FormBuilder::fill  从实体类T中取字段值填充进界面
	// Access:    public 
	// Returns:   void
	// Qualifier:
	// Parameter: T & t  需传入实体类的智能指针, 且其关联的实体类要和构造界面的build函数中的实体类T保持一致
	//************************************
	template<typename T>
    void fill(std::shared_ptr<T> &t)
	{
		if (!mainWidget || !t)
			return;
		foreach(auto &item, ixWidgets)
		{
			item.second->setValue(item.first->toVariant(t.get()));
		}
	}

    void clear();

private slots:
	void onSavePressed();

private:
    QLabel* buildLabel(QString text, bool required, QWidget* parent);

    bool isInput(qx::IxDataMember *dataMember);

private:
    QWidget* mainWidget;

	WidgetFactory *factorys;

	QList<QPair<qx::IxDataMember*, IxWidget*>> ixWidgets;
};


template<typename T>
inline QWidget* FormBuilder::build(const QString &title, quint32 minWidth)
{
    if (mainWidget != nullptr)
    {
        mainWidget->setMinimumWidth(minWidth);
        mainWidget->setWindowTitle(title);
        return mainWidget;
    }
    mainWidget = new QWidget;
    mainWidget->setMinimumWidth(minWidth);
    mainWidget->setWindowTitle(title);

    QVBoxLayout* widgetLayout = new QVBoxLayout(mainWidget);

    QScrollArea* scrollArea = new QScrollArea(mainWidget);
    QWidget* scrollAreaContent = new QWidget(scrollArea);
    QGridLayout* layout = new QGridLayout(scrollAreaContent);
    qint16 row = -1, col = 0, count = 0;

    QWidget* input = nullptr;
    qx::IxDataMemberX* dataMembers = qx::QxClass<T>::getSingleton()->getDataMemberX();
    for (int i = 0; i < dataMembers->size(); ++i)
    {
        qx::IxDataMember* dataMember = dataMembers->get(i);
        if (!isInput(dataMember))
			continue;
		IxWidgetFactory_ptr widgetFactory = factorys->getFactory(dataMember);
        if(!widgetFactory)
            continue;
        widgetFactory->create(dataMember,mainWidget);
        input =  widgetFactory->getWidget();
        IxWidget *iWidget = widgetFactory->getIxWidget();
        iWidget->setName(dataMember->getName());
        ixWidgets << qMakePair(dataMember,iWidget);

		QLabel* label = buildLabel(dataMember->getDescription(), dataMember->getRequired(), mainWidget);
        if (count % 2 == 0)
        {
            row++;
            col = 0;
        }
        else
        {
            col += 2;
            label->setStyleSheet("margin-left:15px");
        }
        count++;

        if (input != nullptr)
        {
            input->setObjectName(dataMember->getName());
            input->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
            layout->addWidget(label, row, col, Qt::AlignRight);
            layout->addWidget(input, row, col + 1);
        }
    }

    // 添加到布局中

    QPushButton* pbSave = new QPushButton(scrollAreaContent);
    QPushButton* pbCancel = new QPushButton(scrollAreaContent);
    QHBoxLayout* layoutButton = new QHBoxLayout(scrollAreaContent);
    layoutButton->addStretch();
    layoutButton->addWidget(pbSave);
    layoutButton->addWidget(pbCancel);
    pbSave->setText(QStringLiteral("保存"));
	pbCancel->setText(QStringLiteral("取消"));

    connect(pbSave, &QPushButton::clicked, this, &FormBuilder::onSavePressed);
    connect(pbCancel, &QPushButton::pressed, [=]() {
        ((QDialog*)(mainWidget->parent()))->reject();
        });

    widgetLayout->addWidget(scrollArea);
    widgetLayout->addLayout(layoutButton);
    widgetLayout->setContentsMargins(15, 15, 15, 15);
    widgetLayout->setSpacing(10);
    layout->setVerticalSpacing(15);

    scrollArea->setWidgetResizable(true);
    scrollArea->setFrameStyle(0);
    scrollArea->setWidget(scrollAreaContent);
    scrollArea->setStyleSheet("background-color:transparent;");

    return mainWidget;
}
#endif
