/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2024 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/

#include "FrameExplorer.h"

//-- CamiTK stuff
#include <Component.h>
#include <Application.h>

//-- to stretch th first column to entirely show the names
#include <QHeaderView>

using namespace camitk;

//----------------------- constructor ------------------------
FrameExplorer::FrameExplorer(QString name) : Viewer(name, Viewer::DOCKED) {
    explorerTree = nullptr;
    setIcon(QPixmap(":/axes"));
    setDescription("The frame explorer shows all the hierarchy of frames (which is independent from the hierarchy of components)");
}

//----------------------- getWidget ------------------------
QWidget* FrameExplorer::getWidget() {
    if (explorerTree == nullptr) {
        //-- create the explorer tree
        explorerTree = new QTreeWidget();
        // For explorerTree to emit the customMenu.. signal
        explorerTree->setContextMenuPolicy(Qt::CustomContextMenu);
        // headers
        QStringList headerTitles;
        headerTitles << "Name" << "ComponentName" ;
        explorerTree->setHeaderLabels(headerTitles);
        explorerTree->header()->setStretchLastSection(false);
        explorerTree->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); // First column stretch to what is needed
        // Unsortable column
        explorerTree->setSortingEnabled(false);
        // Multiple selection (click + Shift or Control key)
        explorerTree->setSelectionMode(QAbstractItemView::ExtendedSelection);

        //-- connections
        connect(explorerTree, SIGNAL(itemSelectionChanged()), this, SLOT(frameSelectionChanged()));
    }

    return explorerTree;
}

//----------------------- refresh ------------------------
void FrameExplorer::refresh(Viewer* whoIsAsking) {
    // if it is this instance who is asking the refresh, then only the Component names need to be checked...
    if (whoIsAsking != this) {
        ComponentList cptList = Application::getAllComponents();

        //clear the explorer
        remove();

        // rebuild the explorer tree
        foreach (Component* comp, cptList) {
            add(comp);
        }

        explorerTree->expandAll();
    }
}

//----------------------- getNewItem ------------------------
QTreeWidgetItem* FrameExplorer::getNewItem(QTreeWidgetItem* parent, Component* abstractNode) {
    //-- create the tree widget for abstractNode
    auto* tw = new QTreeWidgetItem(parent);
    // set the first column (#0)
    tw->setText(0, abstractNode->getFrame()->getFrameName());

    // and the second column (#1)
    tw->setText(1, abstractNode->getName());

    //-- add children recursively
    foreach (InterfaceFrame* intFrame, (abstractNode->getFrame()->getChildrenFrame())) {
        ComponentList cptlst = Application::getAllComponents();
        foreach (Component* cp, cptlst) {
            if (cp->getFrame()->getFrameName() == intFrame->getFrameName()) {
                getNewItem(tw, cp);
            }
        }
    }

    return tw;
}


//----------------------- add ------------------------
QTreeWidgetItem* FrameExplorer::add(QTreeWidgetItem* parent, Component* abstractNode) {

    //-- create the tree widget for abstractNode
    auto* tw = new QTreeWidgetItem(parent);

    // set the first column (#0)
    tw->setText(0, abstractNode->getFrame()->getFrameName());

    // and the second column (#1)
    tw->setText(1, abstractNode->getName());

    // add the explorer to the Component viewer list
    abstractNode->setVisibility(this->getName(), true);

    //-- add children
    foreach (InterfaceFrame* intFrame, abstractNode->getFrame()->getChildrenFrame()) {
        ComponentList cptlst = Application::getAllComponents();
        foreach (Component* cp, cptlst) {
            if (cp->getFrame()->getFrameName() == intFrame->getFrameName()) {
                getNewItem(tw, cp);
            }
        }
    }

    return tw;
}

//----------------------- add ------------------------
void FrameExplorer::add(Component* comp) {
    if (!comp->getFrame()->getParentFrame()) {
        // create the items
        QTreeWidgetItem* compItem = add(nullptr, comp);
        explorerTree->addTopLevelItem(compItem);
    }
}

//----------------------- remove ------------------------
void FrameExplorer::remove() {

    explorerTree->clear();

}

//----------------------- frameSelectionChanged ------------------------
void FrameExplorer::frameSelectionChanged() {
    // refresh!
    refresh(this);
}
