/*
    QAD - Qt ADvanced

    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 SESSION_MANAGER_H
#define SESSION_MANAGER_H

#include "evalspinbox.h"
#include "qad_widgets_export.h"
#include "qpiconfig.h"
#include "spinslider.h"

#include <QAction>
#include <QCheckBox>
#include <QComboBox>
#include <QDoubleSpinBox>
#include <QGroupBox>
#include <QLineEdit>
#include <QMainWindow>
#include <QPair>
#include <QSplitter>
#include <QStackedWidget>
#include <QTabWidget>
#include <QToolButton>


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


class QAD_WIDGETS_EXPORT SessionManager: public QObject {
	Q_OBJECT

public:
	SessionManager(QString file = QString());

	void setFile(const QString & file);

	void addEntry(QMainWindow * e) { addEntry(e->objectName(), e); }
	void addEntry(QCheckBox * e) { addEntry(e->objectName(), e); }
	void addEntry(QLineEdit * e) { addEntry(e->objectName(), e); }
	void addEntry(QComboBox * e) { addEntry(e->objectName(), e); }
	void addEntry(QDoubleSpinBox * e) { addEntry(e->objectName(), e); }
	void addEntry(QSpinBox * e) { addEntry(e->objectName(), e); }
	void addEntry(SpinSlider * e) { addEntry(e->objectName(), e); }
	void addEntry(EvalSpinBox * e) { addEntry(e->objectName(), e); }
	void addEntry(QTabWidget * e) { addEntry(e->objectName(), e); }
	void addEntry(QGroupBox * e) { addEntry(e->objectName(), e); }
	void addEntry(QAction * e) { addEntry(e->objectName(), e); }
	void addEntry(QAbstractButton * e) { addEntry(e->objectName(), e); }
	void addEntry(QStackedWidget * e) { addEntry(e->objectName(), e); }
	void addEntry(QSlider * e) { addEntry(e->objectName(), e); }
	void addMainWidget(QWidget * e) { addMainWidget(e->objectName(), e); }
	void removeMainWidget(QWidget * e);

	void addEntry(const QString & name, QMainWindow * 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, QSlider * e) { sliders.push_back(QPair<QString, QSlider *>(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, QSlider *>> sliders;
	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;
	QMap<QMainWindow *, QList<QSplitter *>> mw_splitters;
	QString file_;

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

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

#endif // SESSION_MANAGER_H
