#include "qgscopeobjectdockwidget.h"
#include "ui_qgscopeobjectdockwidget.h"

#include "qgpropertywidget.h"

#include <QTreeWidget>
#include <QTreeWidgetItem>

#include <QMenu>
#include <QAction>

enum MyTreeRoles
{
    objPointer=Qt::UserRole
};


class QgScopeObjectDockWidget::Implementation
{
public:
    QTreeWidget* tw;
    QTreeWidgetItem* devRoot;
    QTreeWidgetItem* chRoot;
    QMap<QgScopeDevice*, QTreeWidgetItem*> dMap;

    QMenu* deviceMenu;
    QAction* aDevActivte;
    QAction* aDevFreeze;
    QAction* aObjectView;

    QgScopeDevice* selectedDevice;
};

QgScopeObjectDockWidget::QgScopeObjectDockWidget(QWidget *parent) :
    ads::CDockWidget("Scope Objects"),
    p_(*new Implementation)
{

    //Devices
    {
        p_.tw=new QTreeWidget;
        QTreeWidget& tw=*p_.tw;

        tw.setColumnCount(2);

        tw.setHeaderLabels(
                QStringList()
                  <<QString("Name")
                  <<QString("Status")
                  );

        p_.devRoot=new QTreeWidgetItem;
        p_.devRoot->setText(0, "Devices");

        p_.chRoot=new QTreeWidgetItem;
        p_.chRoot->setText(0, "Channels");

        tw.invisibleRootItem()->addChild(p_.devRoot);
        tw.invisibleRootItem()->addChild(p_.chRoot);

        tw.setRootIsDecorated(true);
        tw.setContextMenuPolicy(Qt::CustomContextMenu);

        p_.deviceMenu=new QMenu;
        p_.aDevActivte=p_.deviceMenu->addAction("Active");
        p_.aDevActivte->setCheckable(true);

        p_.aDevFreeze=p_.deviceMenu->addAction("Chrono Running");
        p_.aDevFreeze->setCheckable(true);

        p_.deviceMenu->addSeparator();
        p_.aObjectView=p_.deviceMenu->addAction("Object Propertiers...");

        connect(&tw, &QTreeWidget::customContextMenuRequested, this, &QgScopeObjectDockWidget::deviceContextMenu);

        connect(p_.aDevActivte, &QAction::toggled, this,
                [this](bool checked)
                {
                    p_.selectedDevice->setDeviceActive(checked);
                }
            );
        connect(p_.aDevFreeze, &QAction::toggled, this,
                [this](bool checked)
                {
                    p_.selectedDevice->chronoTimer().setFreeze(!checked);
                }
            );

        connect(p_.aObjectView, &QAction::triggered, this,
                [this]()
                {
                    QgPropertyDialog dlg(p_.selectedDevice, this);
                    dlg.exec();
                }
            );

        this->setWidget(&tw);
    }
}

QgScopeObjectDockWidget::~QgScopeObjectDockWidget()
{
    delete &p_;
    //delete ui;
}

void QgScopeObjectDockWidget::addChannel(QgScopeChannel* d)
{
    QTreeWidgetItem* i=new QTreeWidgetItem;
    i->setText(0, d->objectName());
    i->setData(0, objPointer, (quint64)d);

    p_.chRoot->addChild(i);
}

void QgScopeObjectDockWidget::addDevice(QgScopeDevice* d)
{
    QTreeWidgetItem* i=new QTreeWidgetItem;
    i->setText(0, d->nickName());
    i->setData(0, objPointer, (quint64)d);
    i->setData(0, Qt::ToolTipRole, d->tooltipString());
    i->setData(1, Qt::DisplayRole, d->statusString());

    p_.dMap[d]=i;

    p_.devRoot->addChild(i);

    i->setDisabled(!d->deviceActive());

    connect(d, &QgScopeDevice::deviceActivated, this, QgScopeObjectDockWidget::syncDeviceStatus);

    connect(d, &QgScopeDevice::statusStringChanged, this,
            [this](const QString& str)
            {
                QgScopeDevice* d=qobject_cast<QgScopeDevice*>(sender());
                auto i=p_.dMap.find(d);
                if (i!=p_.dMap.end())
                {
                    i.value()->setData(1, Qt::DisplayRole, str);
                }
            }
        );
    connect(d, &QgScopeDevice::tooltipChanged, this,
            [this](const QString& str)
            {
                QgScopeDevice* d=qobject_cast<QgScopeDevice*>(sender());
                auto i=p_.dMap.find(d);
                if (i!=p_.dMap.end())
                {
                    i.value()->setData(0, Qt::ToolTipRole, str);
                }
            }
        );
}

void QgScopeObjectDockWidget::syncDeviceStatus(bool /*active*/)
{
    QgScopeDevice* d=qobject_cast<QgScopeDevice*>(sender());
    auto i=p_.dMap.find(d);
    if (i!=p_.dMap.end())
    {
        //i.value()->setDisabled(!active);
    }
}

void QgScopeObjectDockWidget::deviceContextMenu(const QPoint& pos)
{
    auto gpos=p_.tw->mapToGlobal(pos);
    auto i=p_.tw->currentItem();
    p_.selectedDevice=qobject_cast<QgScopeDevice*>((QObject*)(i->data(0, objPointer).toULongLong()));
    if (!p_.selectedDevice)
        return;

    //Sync the option
    p_.aDevActivte->setChecked(p_.selectedDevice->deviceActive());
    p_.aDevFreeze->setChecked(!p_.selectedDevice->chronoTimer().frozen());

    p_.deviceMenu->popup(gpos);
}
