/*****************************************************************************
 * $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 IMP_MAINWINDOW_H
#define IMP_MAINWINDOW_H

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

/**
 * @ingroup group_sdk_application_imp
 *
 * @brief
 * This Class describes the "historical" imp application.
 * It is a classical desktop application, with  menubar and statusbar.
 *
 */
class ImpMainWindow : public camitk::MainWindow {
    Q_OBJECT

public:

    /// @name general
    ///@{
    /// construtor
    ImpMainWindow();

    /// overriden from MainWindow to automatically load last opened document if needed
    void aboutToShow() override;

    /// destructor
    virtual ~ImpMainWindow();

    /// @name open a top-level component
    ///@{

    /** add a Viewer to the application as a docking widget and specify where it has to be docked
    * MainWindow takes the hand on the Viewer (it will be deleted when MainWindow is deleted).
    * This method calls addViewer(...).
    */
    virtual void addDockViewer(Qt::DockWidgetArea, camitk::Viewer*) override final;

    /** set the central Viewer of the application.
    * MainWindow takes the hand on the Viewer (it will be deleted when MainWindow is deleted)
    * This method calls addViewer(...).
    */
    virtual void setCentralViewer(camitk::Viewer*) override final;

    /// use or not the application console (overriden to add an action to show the console window)
    virtual void redirectToConsole(bool) override;
    ///@}

public slots:

    /// @name file menu slot
    ///@{
    /// open a data directory, "called" from the fileOpenDataDirectoryMenu
    void openDataDirectory(QString plugin);
    ///@}

    /// @name viewers' slot
    ///@{
    /// this slot is connected to all the viewers selectionChanged() signal, this will call the refresh method of all viewers but whoIsAsking
    virtual void refresh() override;
    ///@}

    /** @name View menu slots
     *  \note everything that is linked to the InteractiveViewer has to be managed by the view (in case there is more than one InteractiveViewer)
     */
    ///@{

    /// show or hide the menu bar
    void toggleMenuBar();

    /// reset all windows in their initial state
    void resetWindows();

    /// show or hide the status bar
    void showStatusBar(bool);

    /// Save the history of action as a SCXML file
    void saveHistoryAsSCXML();

    ///@}

    /** @name Edit menu slots */
    ///@{
    /// settings slot
    void editSettings();

    ///@}

protected:

    /** @name initialization/update methods */
    ///@{
    /// update the viewer's menu
    void updateViewMenu();

    /// update the open data directory menu depending on registered plugins
    void updateOpenDirectoryMenu();

    /// update the recent document menu
    void updateRecentDocumentsMenu();

    /// set the current QAction enable state depending on the current selection, also update the dev menu
    void updateActionStates();

    /** initializes all QActions of the application */
    void initActions();
    ///@}

private:

    /** @name initialization/update methods */
    ///@{

    /** initMenuBar creates the menu_bar and inserts the menuitems */
    void initMenuBar();

    ///@}



    /** @name File menu attributes */
    ///@{
    /** file_menu contains all items of the menubar entry "File" */
    QMenu* fileMenu;
    QMenu* editMenu;
    QMenu* helpMenu;
    QMenu* fileOpenDataDirectoryMenu;
    QAction* fileOpen;
    QAction* fileClose;
    QAction* fileCloseAll;
    QAction* fileSave;
    QAction* fileSaveAs;
    QAction* fileSaveAll;
    QAction* workspaceSave;
    QAction* fileQuit;

    /** @name View menu attributes and action */
    ///@{
    /** viewMenu contains all items of the menubar entry "View" */
    QMenu* viewMenu;
    QAction* viewMenuBar;
    QAction* viewStatusBar;
    QAction* viewResetWindows;
    ///@}

    /** @name Edit menu attributes */
    ///@{
    /// edit actions
    QAction* editApplicationSettings;
    QAction* editClearSelection;
    QAction* saveHistory;
    ///@}

    /** @name Other menu attributes */
    ///@{
    /** the actionMenu.
    ** it contains the list of specific actions possible on the currently selected Component
    ** (this menu is in fact the Popup Menu of the selected Component and is
    ** updated everytime a new Component is selected)
    */
    QMenu* actionMenu;

    /** @name OevMenu as the developer actions */
    ///@{
    QMenu* devMenu;
    QAction* newExtensionFileAction;
    QAction* openExtensionFileAction;
    QAction* registerExtensionAction;
    QAction* verifyOrRebuildOnStartup;
    ///@}

    /** @name Other menu attributes */
    ///@{
    /// actions of the Help menu
    QAction* helpAboutApp;

    /// action for the show console
    QAction* helpShowConsole;
    ///@}

    /** @name Translation menu attributes */
    ///@{
    /// action to the change the language of the application
    QAction* changeLanguage;
    ///@}

    /// @name File management attributes
    ///@{

    /// list of all the possible recent documents actions
    QList<QAction*> recentDocumentActions;

    /// the separator between the last file menu action and the recent document actions
    QAction* recentDocumentSeparator;

    /// the separator between the last edit action and the preference menu separator
    QAction* editMenuSeparator;

    /// the separator between the viewer menus and the toggle menu
    QAction* viewMenuSeparator;

    /// the separator between the extension management action and the generic dev studio options
    QAction* devMenuSeparator;

    /// the separator between the help menu actions and the About action
    QAction* helpMenuSeparator;
    ///@}

private slots:

    /// open a given recent document
    void openRecentDocuments();

    /// use a timer to defer the rebuild of the menu in a later event
    void deferUpdateDevMenu();

    /// rebuild dev menu
    void updateDevMenu();

};

#endif // IMP_MAINWINDOW_H

