//
// C++ Interface: MerkaartorPreferences
//
// Description:
//
//
// Author: cbro <cbro@semperpax.com>, bvh, (C) 2008
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef MERKAARTORPREFERENCES_H
#define MERKAARTORPREFERENCES_H

#include <QtCore>
#include <QtCore/QSettings>
#include <QColor>
#include <QHttp>
#include <QBuffer>

#include "Map/Coord.h"

class MainWindow;
class MapView;

//#define WORLD_COORDBOX CoordBox(Coord(1.3, -1.3), Coord(-1.3, 1.3))
#define WORLD_COORDBOX CoordBox(Coord(INT_MAX/2, -INT_MAX/2), Coord(-INT_MAX/2, INT_MAX/2))
#define BUILTIN_STYLES_DIR ":/Styles"
#define BUILTIN_TEMPLATES_DIR ":/Templates"
#define M_PREFS MerkaartorPreferences::instance()

#define M_PARAM_DECLARE_BOOL(Param) \
	private: \
		bool m_##Param; \
	public: \
		void set##Param(bool theValue); \
		bool get##Param(); 
#define M_PARAM_DECLARE_STRING(Param) \
	private: \
		QString m_##Param; \
	public: \
		void set##Param(QString theValue); \
		QString get##Param(); 
#define M_PARAM_DECLARE_INT(Param) \
	private: \
		int m_##Param; \
	public: \
		void set##Param(int theValue); \
		int get##Param(); 
#define M_PARAM_DECLARE_DOUBLE(Param) \
	private: \
		double m_##Param; \
	public: \
		void set##Param(double theValue); \
		double get##Param(); 

#define SAFE_DELETE(x) {delete (x); x = NULL;}

/**
	@author cbro <cbro@semperpax.com>
*/

enum ImageBackgroundType {
	Bg_None,
	Bg_Wms,
 	Bg_Tms
#ifdef USE_GDAL
	, Bg_Shp
#endif
#ifdef YAHOO
 	, Bg_Yahoo
#endif
#ifdef YAHOO_ILLEGAL
	, Bg_Yahoo_illegal
#endif
#ifdef GOOGLE_ILLEGAL
	, Bg_Google_illegal
#endif
#ifdef MSLIVEMAP_ILLEGAL
	, Bg_MsVirtualEarth_illegal
#endif
};

#ifndef USE_PROJ
enum ProjectionType {
 	Proj_Background,
	Proj_Merkaartor
};
#else
typedef QString ProjectionType;
#endif

enum ExportType {
	Export_All,
	Export_Viewport,
	Export_Selected
};

enum DirectionalArrowsShow {
	DirectionalArrows_Never,
	DirectionalArrows_Oneway,
	DirectionalArrows_Always
};

typedef QMap<QString, CoordBox> BookmarkList;
typedef QMapIterator<QString, CoordBox> BookmarkListIterator;

class WmsServer
{
	public:
		WmsServer();
		WmsServer(QString Name, QString Adress, QString Path, QString Layers, QString Projections, QString Styles, QString ImgFormat);

	public:
		QString WmsName;
		QString WmsAdress;
		QString WmsPath;
		QString WmsLayers;
		QString WmsProjections;
		QString WmsStyles;
		QString WmsImgFormat;
};
typedef QMap<QString, WmsServer> WmsServerList;
typedef QMapIterator<QString, WmsServer> WmsServerListIterator;

class TmsServer
{
	public:
		TmsServer();
		TmsServer(QString Name, QString Adress, QString Path, int tileSize, int minZoom, int maxZoom);

	public:
		QString TmsName;
		QString TmsAdress;
		QString TmsPath;
		int TmsTileSize;
		int TmsMinZoom;
		int TmsMaxZoom;
};
typedef QMap<QString, TmsServer> TmsServerList;
typedef QMapIterator<QString, TmsServer> TmsServerListIterator;

#define TOOL_FIELD_SIZE 2
class Tool
{
	public:
		Tool();
		Tool(QString Name, QString Path);

	public:
		QString ToolName;
		QString ToolPath;
};
typedef QMap<QString, Tool> ToolList;
typedef QMapIterator<QString, Tool> ToolListIterator;


// Outside of merkaartorpreferences, because initializing it will need translations
// Classic chicken & egg problem.
QString getDefaultLanguage();
void setDefaultLanguage(const QString& L);

class MerkaartorPreferences : public QObject
{
Q_OBJECT
public:
	MerkaartorPreferences();
	~MerkaartorPreferences();

