/*
    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) 2012  Benjamin Mesing <email>

    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, see <http://www.gnu.org/licenses/>.
*/


#ifndef __NETWORKSETTINGS_H_2012_01_31
#define __NETWORKSETTINGS_H_2012_01_31

#include <string>

#include <QNetworkProxy>
#include <QNetworkAccessManager>

#include "ixmlstorable.h"


using namespace std;

namespace NUtil {

/**
 * @Brief Stores the proxy network settings.
 * 
 * Different types of proxies can be configured:
 * <ol>
 * 	<li>NO_PROXY: speaks for itself</li>
 * 	<li>SYSTEM_PROXY: use the system configuration (this will access the value of the http_proxy 
 * 	variable)</li>
 * 	<li>CUSTOM_PROXY: use a custom proxy configuration</li>
 * </ol>
 * 
 * 
 * 
 */
class NetworkSettings : public NXml::IXmlStorable
{
public:
	enum ProxyType {
		NO_PROXY = 0,
		SYSTEM_PROXY,
		CUSTOM_PROXY
	};
private:
	ProxyType _proxyType;
	string _host;
	int _port;
	bool _useProxy;
	/** @brief The QNetworkManager.
	  *
	  * Should be configured for local network connection.
	  */
	QNetworkAccessManager* _pNetwork;

	QNetworkProxy _qNetworkProxy;
public:
	NetworkSettings();
	
	/** Returns true if a proxy shall be used.
	 *
	 * <ul>
	 * <li>if type() == NO_PROXY returns false</li>
	 * <li>if type() == SYSTEM_PROXY returns true if a system proxy was configured, else false
	 * <li>if type() == CUSTOM_PROXY returns true</li>
	 * </ul>	 
	 */
	bool useProxy() const { return _useProxy; };	
	/** Initialises the network settings. 
	 * 
	 * If (type == SYSTEM_PROXY), host and port will be ignored and 
	 * loadSystemProxy() will be called instead.
	 */
	NetworkSettings(ProxyType type, string host="", int port=-1);
	
	~NetworkSettings();
	/** Returns the current proxy typ. */
	ProxyType proxyType() const { return _proxyType; }
	/** Returns the host, or an empty string if no host is configured. */
	string host() const { return _host; }
	/** Returns the port, or -1 if no port is configured. */
	int port() const { return _port; }

	/** @brief Returns the network manager corresponding to this configuration. */
	QNetworkAccessManager* network();
	
	
	/** @name IXmlStorable interface
	  * 
	  * Implementation of the IXmlStorable interface.
	  * 
	  * Both functions do nothing in the default implementation.
	  */
	//@{
	/** @brief 	Save the data for this object into the given XML tree.
	  *
	  * The implementation for this creates a new element beneath parent with the
	  * name "network". All attributes are stored below this node.
	  *
	  * @see IXmlStorable::saveSettings() for details how to save.
	  */
	virtual void saveSettings(NXml::XmlData& outData, QDomElement parent) const;
	/** @brief Loads the data for this object from the given XML node.
	  *
	  * @see IXmlStorable::loadSettings() on the loading process.
	  */
	virtual QDomElement loadSettings(const QDomElement source);
	//@}};
protected:
	/**
	 * Sets the proxy type.
	 * 
	 * If CUSTOM_PROXY or NO_PROXY are handed, _host and _port remain untouched.
	 * If SYSTEM_PROXY is handed <em>and </em> a system proxy is configured, _host
	 * and _port will be set to the values of the system proxy.
	 * 
	 * Also updates the QNetworkProxy for the QNetworkAccessManager.
	 */
	void setProxyType(ProxyType type);
	
	/** Updates the internal QNetworkProxy configuration. */
	void updateQProxy();

	/** Loads the system proxy from the environment variable. 
	 *
	 * Modifies _host and _port if a system proxy is configured.
	 * 
	 * @returns true if a system proxy is available (i.e. http_proxy is set) else false;
	 */
	bool loadSystemProxy();
	
};


}	// NUtil

#endif // __NETWORKSETTINGS_H_2012_01_31
