#pragma once

#include <QAbstractTableModel>

#include "data/pattern.h"

namespace Xybrid::UI {
    class PatternEditorHeaderProxyModel;
    class PatternEditorModel : public QAbstractTableModel {
        Q_OBJECT

        std::shared_ptr<Data::Pattern> pattern;

    public:
        static constexpr int paramSoftCap = 16; // maximum number of parameter columns that can be displayed per channel; the rest are hidden
        static constexpr int colsPerChannel = 2 + (2 * paramSoftCap);
        static constexpr int cellPadding = 2;

        PatternEditorHeaderProxyModel* hprox;

        bool fitHeaderToName = false;
        bool folded = true;
        int endHeight = -1;

        PatternEditorModel(QObject *parent);
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
        int columnCount(const QModelIndex &parent = QModelIndex()) const override;
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
        QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
        Qt::ItemFlags flags(const QModelIndex & index) const override;

        int hdrColumnCount() const;
        QVariant hdrData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;

        void setPattern(const std::shared_ptr<Data::Pattern>& pattern);
        std::shared_ptr<Data::Pattern> getPattern() {
            return pattern;
        }

        void updateColumnDisplay();
        void refresh() { // implemented in header to allow inlining
            emit layoutChanged();
            updateFold();
            updateColumnDisplay();
        }

        void updateFold();
        void toggleFold();
    };

    class PatternEditorHeaderProxyModel : public QAbstractTableModel {
        PatternEditorModel* pm;
    public:
        PatternEditorHeaderProxyModel(QObject *parent, PatternEditorModel* p);
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
        int columnCount(const QModelIndex &parent = QModelIndex()) const override;
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
        QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    };
}
