/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Miodrag Milanovic <miodrag@symbioticeda.com>
 *  Copyright (C) 2018  Serge Bazanski <q3k@symbioticeda.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "designwidget.h"
#include <QAction>
#include <QApplication>
#include <QGridLayout>
#include <QLineEdit>
#include <QMenu>
#include <QSplitter>
#include <QToolBar>
#include <QTreeWidgetItem>
#include "fpgaviewwidget.h"

NEXTPNR_NAMESPACE_BEGIN

TreeView::TreeView(QWidget *parent) : QTreeView(parent) {}

TreeView::~TreeView() {}

void TreeView::mouseMoveEvent(QMouseEvent *event)
{
    QModelIndex index = indexAt(event->pos());
    if (index != current) {
        current = index;
        Q_EMIT hoverIndexChanged(index);
    }
    QTreeView::mouseMoveEvent(event);
}

void TreeView::leaveEvent(QEvent *event) { Q_EMIT hoverIndexChanged(QModelIndex()); }

DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr)
{
    tabWidget = new QTabWidget();

    // Add tree view
    for (int i = 0; i < 6; i++) {
        treeView[i] = new TreeView();
        treeModel[i] = new TreeModel::Model();
        treeView[i]->setModel(treeModel[i]);
        treeView[i]->setContextMenuPolicy(Qt::CustomContextMenu);
        treeView[i]->setSelectionMode(QAbstractItemView::ExtendedSelection);
        treeView[i]->viewport()->setMouseTracking(true);
        selectionModel[i] = nullptr;
    }

    tabWidget->addTab(treeView[0], "Bels");
    tabWidget->addTab(treeView[1], "Wires");
    tabWidget->addTab(treeView[2], "Pips");
    tabWidget->addTab(treeView[3], "Cells");
    tabWidget->addTab(treeView[4], "Nets");
    tabWidget->addTab(treeView[5], "Groups");

    // Add property view
    variantManager = new QtVariantPropertyManager(this);
    readOnlyManager = new QtVariantPropertyManager(this);
    groupManager = new QtGroupPropertyManager(this);
    variantFactory = new QtVariantEditorFactory(this);
    propertyEditor = new QtTreePropertyBrowser(this);
    propertyEditor->setFactoryForManager(variantManager, variantFactory);
    propertyEditor->setPropertiesWithoutValueMarked(true);
    propertyEditor->show();
    propertyEditor->treeWidget()->setContextMenuPolicy(Qt::CustomContextMenu);
    propertyEditor->treeWidget()->setSelectionMode(QAbstractItemView::ExtendedSelection);
    propertyEditor->treeWidget()->viewport()->setMouseTracking(true);

    searchEdit = new QLineEdit();
    searchEdit->setClearButtonEnabled(true);
    searchEdit->addAction(QIcon(":/icons/resources/zoom.png"), QLineEdit::LeadingPosition);
    searchEdit->setPlaceholderText("Search...");
    connect(searchEdit, &QLineEdit::returnPressed, this, &DesignWidget::onSearchInserted);

    actionFirst = new QAction("", this);
    actionFirst->setIcon(QIcon(":/icons/resources/resultset_first.png"));
    actionFirst->setEnabled(false);
    connect(actionFirst, &QAction::triggered, this, [this] {
        history_ignore = true;
        history_index = 0;
        auto h = history.at(history_index);
        if (tabWidget->currentIndex() != h.first) {
            selectionModel[tabWidget->currentIndex()]->clearSelection();
            tabWidget->setCurrentIndex(h.first);
            selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::Select);
        } else {
            selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::ClearAndSelect);
        }
        updateButtons();
    });

    actionPrev = new QAction("", this);
    actionPrev->setIcon(QIcon(":/icons/resources/resultset_previous.png"));
    actionPrev->setEnabled(false);
    connect(actionPrev, &QAction::triggered, this, [this] {
        history_ignore = true;
        history_index--;
        auto h = history.at(history_index);
        if (tabWidget->currentIndex() != h.first) {
            selectionModel[tabWidget->currentIndex()]->clearSelection();
            tabWidget->setCurrentIndex(h.first);
            selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::Select);
        } else {
            selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::ClearAndSelect);
        }
        updateButtons();
    });

    actionNext = new QAction("", this);
    actionNext->setIcon(QIcon(":/icons/resources/resultset_next.png"));
    actionNext->setEnabled(false);
    connect(actionNext, &QAction::triggered, this, [this] {
        history_ignore = true;
        history_index++;
        auto h = history.at(history_index);
        if (tabWidget->currentIndex() != h.first) {
            selectionModel[tabWidget->currentIndex()]->clearSelection();
            tabWidget->setCurrentIndex(h.first);
            selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::Select);
        } else {
            selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::ClearAndSelect);
        }
        updateButtons();
    });

    actionLast = new QAction("", this);
    actionLast->setIcon(QIcon(":/icons/resources/resultset_last.png"));
    actionLast->setEnabled(false);
    connect(actionLast, &QAction::triggered, this, [this] {
        history_ignore = true;
        history_index = int(history.size() - 1);
        auto h = history.at(history_index);
        if (tabWidget->currentIndex() != h.first) {
            selectionModel[tabWidget->currentIndex()]->clearSelection();
            tabWidget->setCurrentIndex(h.first);
            selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::Select);
        } else {
            selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::ClearAndSelect);
        }
        updateButtons();
    });

    actionClear = new QAction("", this);
    actionClear->setIcon(QIcon(":/icons/resources/cross.png"));
    actionClear->setEnabled(true);
    connect(actionClear, &QAction::triggered, this, [this] {
        history_index = -1;
        history.clear();
        int num = tabWidget->currentIndex();
        if (selectionModel[num]->selectedIndexes().size() > 0) {
            QModelIndex index = selectionModel[num]->selectedIndexes().at(0);
            if (index.isValid()) {
                ElementType type = treeModel[num]->nodeFromIndex(index)->type();
                if (type != ElementType::NONE)
                    addToHistory(num, index);
            }
        }
        updateButtons();
    });

    QToolBar *toolbar = new QToolBar();
    toolbar->addAction(actionFirst);
    toolbar->addAction(actionPrev);
    toolbar->addAction(actionNext);
    toolbar->addAction(actionLast);
    toolbar->addAction(actionClear);

    QWidget *topWidget = new QWidget();
    QVBoxLayout *vbox1 = new QVBoxLayout();
    topWidget->setLayout(vbox1);
    vbox1->setSpacing(5);
    vbox1->setContentsMargins(0, 0, 0, 0);
    vbox1->addWidget(searchEdit);
    vbox1->addWidget(tabWidget);

    QWidget *toolbarWidget = new QWidget();
    QHBoxLayout *hbox = new QHBoxLayout;
    hbox->setAlignment(Qt::AlignCenter);
    toolbarWidget->setLayout(hbox);
    hbox->setSpacing(0);
    hbox->setContentsMargins(0, 0, 0, 0);
    hbox->addWidget(toolbar);

    QWidget *btmWidget = new QWidget();

    QVBoxLayout *vbox2 = new QVBoxLayout();
    btmWidget->setLayout(vbox2);
    vbox2->setSpacing(0);
    vbox2->setContentsMargins(0, 0, 0, 0);
    vbox2->addWidget(toolbarWidget);
    vbox2->addWidget(propertyEditor);

    QSplitter *splitter = new QSplitter(Qt::Vertical);
    splitter->addWidget(topWidget);
    splitter->addWidget(btmWidget);

    QGridLayout *mainLayout = new QGridLayout();
    mainLayout->setSpacing(0);
    mainLayout->setContentsMargins(0, 0, 0, 0);
    mainLayout->addWidget(splitter);
    setLayout(mainLayout);

    // Connection
    connect(propertyEditor->treeWidget(), &QTreeWidget::customContextMenuRequested, this,
            &DesignWidget::prepareMenuProperty);
    connect(propertyEditor->treeWidget(), &QTreeWidget::itemDoubleClicked, this, &DesignWidget::onItemDoubleClicked);
    connect(propertyEditor, &QtTreePropertyBrowser::hoverPropertyChanged, this, &DesignWidget::onHoverPropertyChanged);

    for (int num = 0; num < 6; num++) {
        connect(treeView[num], &TreeView::customContextMenuRequested,
                [this, num](const QPoint &pos) { prepareMenuTree(num, pos); });
        connect(treeView[num], &TreeView::doubleClicked, [this](const QModelIndex &index) { onDoubleClicked(index); });
        connect(treeView[num], &TreeView::hoverIndexChanged,
                [this, num](QModelIndex index) { onHoverIndexChanged(num, index); });
        selectionModel[num] = treeView[num]->selectionModel();
        connect(selectionModel[num], &QItemSelectionModel::selectionChanged,
                [this, num](const QItemSelection &selected, const QItemSelection &deselected) {
                    onSelectionChanged(num, selected, deselected);
                });
    }

    history_index = -1;
    history_ignore = false;

    highlightColors[0] = QColor("#6495ed");
    highlightColors[1] = QColor("#7fffd4");
    highlightColors[2] = QColor("#98fb98");
    highlightColors[3] = QColor("#ffd700");
    highlightColors[4] = QColor("#cd5c5c");
    highlightColors[5] = QColor("#fa8072");
    highlightColors[6] = QColor("#ff69b4");
    highlightColors[7] = QColor("#da70d6");
}

