#include <QDebug>

#include <QtWidgets/QLabel>
#include <QtWidgets/QTreeWidgetItem>
#include <QtWidgets/QListWidgetItem>
#include <QtWidgets/QTableView>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QTextEdit>

class QTreeWidget;
class QTreeWidgetItem;
class QListWidget;
class QListWidgetItem;

#include <QHBoxLayout>
#include <QScrollArea>
#include <QHeaderView>
#include <QDialog>
#include <QPushButton>
#include <QDialogButtonBox>

#include <QApplication>
#include <QMainWindow>
#include <QAbstractTableModel>
#include <QSortFilterProxyModel>
//#include <QAbstractItemModel>
#include <QBrush>
#include <QFont>

// ===============================================================================================

class DataEntity
{
public:
  DataEntity();
  virtual ~DataEntity();
  const QString getName() const { return name; };
  const QString getDescription() const { return description; };
  bool setData(const QString _name,
               const QString _description);
private:

  QString name;
  QString description;
  /* more data ... */
};

// -----------------------------------------------------------------------------------------------

class ListModel : public QAbstractTableModel
{
  Q_OBJECT

public:
  explicit ListModel(QObject *parent=0, QList<DataEntity>*local_list=0, QList<DataEntity>*global_list=0);
  ~ListModel();

  Qt::ItemFlags flags(const QModelIndex &index) const;
  QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
  int rowCount(const QModelIndex &index=QModelIndex()) const;
  int columnCount(const QModelIndex &index=QModelIndex()) const;

  DataEntity *getItem(const QModelIndex &index);
  void deleteItem(const QModelIndex &index);

  void reset() { beginResetModel(); endResetModel(); };

private:
  int listCount() const;

  QList<DataEntity> *local_list;
  QList<DataEntity> *global_list;
};

// -----------------------------------------------------------------------------------------------

class ProxyModel : public QSortFilterProxyModel
{
  Q_OBJECT

public:
    explicit ProxyModel(QObject *parent=0);

    QString getSubStr() const { return substr; }

    void reset() { beginResetModel(); endResetModel(); };

public slots:
    void clearFilters();
    void setSubStr(const QString &new_substr);

protected:
    bool filterAcceptsRow(int sourceRow,
                          const QModelIndex &sourceParent) const;

private:
    QString substr;
};

// -----------------------------------------------------------------------------------------------

class DetailsDialog : public QDialog
{
  Q_OBJECT
public:
  explicit DetailsDialog(QWidget *parent = 0);
  ~DetailsDialog();

  void setFormValues(DataEntity * const data);
  bool getFormValues(DataEntity * const data);

private:
  QLineEdit *lineEdit_name;
  QTextEdit *textEdit_description;
};

// -----------------------------------------------------------------------------------------------

class MainWindow : public QMainWindow
{
  Q_OBJECT
public:
  explicit MainWindow(QWidget *parent = 0);
  ~MainWindow();

private slots:
  // Main-Lists entry modify functions
  void editListItem(const QModelIndex*);
  void addListEntry();
  void editListEntry(const QModelIndex&);
  void deleteListEntry();

private:
  /* GUI selection lists */
  ListModel *model;
  ProxyModel *proxyModel;

  /* Data */
  QList<DataEntity> local;
};

// -----------------------------------------------------------------------------------------------
