
/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#pragma once

#include <QAbstractItemModel>
#include <QColor>
#include <QSortFilterProxyModel>
#include <QStyledItemDelegate>
#include <vector>


class MvScm;
class MvScmVar;
class MvScmProfileChange;

class MvQScmTableViewDelegate : public QStyledItemDelegate
{
public:
    MvQScmTableViewDelegate(QObject* parent = 0);
    void paint(QPainter* painter, const QStyleOptionViewItem& option,
               const QModelIndex& index) const;
};

class MvQScmDataModel : public QAbstractItemModel
{
    Q_OBJECT

public:
    QModelIndex index(int, int, const QModelIndex& parent = QModelIndex()) const;
    virtual QModelIndex indexForVar(MvScmVar*, int, int) const = 0;
    QModelIndex indexForChange(const MvScmProfileChange&) const;
    QModelIndex parent(const QModelIndex&) const;

    void dataIsAboutToChange();
    void setStep(int);
    void reload();
    int step() const { return step_; }
    void setEditableVars(const std::vector<MvScmVar*>& v) { editableVars_ = v; }

    virtual bool setData(const QModelIndex&, const QVariant&, int role = Qt::EditRole) = 0;
    virtual void setData(const std::vector<MvScmVar*>&, int, const std::vector<float>&, const std::string&) {}
    virtual void setData(const std::vector<MvScmVar*>&, int) {}

signals:
    void dataEdited(const MvScmProfileChange&);

protected:
    MvQScmDataModel(QObject* parent = 0);

    std::vector<MvScmVar*> data_;
    QList<int> columnOrder_;
    int step_;
    std::vector<MvScmVar*> editableVars_;
    QColor editCol_;
};


class MvQScmSurfaceModel : public MvQScmDataModel
{
public:
    MvQScmSurfaceModel(QObject* parent = 0);

    int columnCount(const QModelIndex& parent = QModelIndex()) const;
    int rowCount(const QModelIndex& parent = QModelIndex()) const;
    QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const;
    bool setData(const QModelIndex&, const QVariant&, int role = Qt::EditRole);
    void setData(const std::vector<MvScmVar*>&, int);
    QVariant headerData(int, Qt::Orientation, int role = Qt::DisplayRole) const;
    QModelIndex indexForVar(MvScmVar*, int, int) const;
    Qt::ItemFlags flags(const QModelIndex&) const;
};

class MvQScmProfileModel : public MvQScmDataModel
{
public:
    MvQScmProfileModel(QObject* parent = 0);

    int columnCount(const QModelIndex& parent = QModelIndex()) const;
    int rowCount(const QModelIndex& parent = QModelIndex()) const;
    QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const;
    bool setData(const QModelIndex&, const QVariant&, int role = Qt::EditRole);
    void setData(const std::vector<MvScmVar*>&, int, const std::vector<float>&, const std::string&);
    QVariant headerData(int, Qt::Orientation, int role = Qt::DisplayRole) const;
    QModelIndex indexForVar(MvScmVar*, int, int) const;
    Qt::ItemFlags flags(const QModelIndex&) const;

protected:
    std::vector<float> levels_;
    QString levelName_;
};


class MvQScmProfileFilterModel : public QSortFilterProxyModel
{
public:
    MvQScmProfileFilterModel(QObject* parent = 0);
    bool filterAcceptsColumn(int, const QModelIndex&) const;
    void setShowEditableOnly(bool);
    bool showEditableOnly() const { return showEditableOnly_; }

protected:
    bool showEditableOnly_;
};
