/***************************************************************************
    qgsbrowserdockwidget.h
    ---------------------
    begin                : July 2011
    copyright            : (C) 2011 by Martin Dobias
    email                : wonder dot sk at gmail dot com
 ***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#ifndef QGSBROWSERDOCKWIDGET_H
#define QGSBROWSERDOCKWIDGET_H

#include "ui_qgsbrowserdockwidgetbase.h"
#include "ui_qgsbrowserlayerpropertiesbase.h"
#include "ui_qgsbrowserdirectorypropertiesbase.h"
#include "ui_qgsbrowserpropertiesdialogbase.h"

#include "qgsbrowsertreeview.h"
#include "qgsdockwidget.h"
#include "qgis_gui.h"
#include <QSortFilterProxyModel>

class QgsBrowserGuiModel;
class QModelIndex;
class QgsDockBrowserTreeView;
class QgsLayerItem;
class QgsDataItem;
class QgsBrowserProxyModel;
class QgsMessageBar;
class QgsDataItemGuiContext;

/**
 * \ingroup gui
 * \brief The QgsBrowserDockWidget class
 * \since QGIS 3.0
 */
class GUI_EXPORT QgsBrowserDockWidget : public QgsDockWidget, private Ui::QgsBrowserDockWidgetBase
{
    Q_OBJECT
  public:

    /**
      * Constructor for QgsBrowserDockWidget
      * \param name name of the widget
      * \param browserModel instance of the (shared) browser model
      * \param parent parent widget
      */
    explicit QgsBrowserDockWidget( const QString &name, QgsBrowserGuiModel *browserModel, QWidget *parent SIP_TRANSFERTHIS = nullptr );
    ~QgsBrowserDockWidget() override;

    /**
     * Add directory to favorites.
     * \deprecated will be removed in QGIS 4.0 - use the methods in QgsBrowserModel instead
     */
    Q_DECL_DEPRECATED void addFavoriteDirectory( const QString &favDir, const QString &name = QString() ) SIP_DEPRECATED;

    /**
     * Sets a message \a bar to use alongside the dock widget. Setting this allows items
     * to utilize the message bar to provide non-blocking feedback to users, e.g.
     * success or failure of actions.
     *
     * \see messageBar()
     *
     * \since QGIS 3.6
     */
    void setMessageBar( QgsMessageBar *bar );

    /**
     * Returns the message bar associated with the dock.
     *
     * \see setMessageBar()
     *
     * \since QGIS 3.6
     */
    QgsMessageBar *messageBar();

    /**
     * Sets the customization for data items based on item's data provider key
     *
     * By default browser model shows all items from all available data items provider and few special
     * items (e.g. Favorites). To customize the behavior, set the filter to not load certain data items.
     * The items that are not based on data item providers (e.g. Favorites, Home) have
     * prefix "special:"
     *
     * Used in the proxy browser model to hide items
     *
     * \since QGIS 3.12
     */
    void setDisabledDataItemsKeys( const QStringList &filter );

  public slots:

    /**
     * Adds the layer corresponding to the specified model \a index.
     *
     * Returns TRUE if the index was successfully intrepreted as a map layer and loaded, or
     * FALSE if the index is not a map layer or could not be loaded.
     *
     * \deprecated will be removed in QGIS 4.0 - retrieve the QgsLayerItem itself and manually add to project.
     */
    Q_DECL_DEPRECATED bool addLayerAtIndex( const QModelIndex &index ) SIP_DEPRECATED;

    //! Show context menu
    void showContextMenu( QPoint );

    /**
     * Add current item to favorite.
     * \deprecated will be removed in QGIS 4.0 - use the methods in QgsBrowserModel instead
     */
    Q_DECL_DEPRECATED void addFavorite() SIP_DEPRECATED;

    /**
     * Add directory from file dialog to favorite.
     * \deprecated will be removed in QGIS 4.0 - use the methods in QgsBrowserModel instead
     */
    Q_DECL_DEPRECATED void addFavoriteDirectory() SIP_DEPRECATED;

    /**
     * Remove from favorite.
     * \deprecated will be removed in QGIS 4.0 - use the methods in QgsBrowserModel instead
     */
    Q_DECL_DEPRECATED void removeFavorite() SIP_DEPRECATED;

    //! Refresh browser view model (and view)
    void refresh();

    //! Show/hide filter widget
    void showFilterWidget( bool visible );
    //! Enable/disable properties widget
    void enablePropertiesWidget( bool enable );
    //! Sets filter syntax
    void setFilterSyntax( QAction * );
    //! Sets filter case sensitivity
    void setCaseSensitive( bool caseSensitive );
    //! Apply filter to the model
    void setFilter();
    //! Sets the selection to \a index and expand it
    void setActiveIndex( const QModelIndex &index );
    //! Update project home directory
    void updateProjectHome();

    //! Add selected layers to the project
    void addSelectedLayers();
    //! Show the layer properties
    void showProperties();
    //! Hide current item
    void hideItem();

    /**
     * Toggle fast scan
     * \deprecated will be removed in QGIS 4.0
     */
    Q_DECL_DEPRECATED void toggleFastScan() SIP_DEPRECATED;

    // TODO QGIS 4.0: make these private

    //! Selection has changed
    void selectionChanged( const QItemSelection &selected, const QItemSelection &deselected );
    //! Splitter has been moved
    void splitterMoved();

  signals:
    //! Emitted when a file needs to be opened
    void openFile( const QString &fileName, const QString &fileTypeHint = QString() );
    //! Emitted when drop uri list needs to be handled
    void handleDropUriList( const QgsMimeDataUtils::UriList & );
    //! Connections changed in the browser
    void connectionsChanged();

  protected:
    //! Show event override
    void showEvent( QShowEvent *event ) override;

  private slots:
    void itemDoubleClicked( const QModelIndex &index );
    void onOptionsChanged();

  private:
    //! Refresh the model
    void refreshModel( const QModelIndex &index );
    //! Add a layer
    void addLayer( QgsLayerItem *layerItem );
    //! Clear the properties widget
    void clearPropertiesWidget();
    //! Sets the properties widget
    void setPropertiesWidget();

    //! Count selected items
    int selectedItemsCount();
    //! Settings prefix (the object name)
    QString settingsSection() { return objectName().toLower(); }

    QgsDataItemGuiContext createContext();

    QgsDockBrowserTreeView *mBrowserView = nullptr;
    QgsBrowserGuiModel *mModel = nullptr;
    QgsBrowserProxyModel *mProxyModel = nullptr;
    QString mInitPath;
    bool mPropertiesWidgetEnabled;
    // height fraction
    float mPropertiesWidgetHeight;

    QgsMessageBar *mMessageBar = nullptr;
    QStringList mDisabledDataItemsKeys;
};

#endif // QGSBROWSERDOCKWIDGET_H