	static MerkaartorPreferences* instance() {
		if (!m_prefInstance) {
			m_prefInstance = new MerkaartorPreferences;
		}

		return m_prefInstance;
	}

	void save();

	void toOsmPref();
	void fromOsmPref();
	void putOsmPref(const QString& k, const QString& v);
	void deleteOsmPref(const QString& k);

	//bool use06Api() const;
	void setUse06Api(bool b);
	const QString apiVersion() const;
	double apiVersionNum() const;

	void setRightSideDriving(bool theValue);
	bool getRightSideDriving() const;

	void setDoubleRoadDistance(double theValue);
	double getDoubleRoadDistance() const;

	void setWorkingDir(const QString & theValue);
	QString getWorkingDir() const;

	void setProxyUse(bool theValue);
	bool getProxyUse() const;

	void setProxyHost(const QString & theValue);
	QString getProxyHost() const;
	void setProxyPort(int theValue);
	int getProxyPort() const;

	void setBookmarks();
	BookmarkList&  getBookmarks();

	void setSelectedWmsServer(const QString & theValue);
	QString getSelectedWmsServer() const;
	WmsServerList& getWmsServers();

	void setSelectedTmsServer(const QString & theValue);
	QString getSelectedTmsServer() const;
	TmsServerList& getTmsServers();

	void setBgVisible(bool theValue);
	bool getBgVisible() const;

	void setBgType(ImageBackgroundType theValue);
	ImageBackgroundType getBgType() const;
	QStringList getBgTypes();

	/* Tile Cache */
	void setCacheDir(const QString & theValue);
	QString getCacheDir() const;
	void setCacheSize(int theValue);
	int getCacheSize() const;

	/* Search */
	void setLastMaxSearchResults(int theValue);
	int getLastMaxSearchResults() const;
	void setLastSearchName(const QString & theValue);
	QString getLastSearchName() const;
	void setLastSearchKey(const QString & theValue);
	QString getLastSearchKey() const;
	void setLastSearchValue(const QString & theValue);
	QString getLastSearchValue() const;

	/* Visual */
	void setZoomInPerc(int theValue);
	int getZoomInPerc() const;
	void setZoomOutPerc(int theValue);
	int getZoomOutPerc() const;

	void setProjectionType(ProjectionType theValue);
	ProjectionType getProjectionType() const;
	QStringList getProjectionTypes();

	QStringList getAlphaList() const;
	void setAlphaList();
	qreal getAlpha(QString lvl);
	QHash<QString, qreal>* getAlphaPtr();

	QColor getBgColor() const;
	void setBgColor(const QColor theValue);
	QColor getWaterColor() const;
	void setWaterColor(const QColor theValue);
	QColor getFocusColor() const;
	int getFocusWidth() const;
	void setFocusColor(const QColor theValue, int width);
	QColor getHoverColor() const;
	int getHoverWidth() const;
	void setHoverColor(const QColor theValue, int width);
	QColor getRelationsColor() const;
	int getRelationsWidth() const;
	void setRelationsColor(const QColor theValue, int width);

	void setDownloadedVisible(bool theValue);
	bool getDownloadedVisible() const;

	void setScaleVisible(bool theValue);
	bool getScaleVisible() const;

	bool getStyleBackgroundVisible() const;
	void setStyleBackgroundVisible(bool theValue);
	bool getStyleForegroundVisible() const;
	void setStyleForegroundVisible(bool theValue);
	bool getStyleTouchupVisible() const;
	void setStyleTouchupVisible(bool theValue);
	void setNamesVisible(bool theValue);
	bool getNamesVisible() const;

	DirectionalArrowsShow getDirectionalArrowsVisible();
	void setDirectionalArrowsVisible(DirectionalArrowsShow theValue);

	void setTrackPointsVisible(bool theValue);
	bool getTrackPointsVisible() const;

	void setTrackSegmentsVisible(bool theValue);
	bool getTrackSegmentsVisible() const;

	void setRelationsVisible(bool theValue);
	bool getRelationsVisible() const;

    M_PARAM_DECLARE_INT(TagListFirstColumnWidth)

	/* MainWindow state */
	void saveMainWindowState(const class MainWindow * mainWindow);
	void restoreMainWindowState(class MainWindow * mainWindow) const;

	void setInitialPosition(MapView* vw);
	void initialPosition(MapView* vw);

	bool getDrawTileBoundary();

	/* Data */
	void setOsmWebsite(const QString & theValue);
	QString getOsmWebsite() const;

	M_PARAM_DECLARE_STRING(XapiWebSite)
	M_PARAM_DECLARE_BOOL(AutoHistoryCleanup)

