#ifndef CONFIG_FILE_H
#define CONFIG_FILE_H

#include <qvaluelist.h>
#include <qstring.h>
#include <qrect.h>
#include <qsize.h>
#include <qcolor.h>
#include <qfont.h>
#include <qmap.h>

/**
	Klasa reprezentująca plik z zapisem konfiguracji programu
**/
class ConfigFile {

	private:
		void read();
		void write(const QString &f=QString::null) const;
		bool changeEntry(const QString &group, const QString &name, const QString &value);
		QString getEntry(const QString &group, const QString &name, bool *ok = 0) const;

		QString filename;
		QMap<QString, QMap<QString, QString> > groups;
		mutable QString activeGroupName;
		mutable QMap<QString, QString> *activeGroup;

	public:
		/**
			Otwiera plik filename i go wczytuje
		**/
		ConfigFile(const QString &filename);
		
		/**
			Zapisuje na dysk zawartość konfiguracji
		**/
		void sync() const;
		
		/**
			Zapisuje do wybranego pliku kopię konfiguracji
		**/
		void saveTo(const QString &filename) const;
		
		/**
			Zwraca całą sekcję "name"
		**/
		QMap<QString, QString>& getGroupSection(const QString& name);
		
		/**
			Zwraca listę sekcji
		**/
		QStringList getGroupList() const;
		/**
			Zapisuje wartość "value" do grupy "group" w pole "name"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QString do wpisania
		**/
		void writeEntry(const QString &group,const QString &name, const QString &value);
		/**
			Zapisuje wartość "value" do grupy "group" w pole "name"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość char* do wpisania
		**/
		void writeEntry(const QString &group,const QString &name, const char *value);
		/**
			Zapisuje wartość "value" do grupy "group" w pole "name"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość int do wpisania
		**/
		void writeEntry(const QString &group,const QString &name, const int value);
		/**
			Zapisuje wartość "value" do grupy "group" w pole "name"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość double do wpisania
		**/
		void writeEntry(const QString &group,const QString &name, const double value);
		/**
			Zapisuje wartość "value" do grupy "group" w pole "name"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość bool do wpisania
		**/
		void writeEntry(const QString &group,const QString &name, const bool value);
		/**
			Zapisuje wartość "value" do grupy "group" w pole "name"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QRect do wpisania
		**/
		void writeEntry(const QString &group,const QString &name, const QRect &value);
		/**
			Zapisuje wartość "value" do grupy "group" w pole "name"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QSize do wpisania
		**/
		void writeEntry(const QString &group,const QString &name, const QSize &value);
		/**
			Zapisuje wartość "value" do grupy "group" w pole "name"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QColor do wpisania
		**/
		void writeEntry(const QString &group,const QString &name, const QColor &value);
		/**
			Zapisuje wartość "value" do grupy "group" w pole "name"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QFont do wpisania
		**/
		void writeEntry(const QString &group,const QString &name, const QFont &value);
		/**
			Zapisuje wartość "value" do grupy "group" w pole "name"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QPoint do wpisania
		**/
		void writeEntry(const QString &group,const QString &name, const QPoint &value);
		/**
			Zwraca wartość pola "name" z grupy "group"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param def domyślna wartość pola
			@return wartość danego pola, jeśli nie istnieje zwracana
			jest wartość "def"
		**/
		QString readEntry(const QString &group,const QString &name, const QString &def = QString::null) const;
		/**
			Zwraca wartość pola "name" z grupy "group"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param def domyślna wartość pola
			@return wartość danego pola, jeśli nie istnieje zwracana
			jest wartość "def"
		**/
		int readNumEntry(const QString &group,const QString &name, int def = 0) const;
		/**
			Zwraca wartość pola "name" z grupy "group"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param def domyślna wartość pola
			@return wartość danego pola, jeśli nie istnieje zwracana
			jest wartość "def"
		**/
		unsigned int readUnsignedNumEntry(const QString &group,const QString &name, unsigned int def = 0) const;
		/**
			Zwraca wartość pola "name" z grupy "group"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param def domyślna wartość pola
			@return wartość danego pola, jeśli nie istnieje zwracana
			jest wartość "def"
		**/
		double readDoubleNumEntry(const QString &group,const QString &name, double def = 0.0) const;
		/**
			Zwraca wartość pola "name" z grupy "group"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param def domyślna wartość pola
			@return wartość danego pola, jeśli nie istnieje zwracana
			jest wartość "def"
		**/
		bool readBoolEntry(const QString &group,const QString &name, bool def = false) const;
		/**
			Zwraca wartość pola "name" z grupy "group"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param def domyślna wartość pola
			@return wartość danego pola, jeśli nie istnieje zwracana
			jest wartość "def"
		**/
		QRect readRectEntry(const QString &group,const QString &name, const QRect *def = 0L) const;
		/**
			Zwraca wartość pola "name" z grupy "group"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param def domyślna wartość pola
			@return wartość danego pola, jeśli nie istnieje zwracana
			jest wartość "def"
		**/
		QSize readSizeEntry(const QString &group,const QString &name, const QSize *def = 0L) const;
		/**
			Zwraca wartość pola "name" z grupy "group"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param def domyślna wartość pola
			@return wartość danego pola, jeśli nie istnieje zwracana
			jest wartość "def"
		**/
		QColor readColorEntry(const QString &group,const QString &name, const QColor *def = 0L) const;
		/**
			Zwraca wartość pola "name" z grupy "group"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param def domyślna wartość pola
			@return wartość danego pola, jeśli nie istnieje zwracana
			jest wartość "def"
		**/
		QFont readFontEntry(const QString &group,const QString &name, const QFont *def = 0L) const;
		/**
			Zwraca wartość pola "name" z grupy "group"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param def domyślna wartość pola
			@return wartość danego pola, jeśli nie istnieje zwracana
			jest wartość "def"
		**/
		QPoint readPointEntry(const QString &group,const QString &name, const QPoint *def = 0L) const;
		/**
			Tworzy pole "name" w grupie "group" jeśli ono nie istnieje
			i ustawia wartość na "value"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QPoint do wpisania
		**/
		void addVariable(const QString &group,const QString &name, const QString &value);
		/**
			Tworzy pole "name" w grupie "group" jeśli ono nie istnieje
			i ustawia wartość na "value"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QPoint do wpisania
		**/
		void addVariable(const QString &group,const QString &name, const char *value);
		/**
			Tworzy pole "name" w grupie "group" jeśli ono nie istnieje
			i ustawia wartość na "value"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QPoint do wpisania
		**/
		void addVariable(const QString &group,const QString &name, const int value);
		/**
			Tworzy pole "name" w grupie "group" jeśli ono nie istnieje
			i ustawia wartość na "value"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QPoint do wpisania
		**/
		void addVariable(const QString &group,const QString &name, const double value);
		/**
			Tworzy pole "name" w grupie "group" jeśli ono nie istnieje
			i ustawia wartość na "value"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QPoint do wpisania
		**/
		void addVariable(const QString &group,const QString &name, const bool value);
		/**
			Tworzy pole "name" w grupie "group" jeśli ono nie istnieje
			i ustawia wartość na "value"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QPoint do wpisania
		**/
		void addVariable(const QString &group,const QString &name, const QRect &value);
		/**
			Tworzy pole "name" w grupie "group" jeśli ono nie istnieje
			i ustawia wartość na "value"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QPoint do wpisania
		**/
		void addVariable(const QString &group,const QString &name, const QSize &value);
		/**
			Tworzy pole "name" w grupie "group" jeśli ono nie istnieje
			i ustawia wartość na "value"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QPoint do wpisania
		**/
		void addVariable(const QString &group,const QString &name, const QColor &value);
		/**
			Tworzy pole "name" w grupie "group" jeśli ono nie istnieje
			i ustawia wartość na "value"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QPoint do wpisania
		**/
		void addVariable(const QString &group,const QString &name, const QFont &value);
		/**
			Tworzy pole "name" w grupie "group" jeśli ono nie istnieje
			i ustawia wartość na "value"
			@param group nazwa grupy
			@param name nazwa pola w grupie
			@param value wartość QPoint do wpisania
		**/
		void addVariable(const QString &group,const QString &name, const QPoint &value);
};

//TODO: po wydaniu 0.4 trzeba zmienić nazwę na config_file i wywalić define'a
extern ConfigFile *config_file_ptr;
#define config_file (*config_file_ptr)

#endif
