/*****************************************************************************
 * $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$
 ****************************************************************************/


#ifndef MEDICAL_IMAGE_VIEWER_H
#define MEDICAL_IMAGE_VIEWER_H

#include "MedicalImageViewerAPI.h"

// -- Core stuff
#include <Viewer.h>

// -- QT stuff
#include <QFrame>
#include <QGridLayout>
#include <QAction>
#include <QBoxLayout>

/**
  * @ingroup group_sdk_libraries_core_medicalimageviewer
  *
  * @brief All-in-one medical image viewer.
  *
  * MedicalImageViewer is a viewer that can display from 1 to 4 InteractiveViewer that represents
  * the axial, coronal, sagittal and 3D view of the same medical image.
  * The views used the default Interactive Viewers defined in the interactivesliceviewer and interactivegeometryviewer
  * viewer extensions.
  *
  * If this viewer extension is loaded, the default instance of this viewer can be accessed directly
  * by Application::getViewer("Medical Image Viewer").
  *
  * \image html libraries/medicalimageviewer.png "The medical image viewer"
  *
  * @see camitk::Viewer
  *
  */
class MEDICALIMAGEVIEWER_API MedicalImageViewer : public camitk::Viewer {
    Q_OBJECT

public:
    /// \enum LayoutVisibility describes the possible currently displayed InteractiveViewer
    enum LayoutVisibility {
        VIEWER_ALL,        ///< All InteractiveViewer are visible
        VIEWER_3D,         ///< Only the 3D InteractiveViewer are visible
        VIEWER_AXIAL,      ///< Only the axial InteractiveViewer are visible
        VIEWER_CORONAL,    ///< Only the coronal InteractiveViewer are visible
        VIEWER_SAGITTAL,   ///< Only the sagittal InteractiveViewer are visible
        VIEWER_ARBITRARY   ///< Only the arbitrary InteractiveViewer are visible
    };
    Q_ENUM(LayoutVisibility);

    Q_INVOKABLE MedicalImageViewer(QString);

    /** destructor */
    virtual ~MedicalImageViewer() override;

    /** @name Viewer inherited
      */
    /// @{
    /// refresh the view (can be interesting to know which other viewer is calling this)
    void refresh(Viewer* whoIsAsking = nullptr) override;

    /// get the viewer widget.
    QWidget* getWidget() override;

    /// get the propertyObject (only the 3D Scene one)
    camitk::PropertyObject* getPropertyObject() override;

    /// get the viewer menu
    QMenu* getMenu() override;

    /// get the viewer toolbar
    QToolBar* getToolBar() override;

    /** set the visibility of the toolbar in the main window (true by default).
      * If the visibility is set to false, the next call to setCentralViewer(..)
      * or addDockViwer(...) will remove it
      *
      * Specific behaviour for MedicalImageViewer:
      * The toolbar is normally updated automatically on layout update (see updateLayout())
      * and is visible.
      *
      *  if all the 3D scene is visible (which is the default visualization state).
      *  Calling this method with false will avoid this automatic update.
      *
      *  By default the toolbar is automatically updated.
      */
    void setToolBarVisibility(bool) override;
    /// @}

    /// called to change the layout, i.e. which viewer is visible
    void setVisibleViewer(LayoutVisibility);

    /// get the current layout value
    LayoutVisibility getVisibleViewer() const;

public slots:
    /// called when an internal InteractiveViewers has emitted a selectionChanged signal
    void synchronizeSelection();

private:
    /// set the current visibility of the different viewer
    void updateLayout();

    /// The main layout
    QGridLayout* frameLayout;

    /// The four corners of the main layout
    QVBoxLayout* northWestLayout;
    QVBoxLayout* southWestLayout;
    QVBoxLayout* northEastLayout;
    QVBoxLayout* southEastLayout;

    /// the main widget
    QFrame* frame;

    /// the QMenu for the MedicalImageViewer
    QMenu* viewerMenu;

    /// which viewer(s) is/are currently visible
    LayoutVisibility visibleLayout;

    /// contains all InteractiveViewer instance (access them by LayoutVisibility)
    QMap<LayoutVisibility, Viewer*> viewers;

    /// viewer visibility enum
    QList<LayoutVisibility> viewerVisibility;

    /// number of top-level component that are currently displayed
    unsigned int displayedTopLevelComponents;

    /// if true, the toolbar automatically updated
    bool autoUpdateToolbarVisibility;
};

Q_DECLARE_METATYPE(MedicalImageViewer::LayoutVisibility)

#endif

