/***************************************************************************
 *   Copyright (C) 2008,2010 by Volker Lanz <vl@fidra.de>                  *
 *                                                                         *
 *   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 2 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.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
 ***************************************************************************/

#include "veneer/settings.h"

#include <QSettings>
#include <QCoreApplication>
#include <QDebug>
#include <QStringList>
#include <QApplication>
#include <QDesktopWidget>
#include <QDialog>

static void writeArray(QSettings* qs, const QString& name, QList<int> v)
{
	qs->beginWriteArray(name);

	for (int i = 0; i < v.size(); i++)
	{
		qs->setArrayIndex(i);
		qs->setValue("v", v[i]);
	}

	qs->endArray();
}

static QList<int> readArray(QSettings* qs, const QString& name)
{
	QList<int> result;

	int size = qs->beginReadArray(name);

	for (int i = 0; i < size; i++)
	{
		qs->setArrayIndex(i);
		result.append(qs->value("v").toInt());
	}

	qs->endArray();

	return result;
}

namespace Veneer
{

	Settings* Veneer::Settings::self()
	{
		static Settings* self_ = NULL;

		if (self_ == NULL)
			self_ = new Settings();

		return self_;
	}

	Settings::Settings() :
		m_QSettings(new QSettings(QCoreApplication::organizationName(), QCoreApplication::applicationName().toLower()))
	{
		qs()->setDefaultFormat(QSettings::IniFormat);
	}

	void Settings::writeConfig()
	{
		qs()->sync();
	}

	void Settings::setShowStatusbar(bool v)
	{
		qs()->setValue("showStatusbar", v);
	}

	bool Settings::showStatusbar() const
	{
		return qs()->value("showStatusbar", true).toBool();
	}

	void Settings::setEnergyUnit(int v)
	{
		qs()->setValue("energyUnit", v);
	}

	int Settings::energyUnit() const
	{
		return qs()->value("energyUnit", EnumEnergyUnit::kJoule).toInt();
	}

	void Settings::setHeightCalcThreshold(int v)
	{
		qs()->setValue("heightCalcThreshold", v);
	}

	int Settings::heightCalcThreshold() const
	{
		return qs()->value("heightCalcThreshold", 20).toInt();
	}

	void Settings::setActivitiesTreeColumnWidths(const QList<int>& v)
	{
		writeArray(qs(), "activitiesTreeColumnWidths", v);
	}

	QList<int> Settings::activitiesTreeColumnWidths() const
	{
		if (qs()->childGroups().indexOf("activitiesTreeColumnWidths") == -1)
			return QList<int>() << 120 << 180 << 80 << 80 << 80 << 80 << 80 << 80 << 80 << 80 << 80 << 80 << 80;

		return readArray(qs(), "activitiesTreeColumnWidths");
	}

	void Settings::setActivitiesTreeColumnPositions(const QList<int>& v)
	{
		writeArray(qs(), "activitiesTreeColumnPositions", v);
	}

	QList<int> Settings::activitiesTreeColumnPositions() const
	{
		if (qs()->childGroups().indexOf("activitiesTreeColumnPositions") == -1)
			return QList<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12;

		return readArray(qs(), "activitiesTreeColumnPositions");
	}

	void Settings::setActivitiesTreeColumnVisible(const QList<int>& v)
	{
		writeArray(qs(), "activitiesTreeColumnVisible", v);
	}

	QList<int> Settings::activitiesTreeColumnVisible() const
	{
		if (qs()->childGroups().indexOf("activitiesTreeColumnVisible") == -1)
			return QList<int>() << 1 << 1 << 1 << 1 << 0 << 1 << 1 << 0 << 0 << 0 << 0 << 0 << 0;

		return readArray(qs(), "activitiesTreeColumnVisible");
	}

	void Settings::setLastProfile(const QString& v)
	{
		qs()->setValue("lastProfile", v);
	}

	QString Settings::lastProfile() const
	{
		return qs()->value("lastProfile", QString()).toString();
	}

	void Settings::setActivityPageSplitterSizes(const QList<int>& v)
	{
		writeArray(qs(), "activityPageSplitterSizes", v);
	}

	QList<int> Settings::activityPageSplitterSizes() const
	{
		if (qs()->childGroups().indexOf("activityPageSplitterSizes") == -1)
			return QList<int>() << 180 << 240;

		return readArray(qs(), "activityPageSplitterSizes");
	}

	void Settings::setAthleteLogTreeColumnWidths(const QList<int>& v)
	{
		writeArray(qs(), "athleteLogTreeColumnWidths", v);
	}

	QList<int> Settings::athleteLogTreeColumnWidths() const
	{
		if (qs()->childGroups().indexOf("athleteLogTreeColumnWidths") == -1)
			return QList<int>() << 110 << 90 << 80 << 80 << 100 << 100 << 160 << 80 << 110;

		return readArray(qs(), "athleteLogTreeColumnWidths");
	}