	void setOsmUser(const QString & theValue);
	QString getOsmUser() const;

	void setOsmPassword(const QString & theValue);
	QString getOsmPassword() const;

	void setGpsPort(const QString & theValue);
	QString getGpsPort() const;

	M_PARAM_DECLARE_DOUBLE(MaxDistNodes)

	void setAutoSaveDoc(bool theValue);
	bool getAutoSaveDoc() const;

	void setAutoExtractTracks(bool theValue);
	bool getAutoExtractTracks() const;

	/* Export Type */
	void setExportType(ExportType theValue);
	ExportType getExportType() const;

	/* Tools */
	ToolList* getTools() const;
	Tool getTool(QString toolName) const;

	QStringList getShortcuts() const;
	void setShortcuts(const QStringList & theValue);

	/* Recent */
	void setRecentOpen(const QStringList & theValue);
	QStringList getRecentOpen() const;
	void addRecentOpen(const QString & theValue);

	void setRecentImport(const QStringList & theValue);
	QStringList getRecentImport() const;
	void addRecentImport(const QString & theValue);

	/* Styles */
	M_PARAM_DECLARE_STRING(DefaultStyle)
	M_PARAM_DECLARE_STRING(CustomStyle)
	M_PARAM_DECLARE_BOOL(DisableStyleForTracks)

	/* Visual */
	M_PARAM_DECLARE_BOOL(BackgroundOverwriteStyle)
	M_PARAM_DECLARE_INT(AreaOpacity)
	M_PARAM_DECLARE_BOOL(UseShapefileForBackground)
	M_PARAM_DECLARE_BOOL(DrawingHack)

	/* Templates */
	M_PARAM_DECLARE_STRING(DefaultTemplate)
	M_PARAM_DECLARE_STRING(CustomTemplate)

	M_PARAM_DECLARE_BOOL(GpsSaveLog)
	M_PARAM_DECLARE_BOOL(GpsMapCenter)
	M_PARAM_DECLARE_STRING(GpsLogDir)
	M_PARAM_DECLARE_BOOL(GpsSyncTime)

	M_PARAM_DECLARE_BOOL(ResolveRelations)
	M_PARAM_DECLARE_BOOL(DeleteIncompleteRelations)

	M_PARAM_DECLARE_BOOL(TranslateTags)

	M_PARAM_DECLARE_BOOL(MapTooltip)
	M_PARAM_DECLARE_BOOL(InfoOnHover)
	M_PARAM_DECLARE_BOOL(ShowParents)

	/* World OSB manager */
	M_PARAM_DECLARE_DOUBLE(TileToRegionThreshold)

	M_PARAM_DECLARE_STRING(WorldOsbUri)
	M_PARAM_DECLARE_BOOL(WorldOsbAutoload)
	M_PARAM_DECLARE_BOOL(WorldOsbAutoshow)

	/* Mouse bevaviour */
	M_PARAM_DECLARE_BOOL(MouseSingleButton)
	M_PARAM_DECLARE_BOOL(SeparateMoveMode)
		
	/* Custom Style */
	M_PARAM_DECLARE_BOOL(MerkaartorStyle)

	/* Network */
	M_PARAM_DECLARE_BOOL(OfflineMode)

	/* Track */
	M_PARAM_DECLARE_BOOL(ReadonlyTracksDefault)

protected:
	bool Use06Api;
	QString version;
	bool RightSideDriving;
	double DoubleRoadDistance;
	QString WorkingDir;
	QString OsmWebsite;
	QString OsmUser;
	QString OsmPassword;
	bool ProxyUse;
	QString ProxyHost;
	int ProxyPort;
	QStringList Bookmarks;

	QHttp httpRequest;
	int OsmPrefLoadId;
	int OsmPrefSaveId;
	int OsmPrefDeleteId;
	QBuffer OsmPrefContent;
	QMap<QString, int> OsmPrefListsCount;

	void setWmsServers();
	void setTmsServers();
	void setTools();
	void initialize();

private:
	QHash<QString, qreal> alpha;
	BookmarkList theBookmarks;
	WmsServerList theWmsServerList;
	TmsServerList theTmsServerList;
	ToolList* theToolList;
	QSettings * Sets;
	QStringList bgTypes;
	QStringList projTypes;
	static MerkaartorPreferences* m_prefInstance;

private slots:
	void on_responseHeaderReceived(const QHttpResponseHeader & hdr);
	void on_requestFinished ( int id, bool error );

signals:
	void bookmarkChanged();
};

#endif
