QWidget *Data3DTreeDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option , const QModelIndex& index) const
{
    const Data3DTreeModel* pData3DTreeModel = static_cast<const Data3DTreeModel*>(index.model());
    const AbstractTreeItem* pAbstractItem = static_cast<const AbstractTreeItem*>(pData3DTreeModel->itemFromIndex(index));

    switch(pAbstractItem->type()) {
        case MetaTreeItemTypes::SurfaceColorGyri: {
            QColorDialog *pColorDialog = new QColorDialog(parent);
            connect(pColorDialog, &QColorDialog::currentColorChanged,
                    this, &Data3DTreeDelegate::onEditorEdited);
            pColorDialog->setWindowTitle("Select Gyri Color");
            pColorDialog->show();
            return pColorDialog;
        }

        case MetaTreeItemTypes::SurfaceColorSulci: {
            QColorDialog *pColorDialog = new QColorDialog();
            connect(pColorDialog, &QColorDialog::currentColorChanged,
                    this, &Data3DTreeDelegate::onEditorEdited);
            pColorDialog->setWindowTitle("Select Sulci Color");
            pColorDialog->show();
            return pColorDialog;
        }

        case MetaTreeItemTypes::RTDataColormapType: {
            QComboBox* pComboBox = new QComboBox(parent);
            connect(pComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
                    this, &Data3DTreeDelegate::onEditorEdited);
            pComboBox->addItem("Hot Negative 1");
            pComboBox->addItem("Hot Negative 2");
            pComboBox->addItem("Hot");
            return pComboBox;
        }

        case MetaTreeItemTypes::RTDataNormalizationValue: {
            Spline* pSpline = new Spline("Spline Histogram", 0);
            connect(pSpline, static_cast<void (Spline::*)(double, double, double)>(&Spline::borderChanged),
            this, &Data3DTreeDelegate::onEditorEdited);
            QStandardItem* pParentItem = static_cast<QStandardItem*>(pAbstractItem->QStandardItem::parent());
            QModelIndex indexParent = pData3DTreeModel->indexFromItem(pParentItem);
            MatrixXd matRTData = index.model()->data(indexParent, Data3DTreeModelItemRoles::RTData).value<MatrixXd>();
            Eigen::VectorXd resultClassLimit;
            Eigen::VectorXi resultFrequency;
            MNEMath::histcounts(matRTData, false, 50, resultClassLimit, resultFrequency, 0.0, 0.0);
            pSpline->setData(resultClassLimit, resultFrequency, 0);
            QVector3D vecThresholdValues = index.model()->data(index, MetaTreeItemRoles::RTDataNormalizationValue).value<QVector3D>();
            pSpline->setThreshold(vecThresholdValues);
            AbstractTreeItem* pParentItemAbstract = static_cast<AbstractTreeItem*>(pParentItem);
            QList<QStandardItem*> pColormapItem = pParentItemAbstract->findChildren(MetaTreeItemTypes::RTDataColormapType);
            for(int i = 0; i < pColormapItem.size(); ++i)
            {
                QModelIndex indexColormapItem = pData3DTreeModel->indexFromItem(pColormapItem.at(i));
                QString colorMap = index.model()->data(indexColormapItem, MetaTreeItemRoles::RTDataColormapType).value<QString>();
                pSpline->setColorMap(colorMap);
            }
            return pSpline;
        }

        case MetaTreeItemTypes::RTDataTimeInterval: {
            QSpinBox* pSpinBox = new QSpinBox(parent);
            connect(pSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
                    this, &Data3DTreeDelegate::onEditorEdited);
            pSpinBox->setSuffix(" mSec");
            pSpinBox->setMinimum(17);
            pSpinBox->setMaximum(50000);
            pSpinBox->setSingleStep(10);
            pSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::RTDataTimeInterval).toInt());
            return pSpinBox;
        }

        case MetaTreeItemTypes::RTDataVisualizationType: {
            QComboBox* pComboBox = new QComboBox(parent);
            pComboBox->addItem("Vertex based");
            pComboBox->addItem("Smoothing based");
            pComboBox->addItem("Annotation based");
            return pComboBox;
        }

        case MetaTreeItemTypes::SurfaceColor: {
            QColorDialog *pColorDialog = new QColorDialog();
            connect(pColorDialog, &QColorDialog::currentColorChanged,
                    this, &Data3DTreeDelegate::onEditorEdited);
            pColorDialog->setWindowTitle("Select Surface Color");
            pColorDialog->show();
            return pColorDialog;
        }

        case MetaTreeItemTypes::PointColor: {
            QColorDialog *pColorDialog = new QColorDialog();
            connect(pColorDialog, &QColorDialog::currentColorChanged,
                    this, &Data3DTreeDelegate::onEditorEdited);
            pColorDialog->setWindowTitle("Select Point Color");
            pColorDialog->show();
            return pColorDialog;
        }

        case MetaTreeItemTypes::RTDataNumberAverages: {
            QSpinBox* pSpinBox = new QSpinBox(parent);
            connect(pSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
                    this, &Data3DTreeDelegate::onEditorEdited);
            pSpinBox->setMinimum(1);
            pSpinBox->setMaximum(100);
            pSpinBox->setSingleStep(1);
            pSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::RTDataNumberAverages).toInt());
            return pSpinBox;
        }

        case MetaTreeItemTypes::SurfaceAlpha: {
            QDoubleSpinBox* pDoubleSpinBox = new QDoubleSpinBox(parent);
            connect(pDoubleSpinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
                    this, &Data3DTreeDelegate::onEditorEdited);
            pDoubleSpinBox->setMinimum(0.01);
            pDoubleSpinBox->setMaximum(1.0);
            pDoubleSpinBox->setSingleStep(0.01);
            pDoubleSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::SurfaceAlpha).toDouble());
            return pDoubleSpinBox;
        }

        case MetaTreeItemTypes::SurfaceTranslateX: {
            QDoubleSpinBox* pDoubleSpinBox = new QDoubleSpinBox(parent);
            connect(pDoubleSpinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
                    this, &Data3DTreeDelegate::onEditorEdited);
            pDoubleSpinBox->setMinimum(-10000.0);
            pDoubleSpinBox->setMaximum(10000.0);
            pDoubleSpinBox->setSingleStep(0.01);
            pDoubleSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::SurfaceTranslateX).toDouble());
            return pDoubleSpinBox;
        }

        case MetaTreeItemTypes::SurfaceTranslateY: {
            QDoubleSpinBox* pDoubleSpinBox = new QDoubleSpinBox(parent);
            connect(pDoubleSpinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
                    this, &Data3DTreeDelegate::onEditorEdited);
            pDoubleSpinBox->setMinimum(-10000.0);
            pDoubleSpinBox->setMaximum(10000.0);
            pDoubleSpinBox->setSingleStep(0.01);
            pDoubleSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::SurfaceTranslateY).toDouble());
            return pDoubleSpinBox;
        }

        case MetaTreeItemTypes::SurfaceTranslateZ: {
            QDoubleSpinBox* pDoubleSpinBox = new QDoubleSpinBox(parent);
            connect(pDoubleSpinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
                    this, &Data3DTreeDelegate::onEditorEdited);
            pDoubleSpinBox->setMinimum(-10000.0);
            pDoubleSpinBox->setMaximum(10000.0);
            pDoubleSpinBox->setSingleStep(0.01);
            pDoubleSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::SurfaceTranslateZ).toDouble());
            return pDoubleSpinBox;
        }

        case MetaTreeItemTypes::NetworkThreshold: {
            Spline* pSpline = new Spline("Spline Histogram", 0);
            connect(pSpline, static_cast<void (Spline::*)(double, double, double)>(&Spline::borderChanged),
                this, &Data3DTreeDelegate::onEditorEdited);

            QStandardItem* pParentItem = static_cast<QStandardItem*>(pAbstractItem->QStandardItem::parent());
            QModelIndex indexParent = pData3DTreeModel->indexFromItem(pParentItem);
            MatrixXd matRTData = index.model()->data(indexParent, Data3DTreeModelItemRoles::NetworkDataMatrix).value<MatrixXd>();
            Eigen::VectorXd resultClassLimit;
            Eigen::VectorXi resultFrequency;
            MNEMath::histcounts(matRTData, false, 50, resultClassLimit, resultFrequency, 0.0, 0.0);
            pSpline->setData(resultClassLimit, resultFrequency, 0);
            QVector3D vecThresholdValues = index.model()->data(index, MetaTreeItemRoles::NetworkThreshold).value<QVector3D>();
            pSpline->setThreshold(vecThresholdValues);

            return pSpline;
        }

        case MetaTreeItemTypes::NetworkMatrix: {
            QStandardItem* pParentItem = static_cast<QStandardItem*>(pAbstractItem->QStandardItem::parent());
            QModelIndex indexParent = pData3DTreeModel->indexFromItem(pParentItem);
            MatrixXd matRTData = index.model()->data(indexParent, Data3DTreeModelItemRoles::NetworkDataMatrix).value<MatrixXd>();

            ImageSc* pPlotLA = new ImageSc(matRTData);
            pPlotLA->show();
            //return pPlotLA;
        }

        default: // do nothing;
            break;
    }


    return QItemDelegate::createEditor(parent, option, index);
}