	void Settings::setAthleteLogTreeColumnPositions(const QList<int>& v)
	{
		writeArray(qs(), "athleteLogTreeColumnPositions", v);
	}

	QList<int> Settings::athleteLogTreeColumnPositions() const
	{
		if (qs()->childGroups().indexOf("athleteLogTreeColumnPositions") == -1)
			return QList<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8;

		return readArray(qs(), "athleteLogTreeColumnPositions");
	}

	void Settings::setAthleteLogTreeColumnVisible(const QList<int>& v)
	{
		writeArray(qs(), "athleteLogTreeColumnVisible", v);
	}

	QList<int> Settings::athleteLogTreeColumnVisible() const
	{
		if (qs()->childGroups().indexOf("athleteLogTreeColumnVisible") == -1)
			return QList<int>() << 1 << 1 << 0 << 1 << 1 << 0 << 1 << 0 << 1;

		return readArray(qs(), "athleteLogTreeColumnVisible");
	}

	void Settings::setAthleteLogPageSplitterSizes(const QList<int>& v)
	{
		writeArray(qs(), "athleteLogPageSplitterSizes", v);
	}

	QList<int> Settings::athleteLogPageSplitterSizes() const
	{
		if (qs()->childGroups().indexOf("athleteLogPageSplitterSizes") == -1)
			return QList<int>() << 200 << 200;

		return readArray(qs(), "athleteLogPageSplitterSizes");
	}

	void Settings::setImportTreeColumnWidths(const QList<int>& v)
	{
		writeArray(qs(), "importTreeColumnWidths", v);
	}

	QList<int> Settings::importTreeColumnWidths() const
	{
		if (qs()->childGroups().indexOf("importTreeColumnWidths") == -1)
			return QList<int>() << 70 << 140 << 140 << 100 << 100 << 100 << 100;

		return readArray(qs(), "importTreeColumnWidths");
	}

	void Settings::setImportTreeColumnPositions(const QList<int>& v)
	{
		writeArray(qs(), "importTreeColumnPositions", v);
	}

	QList<int> Settings::importTreeColumnPositions() const
	{
		if (qs()->childGroups().indexOf("importTreeColumnPositions") == -1)
			return QList<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6;

		return readArray(qs(), "importTreeColumnPositions");
	}

	void Settings::setImportTreeColumnVisible(const QList<int>& v)
	{
		writeArray(qs(), "importTreeColumnVisible", v);
	}

	QList<int> Settings::importTreeColumnVisible() const
	{
		if (qs()->childGroups().indexOf("importTreeColumnVisible") == -1)
			return QList<int>() << 1 << 1 << 1 << 1 << 1 << 1 << 1;

		return readArray(qs(), "importTreeColumnVisible");
	}

	void Settings::setAutoCenterCheckBox(bool v)
	{
		qs()->setValue("autoCenterCheckBox", v);
	}

	bool Settings::autoCenterCheckBox() const
	{
		return qs()->value("autoCenterCheckBox", true).toBool();
	}

	void Settings::setKmlExportPoints(bool v)
	{
		qs()->setValue("kmlExportPoints", v);
	}

	bool Settings::kmlExportPoints() const
	{
		return qs()->value("kmlExportPoints", false).toBool();
	}

	void Settings::setKmlExportSummary(bool v)
	{
		qs()->setValue("kmlExportSummary", v);
	}

	bool Settings::kmlExportSummary() const
	{
		return qs()->value("kmlExportSummary", true).toBool();
	}

	void Settings::setMeasureSystem(int v)
	{
		qs()->setValue("measureSystem", v);
	}

	int Settings::measureSystem() const
	{
		return qs()->value("measureSystem", EnumMeasureSystem::Metric).toInt();
	}

	void saveDialogSize(const QString& group, QDialog* dlg)
	{
		int screenNumber = QApplication::desktop()->screenNumber(dlg->parentWidget());
		QRect desktopGeometry = QApplication::desktop()->screenGeometry(screenNumber);

		const QSize sizeToSave = dlg->size();

		Settings::self()->qs()->beginGroup(group);
		Settings::self()->qs()->setValue(QString("width_%1").arg(desktopGeometry.width()), sizeToSave.width());
		Settings::self()->qs()->setValue(QString("height_%1").arg(desktopGeometry.height()), sizeToSave.height());
		Settings::self()->qs()->endGroup();
	}

	void restoreDialogSize(const QString& group, QDialog* dlg)
	{
		int screenNumber = QApplication::desktop()->screenNumber(dlg->parentWidget());
		QRect desktopGeometry = QApplication::desktop()->screenGeometry(screenNumber);

		int width = dlg->sizeHint().width();
		int height = dlg->sizeHint().height();

		Settings::self()->qs()->beginGroup(group);
		width = Settings::self()->qs()->value(QString("width_%1").arg(desktopGeometry.width()), width).toInt();
		height= Settings::self()->qs()->value(QString("height_%1").arg(desktopGeometry.height()), height).toInt();
		Settings::self()->qs()->endGroup();

		dlg->resize(width, height);
	}

}