DesignWidget::~DesignWidget() {}

void DesignWidget::updateButtons()
{
    int count = int(history.size());
    actionFirst->setEnabled(history_index > 0);
    actionPrev->setEnabled(history_index > 0);
    actionNext->setEnabled(history_index < (count - 1));
    actionLast->setEnabled(history_index < (count - 1));
}

void DesignWidget::addToHistory(int tab, QModelIndex item)
{
    if (!history_ignore) {
        int count = int(history.size());
        for (int i = count - 1; i > history_index; i--)
            history.pop_back();
        history.push_back(std::make_pair(tab, item));
        history_index++;
    }
    history_ignore = false;
    updateButtons();
}

void DesignWidget::newContext(Context *ctx)
{
    if (!ctx)
        return;

    highlightSelected.clear();
    history_ignore = false;
    history_index = -1;
    history.clear();
    updateButtons();

    highlightSelected.clear();
    this->ctx = ctx;
    {
        std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
        std::lock_guard<std::mutex> lock(ctx->mutex);

        {
            TreeModel::ElementXYRoot<BelId>::ElementMap belMap;
            for (const auto &bel : ctx->getBels()) {
                auto loc = ctx->getBelLocation(bel);
                belMap[std::pair<int, int>(loc.x, loc.y)].push_back(bel);
            }
            auto belGetter = [](Context *ctx, BelId id) { return ctx->getBelName(id); };

            getTreeByElementType(ElementType::BEL)
                    ->loadData(ctx,
                               std::unique_ptr<TreeModel::ElementXYRoot<BelId>>(
                                       new TreeModel::ElementXYRoot<BelId>(ctx, belMap, belGetter, ElementType::BEL)));
        }

        {
            TreeModel::ElementXYRoot<WireId>::ElementMap wireMap;
#ifdef ARCH_ICE40
            for (int i = 0; i < ctx->chip_info->num_wires; i++) {
                const auto wire = &ctx->chip_info->wire_data[i];
                WireId wireid;
                wireid.index = i;
                wireMap[std::pair<int, int>(wire->x, wire->y)].push_back(wireid);
            }
#endif
#ifdef ARCH_ECP5
            for (const auto &wire : ctx->getWires()) {
                wireMap[std::pair<int, int>(wire.location.x, wire.location.y)].push_back(wire);
            }
#endif
#ifdef ARCH_XC7
            for (const auto &wire : ctx->getWires()) {
                const auto loc = torc_info->wire_to_loc(wire.index);
                wireMap[std::pair<int, int>(loc.x, loc.y)].push_back(wire);
            }
#endif
            auto wireGetter = [](Context *ctx, WireId id) { return ctx->getWireName(id); };
            getTreeByElementType(ElementType::WIRE)
                    ->loadData(ctx,
                               std::unique_ptr<TreeModel::ElementXYRoot<WireId>>(new TreeModel::ElementXYRoot<WireId>(
                                       ctx, wireMap, wireGetter, ElementType::WIRE)));
        }

        {
            TreeModel::ElementXYRoot<PipId>::ElementMap pipMap;
            for (const auto &pip : ctx->getPips()) {
                auto loc = ctx->getPipLocation(pip);
                pipMap[std::pair<int, int>(loc.x, loc.y)].push_back(pip);
            }
            auto pipGetter = [](Context *ctx, PipId id) { return ctx->getPipName(id); };

            getTreeByElementType(ElementType::PIP)
                    ->loadData(ctx,
                               std::unique_ptr<TreeModel::ElementXYRoot<PipId>>(
                                       new TreeModel::ElementXYRoot<PipId>(ctx, pipMap, pipGetter, ElementType::PIP)));
        }

        getTreeByElementType(ElementType::CELL)
                ->loadData(ctx,
                           std::unique_ptr<TreeModel::IdStringList>(new TreeModel::IdStringList(ElementType::CELL)));
        getTreeByElementType(ElementType::NET)
                ->loadData(ctx,
                           std::unique_ptr<TreeModel::IdStringList>(new TreeModel::IdStringList(ElementType::NET)));
    }
    updateTree();
}

