/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 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 "Viewer.h"
#include "Component.h"
#include "Application.h"
#include "MainWindow.h"
#include "ViewerDockStyle.h"

#include "Log.h"

#include <QDockWidget>
#include <QStackedLayout>
#include <QLayout>

namespace camitk {

//---------------------- constructor ------------------------
Viewer::Viewer(QString name, ViewerType type): QObject() {
    this->name = name;
    setObjectName(name);
    this->type = type;

    dockWidget = nullptr;
    dockWidgetStyle = nullptr;
    embedder = nullptr;

    toolbarVisibility = true;

    componentClassNames << "Component";
}

//---------------------- destructor ------------------------
Viewer::~Viewer() {
    delete dockWidgetStyle;
}

// -------------------- setIcon --------------------
void Viewer::setIcon(QPixmap icon) {
    this->icon = icon;
}

// -------------------- getIcon --------------------
QPixmap Viewer::getIcon() const {
    return icon;
}

// -------------------- setComponentClassNames --------------------
void Viewer::setComponentClassNames(QStringList componentClassNames) {
    this->componentClassNames = componentClassNames;
}

// -------------------- getComponentClassNames --------------------
QStringList Viewer::getComponentClassNames() const {
    return componentClassNames;
}

// -------------------- setDescription --------------------
void Viewer::setDescription(QString description) {
    this->description = description;
}

//---------------------- selectionChanged ------------------------
void Viewer::selectionChanged(camitk::ComponentList& compSet) {
    for (Component* comp : compSet) {
        comp->setSelected(true);
    }

    emit selectionChanged();

}

void Viewer::selectionChanged(Component* comp) {
    comp->setSelected(true);
    emit selectionChanged();
}

//---------------------- clearSelection ------------------------
void Viewer::clearSelection() {
    Application::clearSelectedComponents();
    emit selectionChanged();
}

//---------------------- setToolBarVisibility ------------------------
void Viewer::setToolBarVisibility(bool toolbarVisibility) {
    this->toolbarVisibility = toolbarVisibility;
}

//---------------------- getToolBarVisibility ------------------------
bool Viewer::getToolBarVisibility() const {
    return toolbarVisibility;
}

// -------------------- getType --------------------
Viewer::ViewerType Viewer::getType() const {
    return type;
}

// -------------------- setType --------------------
void Viewer::setType(Viewer::ViewerType type) {
    this->type = type;
}

// -------------------- setDockWidget --------------------
bool Viewer::setDockWidget(QDockWidget* dockWidget) {
    if (type != DOCKED) {
        CAMITK_ERROR(tr("Cannot dock \"%1\": it is not a DOCKED type viewer").arg(name))
        return false;
    }
    else {
        // create the dock widget and insert it only if the viewer has a widget
        if (getWidget() != nullptr && this->dockWidget == nullptr) {
            // set the object name and the visible window title
            dockWidget->setObjectName(name);
            dockWidget->setWindowTitle(name);
            // set the style so that the icon is visible
            dockWidgetStyle = new ViewerDockStyle(this);
            dockWidget->setStyle(dockWidgetStyle);
            // add the widget
            // warning: this transfer ownership of the viewer widget to the dockWidget!
            dockWidget->setWidget(getWidget());
            // store the pointer
            this->dockWidget = dockWidget;
            return true;
        }
        return false;
    }
}

// -------------------- getDockWidget --------------------
QDockWidget* Viewer::getDockWidget() const {
    return dockWidget;
}

// -------------------- setEmbedder --------------------
bool Viewer::setEmbedder(QLayout* embedder) {
    if (type != EMBEDDED) {
        CAMITK_ERROR(tr("Cannot embed \"%1\": it is not a EMBEDDED type viewer").arg(name))
        return false;
    }
    else {
        // get an updated widget
        QWidget* myWidget = getWidget();
        // check all conditions are met
        if (myWidget != nullptr) {
            embedder->addWidget(myWidget);
            // keep the pointer
            this->embedder = embedder;
            // If it is a QStackedLayout, we need to call setCurrentWidget in order
            // to put back the viewer's widget on top of the stack
            QStackedLayout* stackEmbedder = qobject_cast<QStackedLayout*>(embedder);
            if (stackEmbedder != nullptr) {
                stackEmbedder->setCurrentWidget(myWidget);
            }
            return true;
        }
        return false;
    }
}

// -------------------- getEmbedder --------------------
QLayout* Viewer::getEmbedder() const {
    return embedder;
}

// -------------------- setVisible --------------------
void Viewer::setVisible(bool visible) {
    getWidget()->setVisible(visible);
}

}
