//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/View/Instrument/InstrumentsTreeModel.h
//! @brief     Defines class InstrumentsTreeModel
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2021
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_INSTRUMENTSTREEMODEL_H
#define BORNAGAIN_GUI_VIEW_INSTRUMENT_INSTRUMENTSTREEMODEL_H

#include <QAbstractItemModel>
#include <QSet>

class InstrumentModel;
class InstrumentItem;

//! Tree model for instrument item selection. Used e.g. for the instrument library.
class InstrumentsTreeModel : public QAbstractItemModel {
    Q_OBJECT
public:
    InstrumentsTreeModel(QObject* parent, InstrumentModel* model);

    enum InstrumentType {
        None = 0x0,
        Gisas = 0x1,
        Offspec = 0x2,
        Specular = 0x4,
        Depthprobe = 0x8,
        All = Gisas | Offspec | Specular | Depthprobe
    };
    Q_DECLARE_FLAGS(VisibleInstrumentTypes, InstrumentType)

    void enableEmptyHeadlines(bool b);
    void setTypeEnabled(InstrumentType type, bool b);

    QModelIndex index(int row, int column,
                      const QModelIndex& parent = QModelIndex()) const override;

    QModelIndex parent(const QModelIndex& index) const override;
    int columnCount(const QModelIndex& parent = QModelIndex()) const override;
    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
    Qt::ItemFlags flags(const QModelIndex& index) const override;
    bool setData(const QModelIndex& index, const QVariant& value, int role) override;
    InstrumentItem* itemForIndex(const QModelIndex& index) const;
    QModelIndex indexForItem(InstrumentItem* item) const;

    void removeItem(InstrumentItem* item);

    //! The topmost visible item. Can be null of course.
    InstrumentItem* topMostItem() const;

    QModelIndex indexOfHeadline(InstrumentType type) const;
    bool isHeadline(const QModelIndex& index) const;

    static InstrumentType instrumentType(InstrumentItem* item);

private:
    void clear();
    QList<InstrumentType> visibleTypes() const;
    QVector<InstrumentItem*> instrumentItemsOfType(InstrumentType type) const;

private:
    InstrumentModel* m_model = nullptr;
    VisibleInstrumentTypes m_visibleTypes;
    bool m_namesAreEditable;
    bool m_enableEmptyHeadlines;
};

#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_INSTRUMENTSTREEMODEL_H