void DesignWidget::updateTree()
{
    clearProperties();

    QMap<TreeModel::Item *, int>::iterator i = highlightSelected.begin();
    while (i != highlightSelected.end()) {
        QMap<TreeModel::Item *, int>::iterator prev = i;
        ++i;
        if (prev.key()->type() == ElementType::NET && ctx->nets.find(prev.key()->id()) == ctx->nets.end()) {
            highlightSelected.erase(prev);
        }
        if (prev.key()->type() == ElementType::CELL && ctx->cells.find(prev.key()->id()) == ctx->cells.end()) {
            highlightSelected.erase(prev);
        }
    }

    {
        std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
        std::lock_guard<std::mutex> lock(ctx->mutex);

        std::vector<IdString> cells;
        for (auto &pair : ctx->cells) {
            cells.push_back(pair.first);
        }
        std::vector<IdString> nets;
        for (auto &pair : ctx->nets) {
            nets.push_back(pair.first);
        }

        getTreeByElementType(ElementType::CELL)->updateElements(cells);
        getTreeByElementType(ElementType::NET)->updateElements(nets);
    }
}
QtProperty *DesignWidget::addTopLevelProperty(const QString &id)
{
    QtProperty *topItem = groupManager->addProperty(id);
    propertyToId[topItem] = id;
    idToProperty[id] = topItem;
    topItem->setSelectable(false);
    propertyEditor->addProperty(topItem);
    return topItem;
}

void DesignWidget::clearProperties()
{
    QMap<QtProperty *, QString>::ConstIterator itProp = propertyToId.constBegin();
    while (itProp != propertyToId.constEnd()) {
        delete itProp.key();
        itProp++;
    }
    propertyToId.clear();
    idToProperty.clear();
}

QString DesignWidget::getElementTypeName(ElementType type)
{
    if (type == ElementType::NONE)
        return "";
    if (type == ElementType::BEL)
        return "BEL";
    if (type == ElementType::WIRE)
        return "WIRE";
    if (type == ElementType::PIP)
        return "PIP";
    if (type == ElementType::NET)
        return "NET";
    if (type == ElementType::CELL)
        return "CELL";
    return "";
}
ElementType DesignWidget::getElementTypeByName(QString type)
{
    if (type == "BEL")
        return ElementType::BEL;
    if (type == "WIRE")
        return ElementType::WIRE;
    if (type == "PIP")
        return ElementType::PIP;
    if (type == "NET")
        return ElementType::NET;
    if (type == "CELL")
        return ElementType::CELL;
    return ElementType::NONE;
}

