#ifndef SESSION_MANAGER_H
#define SESSION_MANAGER_H

#include <QPair>
#include <QMainWindow>
#include <QCheckBox>
#include <QLineEdit>
#include <QDoubleSpinBox>
#include <QAction>
#include <QComboBox>
#include <QTabWidget>
#include <QToolButton>
#include <QSplitter>
#include <QStackedWidget>
#include <QGroupBox>
#include "spinslider.h"
#include "evalspinbox.h"
#include "qpiconfig.h"


/// for all children widgets of "QMainWindow"s and MainWidgets
/// check for slots
/// * void sessionSave(QByteArray * data);
/// * void sessionLoad(QByteArray * data);


class QAD_EXPORT SessionManager: public QObject
{
	Q_OBJECT
public:
	SessionManager(const QString & file = QString()) {setFile(file);}
	~SessionManager() {;}

	void setFile(const QString & file);

	void addEntry(QMainWindow * e) {mwindows.push_back(QPair<QString, QMainWindow * >(e->objectName(), e));}
	void addEntry(QCheckBox * e) {checks.push_back(QPair<QString, QCheckBox * >(e->objectName(), e));}
	void addEntry(QLineEdit * e) {lines.push_back(QPair<QString, QLineEdit * >(e->objectName(), e));}
	void addEntry(QComboBox * e) {combos.push_back(QPair<QString, QComboBox * >(e->objectName(), e));}
	void addEntry(QDoubleSpinBox * e) {dspins.push_back(QPair<QString, QDoubleSpinBox * >(e->objectName(), e));}
	void addEntry(QSpinBox * e) {spins.push_back(QPair<QString, QSpinBox * >(e->objectName(), e));}
	void addEntry(SpinSlider * e) {spinsliders.push_back(QPair<QString, SpinSlider * >(e->objectName(), e));}
	void addEntry(EvalSpinBox * e) {evals.push_back(QPair<QString, EvalSpinBox * >(e->objectName(), e));}
	void addEntry(QTabWidget * e) {tabs.push_back(QPair<QString, QTabWidget * >(e->objectName(), e));}
	void addEntry(QGroupBox * e) {groups.push_back(QPair<QString, QGroupBox * >(e->objectName(), e));}
	void addEntry(QAction * e) {actions.push_back(QPair<QString, QAction * >(e->objectName(), e));}
	void addEntry(QAbstractButton * e) {buttons.push_back(QPair<QString, QAbstractButton * >(e->objectName(), e));}
	void addEntry(QStackedWidget * e) {stacks.push_back(QPair<QString, QStackedWidget * >(e->objectName(), e));}
	void addMainWidget(QWidget * e) {widgets.push_back(QPair<QString, QWidget * >(e->objectName(), e));}
	void removeMainWidget(QWidget * e);

	void addEntry(const QString & name, QMainWindow * e) {mwindows.push_back(QPair<QString, QMainWindow * >(name, e));}
	void addEntry(const QString & name, QCheckBox * e) {checks.push_back(QPair<QString, QCheckBox * >(name, e));}
	void addEntry(const QString & name, QLineEdit * e) {lines.push_back(QPair<QString, QLineEdit * >(name, e));}
	void addEntry(const QString & name, QComboBox * e) {combos.push_back(QPair<QString, QComboBox * >(name, e));}
	void addEntry(const QString & name, QDoubleSpinBox * e) {dspins.push_back(QPair<QString, QDoubleSpinBox * >(name, e));}
	void addEntry(const QString & name, QSpinBox * e) {spins.push_back(QPair<QString, QSpinBox * >(name, e));}
	void addEntry(const QString & name, SpinSlider * e) {spinsliders.push_back(QPair<QString, SpinSlider * >(name, e));}
	void addEntry(const QString & name, EvalSpinBox * e) {evals.push_back(QPair<QString, EvalSpinBox * >(name, e));}
	void addEntry(const QString & name, QTabWidget * e) {tabs.push_back(QPair<QString, QTabWidget * >(name, e));}
	void addEntry(const QString & name, QGroupBox * e) {groups.push_back(QPair<QString, QGroupBox * >(name, e));}
	void addEntry(const QString & name, QAbstractButton * e) {buttons.push_back(QPair<QString, QAbstractButton * >(name, e));}
	void addEntry(const QString & name, QStackedWidget * e) {stacks.push_back(QPair<QString, QStackedWidget * >(name, e));}
	void addEntry(const QString & name, QAction * e) {actions.push_back(QPair<QString, QAction * >(name, e));}
	void addEntry(const QString & name, QStringList * e) {stringlists.push_back(QPair<QString, QStringList * >(name, e));}
	void addEntry(const QString & name, QString * e) {strings.push_back(QPair<QString, QString * >(name, e));}
	void addEntry(const QString & name, QColor * e) {colors.push_back(QPair<QString, QColor * >(name, e));}
	void addEntry(const QString & name, bool * e) {bools.push_back(QPair<QString, bool * >(name, e));}
	void addEntry(const QString & name, int * e) {ints.push_back(QPair<QString, int * >(name, e));}
	void addEntry(const QString & name, float * e) {floats.push_back(QPair<QString, float * >(name, e));}
	void addMainWidget(const QString & name, QWidget * e) {widgets.push_back(QPair<QString, QWidget * >(name, e));}

private:
	QMap<const QMetaObject*, QByteArray> metaFunctions(const QSet<QObject*> & objects, QByteArray fname);

	QVector<QPair<QString, QMainWindow * > > mwindows;
	QVector<QPair<QString, QWidget * > > widgets;
	QVector<QPair<QString, QCheckBox * > > checks;
	QVector<QPair<QString, QLineEdit * > > lines;
	QVector<QPair<QString, QComboBox * > > combos;
	QVector<QPair<QString, QDoubleSpinBox * > > dspins;
	QVector<QPair<QString, QSpinBox * > > spins;
	QVector<QPair<QString, SpinSlider * > > spinsliders;
	QVector<QPair<QString, EvalSpinBox * > > evals;
	QVector<QPair<QString, QTabWidget * > > tabs;
	QVector<QPair<QString, QGroupBox * > > groups;
	QVector<QPair<QString, QAbstractButton * > > buttons;
	QVector<QPair<QString, QStackedWidget * > > stacks;
	QVector<QPair<QString, QAction * > > actions;
	QVector<QPair<QString, QStringList * > > stringlists;
	QVector<QPair<QString, QString * > > strings;
	QVector<QPair<QString, QColor * > > colors;
	QVector<QPair<QString, bool * > > bools;
	QVector<QPair<QString, int * > > ints;
	QVector<QPair<QString, float * > > floats;
	QString file_;

public slots:
	void save();
	void load(bool onlyMainwindow = false);
	void clear(bool with_filename = true);

signals:
	void loading(QPIConfig & );
	void saving(QPIConfig & );

};

#endif // SESSION_MANAGER_H
