/*
Copyright (C) 2006 Evan Teran
                   eteran@alum.rit.edu

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 "Configuration.h"
#include <QSettings>
#include <QDir>
#include <QFont>

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

//------------------------------------------------------------------------------
// Name: Configuration()
// Desc: constructor
//------------------------------------------------------------------------------
Configuration::Configuration() {
	readSettingsFromFile();
}

//------------------------------------------------------------------------------
// Name: ~Configuration()
// Desc: destructor
//------------------------------------------------------------------------------
Configuration::~Configuration() {
	writeSettingsToFile();
}

//------------------------------------------------------------------------------
// Name: readSettingsFromFile()
// Desc: read in the options from the file
//------------------------------------------------------------------------------
void Configuration::readSettingsFromFile() {

	const QString defaultFontString	= QFont("Monospace", 8).toString();
	
#ifdef DEFAULT_SYMBOL_PATH
	const QString defaultSymbolPathString = TOSTRING(DEFAULT_SYMBOL_PATH);
#else
	const QString defaultSymbolPathString	= QDir().absolutePath();
#endif

#ifdef DEFAULT_PLUGIN_PATH
	const QString defaultPluginPathString = TOSTRING(DEFAULT_PLUGIN_PATH);
#else
	const QString defaultPluginPathString	= QDir().absolutePath();
#endif

	const QString defaultSessionPathString	= QDir().absolutePath();

	QSettings settings;
	
	settings.beginGroup("General");
	closeBehaviour			= static_cast<CloseBehaviour>(settings.value("close_behaviour").value<uint>());
	settings.endGroup();
	
	settings.beginGroup("Appearance");
	stackFont				= settings.value("appearance.stack.font", defaultFontString).value<QString>();
	dataFont				= settings.value("appearance.data.font", defaultFontString).value<QString>();
	registersFont			= settings.value("appearance.registers.font", defaultFontString).value<QString>();
	disassemblyFont			= settings.value("appearance.disassembly.font", defaultFontString).value<QString>();
	dataShowAddress			= settings.value("appearance.data.show_address.enabled", true).value<bool>();
	dataShowHex				= settings.value("appearance.data.show_hex.enabled", true).value<bool>();
	dataShowAscii			= settings.value("appearance.data.show_ascii.enabled", true).value<bool>();
	dataShowComments		= settings.value("appearance.data.show_comments.enabled", true).value<bool>();
	dataWordWidth			= settings.value("appearance.data.word_width", 1).value<int>();
	dataRowWidth			= settings.value("appearance.data.row_width", 16).value<int>();
	showAddressSeperator	= settings.value("appearance.address_semicolon.enabled", true).value<bool>();
	settings.endGroup();
	
	settings.beginGroup("Debugging");
	initialBreakpoint		= static_cast<InitialBreakpoint>(settings.value("debugger.initial_breakpoint.enabled", MainSymbol).value<uint>());
	warnOnNoExecBP			= settings.value("debugger.BP_NX_warn.enabled", true).value<bool>();
	findMain				= settings.value("debugger.find_main.enabled", true).value<bool>();
	minStringLength			= settings.value("debugger.string_min", 4).value<uint>();
	ttyEnabled				= settings.value("debugger.terminal.enabled", true).value<bool>();
	ttyCommand				= settings.value("debugger.terminal.command", "/usr/bin/xterm").value<QString>();
	settings.endGroup();
	
	settings.beginGroup("Disassembly");
	syntax					= static_cast<Syntax>(settings.value("disassembly.syntax", Intel).value<uint>());
	zerosAreFilling			= settings.value("disassembly.zeros_are_filling.enabled", true).value<bool>();
	uppercaseDisassembly	= settings.value("disassembly.uppercase.enabled", false).value<bool>();
	settings.endGroup();
	
	settings.beginGroup("Directories");
	symbolPath				= settings.value("directory.symbol.path", defaultSymbolPathString).value<QString>();
	pluginPath				= settings.value("directory.plugin.path", defaultPluginPathString).value<QString>();
	sessionPath				= settings.value("directory.session.path", defaultSessionPathString).value<QString>();
	settings.endGroup();

	// normalize values
	if(dataWordWidth != 1 && dataWordWidth != 2 && dataWordWidth != 4 && dataWordWidth != 8) {
		dataWordWidth = 1;
	}
	
	if(dataRowWidth != 1 && dataRowWidth != 2 && dataRowWidth != 4 && dataRowWidth != 8 && dataRowWidth != 16) {
		dataRowWidth = 16;
	}
}

//------------------------------------------------------------------------------
// Name: writeSettingsToFile()
// Desc: writes the options to the file
//------------------------------------------------------------------------------
void Configuration::writeSettingsToFile() {

	QSettings settings;
	
	settings.beginGroup("General");
	settings.setValue("close_behaviour", closeBehaviour);
	settings.endGroup();
	
	settings.beginGroup("Appearance");
	settings.setValue("appearance.stack.font", stackFont);
	settings.setValue("appearance.data.font", dataFont);
	settings.setValue("appearance.registers.font", registersFont);
	settings.setValue("appearance.disassembly.font", disassemblyFont);
	settings.setValue("appearance.data.show_address.enabled", dataShowAddress);
	settings.setValue("appearance.data.show_hex.enabled", dataShowHex);
	settings.setValue("appearance.data.show_ascii.enabled", dataShowAscii);
	settings.setValue("appearance.data.show_comments.enabled", dataShowComments);
	settings.setValue("appearance.data.word_width", dataWordWidth);
	settings.setValue("appearance.data.row_width", dataRowWidth);
	settings.setValue("appearance.address_semicolon.enabled", showAddressSeperator);
	settings.endGroup();
	
	settings.beginGroup("Debugging");
	settings.setValue("debugger.BP_NX_warn.enabled", warnOnNoExecBP);
	settings.setValue("debugger.string_min", minStringLength);
	settings.setValue("debugger.initial_breakpoint.enabled", initialBreakpoint);
	settings.setValue("debugger.find_main.enabled", findMain);
	settings.setValue("debugger.terminal.enabled", ttyEnabled);
	settings.setValue("debugger.terminal.command", ttyCommand);
	settings.endGroup();
	
	settings.beginGroup("Disassembly");
	settings.setValue("disassembly.syntax", syntax);
	settings.setValue("disassembly.zeros_are_filling.enabled", zerosAreFilling);
	settings.setValue("disassembly.uppercase.enabled", uppercaseDisassembly);
	settings.endGroup();
	
	settings.beginGroup("Directories");
	settings.setValue("directory.symbol.path", symbolPath);
	settings.setValue("directory.plugin.path", pluginPath);
	settings.setValue("directory.session.path", sessionPath);
	settings.endGroup();
}