TreeModel::Model *DesignWidget::getTreeByElementType(ElementType type)
{
    if (type == ElementType::NONE)
        return nullptr;
    if (type == ElementType::BEL)
        return treeModel[0];
    if (type == ElementType::WIRE)
        return treeModel[1];
    if (type == ElementType::PIP)
        return treeModel[2];
    if (type == ElementType::NET)
        return treeModel[3];
    if (type == ElementType::CELL)
        return treeModel[4];
    return nullptr;
}
int DesignWidget::getIndexByElementType(ElementType type)
{
    if (type == ElementType::NONE)
        return -1;
    if (type == ElementType::BEL)
        return 0;
    if (type == ElementType::WIRE)
        return 1;
    if (type == ElementType::PIP)
        return 2;
    if (type == ElementType::NET)
        return 3;
    if (type == ElementType::CELL)
        return 4;
    if (type == ElementType::GROUP)
        return 5;
    return -1;
}
void DesignWidget::addProperty(QtProperty *topItem, int propertyType, const QString &name, QVariant value,
                               const ElementType &type)
{
    QtVariantProperty *item = readOnlyManager->addProperty(propertyType, name);
    item->setValue(value);
    item->setPropertyId(getElementTypeName(type));
    item->setSelectable(type != ElementType::NONE);
    topItem->addSubProperty(item);
}

QtProperty *DesignWidget::addSubGroup(QtProperty *topItem, const QString &name)
{
    QtProperty *item = groupManager->addProperty(name);
    item->setSelectable(false);
    topItem->addSubProperty(item);
    return item;
}

void DesignWidget::clearAllSelectionModels()
{
    for (int i = 0; i <= getIndexByElementType(ElementType::GROUP); i++)
        selectionModel[i]->clearSelection();
}

