/*
	QCD Utils - Qt bindings/utilites for CD Utils

	Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef QCD_MODEL_H
#define QCD_MODEL_H

#include <QAbstractItemModel>
#include <QItemDelegate>
#include <QStyledItemDelegate>
#include "pistring.h"

namespace CDUtils {
	class CDType;
	class CDSection;
	class Interface;

	enum Column {
		cID        ,
		cName_Cmd  ,
		cType      ,
		cXMode     ,
		cXAvg      ,
		cExpression,
		cValue     ,
		cComment   ,
		cLastColumn,
	};
}

namespace QAD {
	struct Enum;
}

class CDItemModel;


class CDItem {
	friend class CDItemModel;
	friend class CDView;
public:
	enum CDItemType{ItemCDType, ItemCDSection};
	CDItem(CDUtils::Interface * interface, int _index, CDItemType type, CDItem * parent);
	~CDItem();
	QVariant data(int column, int role) const;
	QVariant value(CDUtils::CDType & t, int role) const;
	bool setData(int column, const QVariant & value);
	CDItemType itemType() const {return type_;}
	PIDeque<int> buildPath() const;
	int index() const {return index_;}

	CDUtils::Interface * interface;
	bool expanded;

private:
	QString stringType(const PIString & t) const;
	QAD::Enum xModeEnum(int v) const;

	CDItem * parent_;
	int index_, item_count;
	CDItemType type_;
	QList<CDItem *> childs;
};


class CDDelegate : public QStyledItemDelegate
{
	Q_OBJECT
public:
	CDDelegate(QObject *parent = 0);

	void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
	QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
	void setEditorData(QWidget *editor, const QModelIndex &index) const;
	void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
	void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
	QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;

};


class CDItemModel : public QAbstractItemModel {
	Q_OBJECT
	friend class CDView;
public:
	explicit CDItemModel(int type_, QObject *parent = 0);
	~CDItemModel();

	QVariant data(const QModelIndex & index, int role) const;
	QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
	QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
	QModelIndex parent(const QModelIndex &index) const;
	int rowCount(const QModelIndex &parent = QModelIndex()) const;
	int columnCount(const QModelIndex &parent = QModelIndex()) const;
	Qt::ItemFlags flags(const QModelIndex &index) const;
	bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
	QMimeData * mimeData(const QModelIndexList & indexes) const;
	CDItem * getItem(const QModelIndex & index) const;
	QModelIndex indexByPath(const PIDeque<int> & path, int column = CDUtils::cID) const;

	void buildItem(CDItem * it, CDUtils::CDSection &r);

public slots:
	void rebuildModel();
	void updateModel();

private:
	void internalRebuild();

	CDUtils::Interface * interface;
	CDItem * root;

signals:

};

#endif // QCD_MODEL_H
