
//  Copyright (C) 2009 by Arnaud Dupuis
//  a.dupuis@infinityperl.org
//  http://www.infinityperl.org
// 
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU 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 General Public License for more details.
// 
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the
//  Free Software Foundation, Inc.,
//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA

#ifndef ASSUMA_CONFIGMANAGER_H
#define ASSUMA_CONFIGMANAGER_H

#include <QtCore/QObject>
#include <QtCore/QMap>
#include <QtCore/QVariant>
#include <QtCore/QString>
#include <QtCore/QMutex>

#define AssumaCM AssumaConfigManager::instance()
#define ConfigManager AssumaConfigManager::instance()

/*! \class AssumaConfigManager
* \brief The configuration manager of the application.
*
* This class is the configuration manager used by Association Subscribers Manager.
* This is the class you have to use if you need to access to the configuration of the application.
* This class make a difference between internal configuration tokens (called here "configuration token") and external configuration tokens (called "external configuration token").
* Indeed they are not processed the same way and they do not belong to the same configuration group. This allows addons coder to use whatever config variables name and ensuring it will not conflict with Association Subscribers Manager's internal settings.
*
*Please note that this class is thread safe.
*
* \attention At the moment this configuration manager do not load the configuration file directly. This task is still devoted to the main window, but this might change in the futur.
*
*/

//! \warning This class is a Singleton one, you cannot instanciate it, use the getInstance() function to have the unique instance of AssumaConfigManager. You also can access to this configuration  manager by using the 2 defined macros : ConfigManager and AssumaCM.

class AssumaConfigManager : public QObject {
	Q_OBJECT
	public:
		
		enum Severity {
			Info,
			Critical,
			Warning
		};
		//! Configuration token enumeration.
		/*! This enum contains all configuration tokens.
		* Configuration tokens are used with the getConfigToken() and setConfigToken() functions.
		* \sa setConfigToken getConfigToken
		*/
		enum Token {
			TrimesterCount = 1,
			StaticCost = 2,
			Federation = 3,
			UpdateServer = 4,
			UpdatesOnStart = 5,
			Currency = 6,
			CurrenciesList = 7,
			ContactsList = 8,
			CoursesList = 9,
   			Language = 10,
			Encoding = 11,
			AssociationName = 12,
			Email = 13,
			SmtpServer = 14,
			SmtpLogin = 15,
			SmtpPassword = 16,
	 		ProxyServer = 17,
			ProxyLogin = 18,
			ProxyPassword = 19,
			ProxyEnabled = 20,
			DataDir = 21,
			FederationList = 22,
			LanguageList = 23,
			Country = 24,
			ActivatedAddonList = 25,
			Theme = 26,
			MainWindowLastDatabase = 27,
			MainWindowGeometry = 28,
			MainWindowSplitterGeometry = 29,
			UserDefinedAvatars = 30,
		};
		/*!
		Returns the single instance of AssumaConfigManager. Create one if needed.
		*/
		static AssumaConfigManager *instance();
		/*!
		Returns a configuration token as a QVariant.
		\param token the token identifying the desired value.
		\return data as a QVariant.
		*/
		QVariant getConfigToken(Token);
		/*!
		Returns a configuration token as a QVariant.
		\param token the token identifying the desired value. \sa setExternalConfigToken
		\return data as a QVariant.
		*/
		QVariant getExternalConfigToken(const QString &);
		/*!
		Tmp tokens are just temporaly store, they are not saved on hard drive. Most of the time they are used only to exchange data-to-be-processed between different parts of the application.
		Returns a configuration token as a QVariant.
		\param token the token identifying the desired value. \sa setTmpConfigToken
		\return data as a QVariant.
		*/
		QVariant getTmpConfigToken(const QString &);
	signals:
		/*!
		This signal is emitted whenever a configuration token have been updated.
		*/
		void configurationTokenChanged( AssumaConfigManager::Token, const QVariant & );
		/*!
		This signal is emitted whenever an external configuration token have been updated.
		*/
		void externalConfigurationTokenChanged( const QString & , const QVariant & );
		/*!
		This signal is emitted whenever a tmp configuration token have been updated.
		*/
		void tmpConfigurationTokenChanged( const QString & , const QVariant & );
	public slots:
		/*!
		Set the value of a configuration token.
		\param token \sa Token
		\param data data to store
		*/
		void setConfigToken( Token, const QVariant & );
		/*!
		Set the value of a configuration token.
		\param token the key name. \note External tokens are only accessible with the (s|g)etExternalConfigToken
		\param data data to store
		*/
		void setExternalConfigToken( const QString &, const QVariant & );
		/*!
		Set the value of a configuration token.
		\param token the key name. \note Tmp tokens are only accessible with the (s|g)etTmpConfigToken
		\param data data to store
		*/
		void setTmpConfigToken( const QString &, const QVariant & );
		
	private:
		// Functions
		AssumaConfigManager();
		QString tokenToString( Token );
		// Members variables
		static AssumaConfigManager *m_singleInstance;
		QMap<QString,QVariant>m_configuration;
		QMutex m_mutex;
};

#endif