void DesignWidget::onClickedBel(BelId bel, bool keep)
{
    boost::optional<TreeModel::Item *> item;
    {
        std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
        std::lock_guard<std::mutex> lock(ctx->mutex);

        item = getTreeByElementType(ElementType::BEL)->nodeForId(ctx->getBelName(bel));
        if (!item)
            return;

        Q_EMIT selected(getDecals(ElementType::BEL, ctx->getBelName(bel)), keep);
    }
    int index = getIndexByElementType(ElementType::BEL);
    if (!keep)
        clearAllSelectionModels();
    if (tabWidget->currentIndex() != index) {
        tabWidget->setCurrentIndex(index);
    }
    selectionModel[index]->setCurrentIndex(getTreeByElementType(ElementType::BEL)->indexFromNode(*item),
                                           keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
}

void DesignWidget::onClickedWire(WireId wire, bool keep)
{
    boost::optional<TreeModel::Item *> item;
    {
        std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
        std::lock_guard<std::mutex> lock(ctx->mutex);

        item = getTreeByElementType(ElementType::WIRE)->nodeForId(ctx->getWireName(wire));
        if (!item)
            return;

        Q_EMIT selected(getDecals(ElementType::WIRE, ctx->getWireName(wire)), keep);
    }
    int index = getIndexByElementType(ElementType::WIRE);
    if (!keep)
        clearAllSelectionModels();
    if (tabWidget->currentIndex() != index)
        tabWidget->setCurrentIndex(index);
    selectionModel[index]->setCurrentIndex(getTreeByElementType(ElementType::WIRE)->indexFromNode(*item),
                                           keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
}

void DesignWidget::onClickedPip(PipId pip, bool keep)
{
    boost::optional<TreeModel::Item *> item;
    {
        std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
        std::lock_guard<std::mutex> lock(ctx->mutex);

        item = getTreeByElementType(ElementType::PIP)->nodeForId(ctx->getPipName(pip));
        if (!item)
            return;

        Q_EMIT selected(getDecals(ElementType::PIP, ctx->getPipName(pip)), keep);
    }

    int index = getIndexByElementType(ElementType::PIP);
    if (!keep)
        clearAllSelectionModels();
    if (tabWidget->currentIndex() != index)
        tabWidget->setCurrentIndex(index);
    selectionModel[index]->setCurrentIndex(getTreeByElementType(ElementType::PIP)->indexFromNode(*item),
                                           keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
}

void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QItemSelection &)
{
    int num_selected = 0;
    std::vector<DecalXY> decals;
    for (int i = 0; i <= getIndexByElementType(ElementType::GROUP); i++) {
        num_selected += selectionModel[i]->selectedIndexes().size();
        for (auto index : selectionModel[i]->selectedIndexes()) {
            TreeModel::Item *item = treeModel[i]->nodeFromIndex(index);
            std::vector<DecalXY> d = getDecals(item->type(), item->id());
            std::move(d.begin(), d.end(), std::back_inserter(decals));
        }
    }

    // Keep other tree seleciton only if Control is pressed
    if (num_selected > 1 && QApplication::keyboardModifiers().testFlag(Qt::ControlModifier) == true) {
        Q_EMIT selected(decals, false);
        return;
    }

    // For deselect and multiple select just send all
    if (selectionModel[num]->selectedIndexes().size() != 1) {
        Q_EMIT selected(decals, false);
        return;
    }

    QModelIndex index = selectionModel[num]->selectedIndexes().at(0);
    if (!index.isValid())
        return;
    TreeModel::Item *clickItem = treeModel[num]->nodeFromIndex(index);

    ElementType type = clickItem->type();
    if (type == ElementType::NONE)
        return;

    // Clear other tab selections
    for (int i = 0; i <= getIndexByElementType(ElementType::GROUP); i++)
        if (i != num)
            selectionModel[i]->clearSelection();

    addToHistory(num, index);

    clearProperties();

    IdString c = clickItem->id();
    Q_EMIT selected(getDecals(type, c), false);

    if (type == ElementType::BEL) {
        std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
        std::lock_guard<std::mutex> lock(ctx->mutex);

        BelId bel = ctx->getBelByName(c);
        QtProperty *topItem = addTopLevelProperty("Bel");

        addProperty(topItem, QVariant::String, "Name", c.c_str(ctx));
        addProperty(topItem, QVariant::String, "Type", ctx->getBelType(bel).c_str(ctx));
        addProperty(topItem, QVariant::Bool, "Available", ctx->checkBelAvail(bel));
        addProperty(topItem, QVariant::String, "Bound Cell", ctx->nameOf(ctx->getBoundBelCell(bel)), ElementType::CELL);
        addProperty(topItem, QVariant::String, "Conflicting Cell", ctx->nameOf(ctx->getConflictingBelCell(bel)),
                    ElementType::CELL);

        QtProperty *attrsItem = addSubGroup(topItem, "Attributes");
        for (auto &item : ctx->getBelAttrs(bel)) {
            addProperty(attrsItem, QVariant::String, item.first.c_str(ctx), item.second.c_str());
        }

        QtProperty *belpinsItem = addSubGroup(topItem, "Ports");
        for (const auto &item : ctx->getBelPins(bel)) {
            QtProperty *portInfoItem = addSubGroup(belpinsItem, item.c_str(ctx));
            addProperty(portInfoItem, QVariant::String, "Name", item.c_str(ctx));
            addProperty(portInfoItem, QVariant::Int, "Type", int(ctx->getBelPinType(bel, item)));
            WireId wire = ctx->getBelPinWire(bel, item);
            addProperty(portInfoItem, QVariant::String, "Wire", ctx->getWireName(wire).c_str(ctx), ElementType::WIRE);
        }
    } else if (type == ElementType::WIRE) {
        std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
        std::lock_guard<std::mutex> lock(ctx->mutex);

        WireId wire = ctx->getWireByName(c);
        QtProperty *topItem = addTopLevelProperty("Wire");

        addProperty(topItem, QVariant::String, "Name", c.c_str(ctx));
        addProperty(topItem, QVariant::String, "Type", ctx->getWireType(wire).c_str(ctx));
        addProperty(topItem, QVariant::Bool, "Available", ctx->checkWireAvail(wire));
        addProperty(topItem, QVariant::String, "Bound Net", ctx->nameOf(ctx->getBoundWireNet(wire)), ElementType::NET);
        addProperty(topItem, QVariant::String, "Conflicting Wire",
                    ctx->getWireName(ctx->getConflictingWireWire(wire)).c_str(ctx), ElementType::WIRE);
        addProperty(topItem, QVariant::String, "Conflicting Net", ctx->nameOf(ctx->getConflictingWireNet(wire)),
                    ElementType::NET);

        QtProperty *attrsItem = addSubGroup(topItem, "Attributes");
        for (auto &item : ctx->getWireAttrs(wire)) {
            addProperty(attrsItem, QVariant::String, item.first.c_str(ctx), item.second.c_str());
        }

        DelayInfo delay = ctx->getWireDelay(wire);

        QtProperty *delayItem = addSubGroup(topItem, "Delay");
        addProperty(delayItem, QVariant::Double, "Min Raise", delay.minRaiseDelay());
        addProperty(delayItem, QVariant::Double, "Max Raise", delay.maxRaiseDelay());
        addProperty(delayItem, QVariant::Double, "Min Fall", delay.minFallDelay());
        addProperty(delayItem, QVariant::Double, "Max Fall", delay.maxFallDelay());

        QtProperty *belpinsItem = addSubGroup(topItem, "BelPins");
        for (const auto &item : ctx->getWireBelPins(wire)) {
            QString belname = "";
            if (item.bel != BelId())
                belname = ctx->getBelName(item.bel).c_str(ctx);
            QString pinname = item.pin.c_str(ctx);

            QtProperty *dhItem = addSubGroup(belpinsItem, belname + "-" + pinname);
            addProperty(dhItem, QVariant::String, "Bel", belname, ElementType::BEL);
            addProperty(dhItem, QVariant::String, "PortPin", pinname);
        }

        int counter = 0;
        QtProperty *pipsDownItem = addSubGroup(topItem, "Pips Downhill");
        for (const auto &item : ctx->getPipsDownhill(wire)) {
            addProperty(pipsDownItem, QVariant::String, "", ctx->getPipName(item).c_str(ctx), ElementType::PIP);
            counter++;
            if (counter == 50) {
                addProperty(pipsDownItem, QVariant::String, "Warning", "Too many items...", ElementType::NONE);
                break;
            }
        }

        counter = 0;
        QtProperty *pipsUpItem = addSubGroup(topItem, "Pips Uphill");
        for (const auto &item : ctx->getPipsUphill(wire)) {
            addProperty(pipsUpItem, QVariant::String, "", ctx->getPipName(item).c_str(ctx), ElementType::PIP);
            counter++;
            if (counter == 50) {
                addProperty(pipsUpItem, QVariant::String, "Warning", "Too many items...", ElementType::NONE);
                break;
            }
        }
    } else if (type == ElementType::PIP) {
        std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
        std::lock_guard<std::mutex> lock(ctx->mutex);

        PipId pip = ctx->getPipByName(c);
        QtProperty *topItem = addTopLevelProperty("Pip");

        addProperty(topItem, QVariant::String, "Name", c.c_str(ctx));
        addProperty(topItem, QVariant::String, "Type", ctx->getPipType(pip).c_str(ctx));
        addProperty(topItem, QVariant::Bool, "Available", ctx->checkPipAvail(pip));
        addProperty(topItem, QVariant::String, "Bound Net", ctx->nameOf(ctx->getBoundPipNet(pip)), ElementType::NET);
        WireId conflict = ctx->getConflictingPipWire(pip);
        addProperty(topItem, QVariant::String, "Conflicting Wire",
                    (conflict!=WireId() ? ctx->getWireName(conflict).c_str(ctx) : ""), ElementType::WIRE);
        addProperty(topItem, QVariant::String, "Conflicting Net", ctx->nameOf(ctx->getConflictingPipNet(pip)),
                    ElementType::NET);
        addProperty(topItem, QVariant::String, "Src Wire", ctx->getWireName(ctx->getPipSrcWire(pip)).c_str(ctx),
                    ElementType::WIRE);
        addProperty(topItem, QVariant::String, "Dest Wire", ctx->getWireName(ctx->getPipDstWire(pip)).c_str(ctx),
                    ElementType::WIRE);

        QtProperty *attrsItem = addSubGroup(topItem, "Attributes");
        for (auto &item : ctx->getPipAttrs(pip)) {
            addProperty(attrsItem, QVariant::String, item.first.c_str(ctx), item.second.c_str());
        }

        DelayInfo delay = ctx->getPipDelay(pip);

        QtProperty *delayItem = addSubGroup(topItem, "Delay");
        addProperty(delayItem, QVariant::Double, "Min Raise", delay.minRaiseDelay());
        addProperty(delayItem, QVariant::Double, "Max Raise", delay.maxRaiseDelay());
        addProperty(delayItem, QVariant::Double, "Min Fall", delay.minFallDelay());
        addProperty(delayItem, QVariant::Double, "Max Fall", delay.maxFallDelay());
    } else if (type == ElementType::NET) {
        std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
        std::lock_guard<std::mutex> lock(ctx->mutex);

        NetInfo *net = ctx->nets.at(c).get();

        QtProperty *topItem = addTopLevelProperty("Net");

        addProperty(topItem, QVariant::String, "Name", net->name.c_str(ctx));

        QtProperty *driverItem = addSubGroup(topItem, "Driver");
        addProperty(driverItem, QVariant::String, "Port", net->driver.port.c_str(ctx));
        addProperty(driverItem, QVariant::Double, "Budget", net->driver.budget);
        if (net->driver.cell)
            addProperty(driverItem, QVariant::String, "Cell", net->driver.cell->name.c_str(ctx), ElementType::CELL);
        else
            addProperty(driverItem, QVariant::String, "Cell", "", ElementType::CELL);

        QtProperty *usersItem = addSubGroup(topItem, "Users");
        for (auto &item : net->users) {
            QtProperty *portItem = addSubGroup(usersItem, item.port.c_str(ctx));

            addProperty(portItem, QVariant::String, "Port", item.port.c_str(ctx));
            addProperty(portItem, QVariant::Double, "Budget", item.budget);
            if (item.cell)
                addProperty(portItem, QVariant::String, "Cell", item.cell->name.c_str(ctx), ElementType::CELL);
            else
                addProperty(portItem, QVariant::String, "Cell", "", ElementType::CELL);
        }

        QtProperty *attrsItem = addSubGroup(topItem, "Attributes");
        for (auto &item : net->attrs) {
            addProperty(attrsItem, QVariant::String, item.first.c_str(ctx), item.second.c_str());
        }

        QtProperty *wiresItem = addSubGroup(topItem, "Wires");
        for (auto &item : net->wires) {
            auto name = ctx->getWireName(item.first).c_str(ctx);

            QtProperty *wireItem = addSubGroup(wiresItem, name);
            addProperty(wireItem, QVariant::String, "Wire", name, ElementType::WIRE);

            if (item.second.pip != PipId())
                addProperty(wireItem, QVariant::String, "Pip", ctx->getPipName(item.second.pip).c_str(ctx),
                            ElementType::PIP);
            else
                addProperty(wireItem, QVariant::String, "Pip", "", ElementType::PIP);

            addProperty(wireItem, QVariant::Int, "Strength", (int)item.second.strength);
        }

    } else if (type == ElementType::CELL) {
        std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
        std::lock_guard<std::mutex> lock(ctx->mutex);

        CellInfo *cell = ctx->cells.at(c).get();

        QtProperty *topItem = addTopLevelProperty("Cell");

        addProperty(topItem, QVariant::String, "Name", cell->name.c_str(ctx));
        addProperty(topItem, QVariant::String, "Type", cell->type.c_str(ctx));
        if (cell->bel != BelId())
            addProperty(topItem, QVariant::String, "Bel", ctx->getBelName(cell->bel).c_str(ctx), ElementType::BEL);
        else
            addProperty(topItem, QVariant::String, "Bel", "", ElementType::BEL);
        addProperty(topItem, QVariant::Int, "Bel strength", int(cell->belStrength));

        QtProperty *cellPortsItem = addSubGroup(topItem, "Ports");
        for (auto &item : cell->ports) {
            PortInfo p = item.second;

            QtProperty *portInfoItem = addSubGroup(cellPortsItem, p.name.c_str(ctx));
            addProperty(portInfoItem, QVariant::String, "Name", p.name.c_str(ctx));
            addProperty(portInfoItem, QVariant::Int, "Type", int(p.type));
            if (p.net)
                addProperty(portInfoItem, QVariant::String, "Net", p.net->name.c_str(ctx), ElementType::NET);
            else
                addProperty(portInfoItem, QVariant::String, "Net", "", ElementType::NET);
        }

        QtProperty *cellAttrItem = addSubGroup(topItem, "Attributes");
        for (auto &item : cell->attrs) {
            addProperty(cellAttrItem, QVariant::String, item.first.c_str(ctx), item.second.c_str());
        }

        QtProperty *cellParamsItem = addSubGroup(topItem, "Parameters");
        for (auto &item : cell->params) {
            addProperty(cellParamsItem, QVariant::String, item.first.c_str(ctx), item.second.c_str());
        }

        QtProperty *cellPinsItem = groupManager->addProperty("Pins");
        topItem->addSubProperty(cellPinsItem);
        for (auto &item : cell->pins) {
            std::string cell_port = item.first.c_str(ctx);
            std::string bel_pin = item.second.c_str(ctx);

            QtProperty *pinGroupItem = addSubGroup(cellPortsItem, (cell_port + " -> " + bel_pin).c_str());

            addProperty(pinGroupItem, QVariant::String, "Cell", cell_port.c_str(), ElementType::CELL);
            addProperty(pinGroupItem, QVariant::String, "Bel", bel_pin.c_str(), ElementType::BEL);
        }
    }
}

std::vector<DecalXY> DesignWidget::getDecals(ElementType type, IdString value)
{
    std::vector<DecalXY> decals;
    switch (type) {
    case ElementType::BEL: {
        BelId bel = ctx->getBelByName(value);
        if (bel != BelId()) {
            decals.push_back(ctx->getBelDecal(bel));
        }
    } break;
    case ElementType::WIRE: {
        WireId wire = ctx->getWireByName(value);
        if (wire != WireId()) {
            decals.push_back(ctx->getWireDecal(wire));
        }
    } break;
    case ElementType::PIP: {
        PipId pip = ctx->getPipByName(value);
        if (pip != PipId()) {
            decals.push_back(ctx->getPipDecal(pip));
        }
    } break;
    case ElementType::NET: {
        NetInfo *net = ctx->nets.at(value).get();
        for (auto &item : net->wires) {
            decals.push_back(ctx->getWireDecal(item.first));
            if (item.second.pip != PipId()) {
                decals.push_back(ctx->getPipDecal(item.second.pip));
            }
        }
    } break;
    case ElementType::CELL: {
        CellInfo *cell = ctx->cells.at(value).get();
        if (cell->bel != BelId()) {
            decals.push_back(ctx->getBelDecal(cell->bel));
        }
    } break;
    default:
        break;
    }
    return decals;
}

void DesignWidget::updateHighlightGroup(QList<TreeModel::Item *> items, int group)
{
    const bool shouldClear = items.size() == 1;
    for (auto item : items) {
        if (highlightSelected.contains(item)) {
            if (shouldClear && highlightSelected[item] == group) {
                highlightSelected.remove(item);
            } else
                highlightSelected[item] = group;
        } else
            highlightSelected.insert(item, group);
    }
    std::vector<DecalXY> decals[8];

    for (auto it : highlightSelected.toStdMap()) {
        std::vector<DecalXY> d = getDecals(it.first->type(), it.first->id());
        std::move(d.begin(), d.end(), std::back_inserter(decals[it.second]));
    }
    for (int i = 0; i < 8; i++)
        Q_EMIT highlight(decals[i], i);
}

void DesignWidget::prepareMenuProperty(const QPoint &pos)
{
    QTreeWidget *tree = propertyEditor->treeWidget();
    QList<TreeModel::Item *> items;
    for (auto itemContextMenu : tree->selectedItems()) {
        QtBrowserItem *browserItem = propertyEditor->itemToBrowserItem(itemContextMenu);
        if (!browserItem)
            continue;
        QtProperty *selectedProperty = browserItem->property();
        ElementType type = getElementTypeByName(selectedProperty->propertyId());
        if (type == ElementType::NONE)
            continue;
        IdString value = ctx->id(selectedProperty->valueText().toStdString());
        auto node = getTreeByElementType(type)->nodeForId(value);
        if (!node)
            continue;
        items.append(*node);
    }
    int selectedIndex = -1;
    if (items.size() == 1) {
        TreeModel::Item *item = items.at(0);
        if (highlightSelected.contains(item))
            selectedIndex = highlightSelected[item];
    }

    QMenu menu(this);
    QAction *selectAction = new QAction("&Select", this);
    connect(selectAction, &QAction::triggered, this, [this, items] {
        std::vector<DecalXY> decals;
        for (auto clickItem : items) {
            std::vector<DecalXY> d = getDecals(clickItem->type(), clickItem->id());
            std::move(d.begin(), d.end(), std::back_inserter(decals));
        }
        Q_EMIT selected(decals, false);
    });
    menu.addAction(selectAction);

    QMenu *subMenu = menu.addMenu("Highlight");
    QActionGroup *group = new QActionGroup(this);
    group->setExclusive(true);
    for (int i = 0; i < 8; i++) {
        QPixmap pixmap(32, 32);
        pixmap.fill(QColor(highlightColors[i]));
        QAction *action = new QAction(QIcon(pixmap), ("Group " + std::to_string(i)).c_str(), this);
        action->setCheckable(true);
        subMenu->addAction(action);
        group->addAction(action);
        if (selectedIndex == i)
            action->setChecked(true);
        connect(action, &QAction::triggered, this, [this, i, items] { updateHighlightGroup(items, i); });
    }
    menu.exec(tree->mapToGlobal(pos));
}

void DesignWidget::prepareMenuTree(int num, const QPoint &pos)
{
    int selectedIndex = -1;

    if (selectionModel[num]->selectedIndexes().size() == 0)
        return;

    QList<TreeModel::Item *> items;
    for (int i = 0; i <= getIndexByElementType(ElementType::GROUP); i++) {
        for (auto index : selectionModel[i]->selectedIndexes()) {
            TreeModel::Item *item = treeModel[i]->nodeFromIndex(index);
            items.append(item);
        }
    }
    if (items.size() == 1) {
        TreeModel::Item *item = items.at(0);
        if (highlightSelected.contains(item))
            selectedIndex = highlightSelected[item];
    }
    QMenu menu(this);
    QMenu *subMenu = menu.addMenu("Highlight");
    QActionGroup *group = new QActionGroup(this);
    group->setExclusive(true);
    for (int i = 0; i < 8; i++) {
        QPixmap pixmap(32, 32);
        pixmap.fill(QColor(highlightColors[i]));
        QAction *action = new QAction(QIcon(pixmap), ("Group " + std::to_string(i)).c_str(), this);
        action->setCheckable(true);
        subMenu->addAction(action);
        group->addAction(action);
        if (selectedIndex == i)
            action->setChecked(true);
        connect(action, &QAction::triggered, this, [this, i, items] { updateHighlightGroup(items, i); });
    }
    menu.exec(treeView[num]->mapToGlobal(pos));
}

void DesignWidget::onItemDoubleClicked(QTreeWidgetItem *item, int column)
{
    QtProperty *selectedProperty = propertyEditor->itemToBrowserItem(item)->property();
    ElementType type = getElementTypeByName(selectedProperty->propertyId());
    if (type == ElementType::NONE)
        return;
    auto it = getTreeByElementType(type)->nodeForId(ctx->id(selectedProperty->valueText().toStdString()));
    if (it) {
        int num = getIndexByElementType(type);
        clearAllSelectionModels();
        if (tabWidget->currentIndex() != num)
            tabWidget->setCurrentIndex(num);
        selectionModel[num]->setCurrentIndex(getTreeByElementType(type)->indexFromNode(*it),
                                             QItemSelectionModel::ClearAndSelect);
    }
}

void DesignWidget::onDoubleClicked(const QModelIndex &index) { Q_EMIT zoomSelected(); }

void DesignWidget::onSearchInserted()
{
    if (currentSearch == searchEdit->text() && currentIndexTab == tabWidget->currentIndex()) {
        currentIndex++;
        if (currentIndex >= currentSearchIndexes.size())
            currentIndex = 0;
    } else {
        std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
        std::lock_guard<std::mutex> lock(ctx->mutex);

        currentSearch = searchEdit->text();
        currentSearchIndexes = treeModel[tabWidget->currentIndex()]->search(searchEdit->text());
        currentIndex = 0;
        currentIndexTab = tabWidget->currentIndex();
    }
    if (currentSearchIndexes.size() > 0 && currentIndex < currentSearchIndexes.size())
        selectionModel[tabWidget->currentIndex()]->setCurrentIndex(currentSearchIndexes.at(currentIndex),
                                                                   QItemSelectionModel::ClearAndSelect);
}

void DesignWidget::onHoverIndexChanged(int num, QModelIndex index)
{
    if (index.isValid()) {
        TreeModel::Item *item = treeModel[num]->nodeFromIndex(index);
        if (item->type() != ElementType::NONE) {
            std::vector<DecalXY> decals = getDecals(item->type(), item->id());
            if (decals.size() > 0)
                Q_EMIT hover(decals.at(0));
            return;
        }
    }
    Q_EMIT hover(DecalXY());
}

void DesignWidget::onHoverPropertyChanged(QtBrowserItem *item)
{
    if (item != nullptr) {
        QtProperty *selectedProperty = item->property();
        ElementType type = getElementTypeByName(selectedProperty->propertyId());
        if (type != ElementType::NONE) {
            IdString value = ctx->id(selectedProperty->valueText().toStdString());
            if (value != IdString()) {
                auto node = getTreeByElementType(type)->nodeForId(value);
                if (node) {
                    std::vector<DecalXY> decals = getDecals((*node)->type(), (*node)->id());
                    if (decals.size() > 0)
                        Q_EMIT hover(decals.at(0));
                    return;
                }
            }
        }
    }
    Q_EMIT hover(DecalXY());
}
NEXTPNR_NAMESPACE_END
