/*
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() {

	QSettings settings;
	const QString defaultFontString = QFont("Monospace", 8).toString();
	const QString defaultDirString = QDir().absolutePath();

	settings.beginGroup("General");
	closeBehaviour		= static_cast<CloseBehaviour>(settings.value("close_behaviour").toUInt());
	settings.endGroup();
	
	settings.beginGroup("Appearance");
	StackViewFont		= settings.value("stack_view_font", defaultFontString).toString();
	MemoryDumpViewFont	= settings.value("memory_view_font", defaultFontString).toString();
	RegisterViewFont	= settings.value("register_view_font", defaultFontString).toString();
	DisassemblyViewFont	= settings.value("disassembly_view_font", defaultFontString).toString();
	settings.endGroup();
	
	settings.beginGroup("Debugging");
	initialBreakpoint		= static_cast<InitialBreakpoint>(settings.value("initial_breakpoint", 1).toUInt());
	warnOnNoExecBP			= settings.value("warn_on_setting_BP_in_no_exec", true).toBool();
	findMain				= settings.value("find_main_if_no_symbol", true).toBool();
	minAsciiStringLength	= settings.value("minimum_ascii_string_length", 4).toUInt();
	ttyEnabled				= settings.value("debugger.terminal.enabled", true).toBool();
	ttyCommand				= settings.value("debugger.terminal.command", "/usr/bin/xterm").toString();
	settings.endGroup();
	
	settings.beginGroup("Disassembly");
	syntax					= static_cast<Syntax>(settings.value("disassembly_syntax").toUInt());
	zerosAreFilling			= settings.value("disassembly.zeros_are_filling.enabled", true).toBool();
	uppercaseDisassembly	= settings.value("disassembly.uppercase.enabled", false).toBool();
	settings.endGroup();
	
	settings.beginGroup("Directories");
#ifdef DEFAULT_SYMBOL_PATH
	symbolPath			= settings.value("symbol_path", TOSTRING(DEFAULT_SYMBOL_PATH)).toString();
#else
	symbolPath			= settings.value("symbol_path", defaultDirString).toString();
#endif

#ifdef DEFAULT_PLUGIN_PATH
	pluginPath			= settings.value("plugin_path", TOSTRING(DEFAULT_PLUGIN_PATH)).toString();
#else
	pluginPath			= settings.value("plugin_path", defaultDirString).toString();
#endif

	sessionPath			= settings.value("session_path", defaultDirString).toString();
	settings.endGroup();
	
	
	settings.beginGroup("Window");	
	DataShowAddress = settings.value("window.data.show_address.enabled", true).toBool();
	DataShowHex = settings.value("window.data.show_hex.enabled", true).toBool();
	DataShowAscii = settings.value("window.data.show_ascii.enabled", true).toBool();
	DataShowComments = settings.value("window.data.show_comments.enabled", true).toBool();
	DataWordWidth = settings.value("window.data.word_width", 1).toInt();
	DataRowWidth = settings.value("window.data.row_width", 16).toInt();
	
	// 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;
	}
	settings.endGroup();
}

//------------------------------------------------------------------------------
// 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("stack_view_font", StackViewFont);
	settings.setValue("memory_view_font", MemoryDumpViewFont);
	settings.setValue("register_view_font", RegisterViewFont);
	settings.setValue("disassembly_view_font", DisassemblyViewFont);
	settings.endGroup();
	
	settings.beginGroup("Debugging");
	settings.setValue("initial_breakpoint", initialBreakpoint);
	settings.setValue("warn_on_setting_BP_in_no_exec", warnOnNoExecBP);
	settings.setValue("find_main_if_no_symbol", findMain);
	settings.setValue("minimum_ascii_string_length", minAsciiStringLength);
	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("symbol_path", symbolPath);
	settings.setValue("plugin_path", pluginPath);
	settings.setValue("session_path", sessionPath);
	settings.endGroup();

	settings.beginGroup("Window");	
	settings.setValue("window.data.show_address.enabled", DataShowAddress);
	settings.setValue("window.data.show_hex.enabled", DataShowHex);
	settings.setValue("window.data.show_ascii.enabled", DataShowAscii);
	settings.setValue("window.data.show_comments.enabled", DataShowComments);
	settings.setValue("window.data.word_width", DataWordWidth);
	settings.setValue("window.data.row_width", DataRowWidth);
	settings.endGroup();
}
