/*
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 "DialogOptions.h"
#include <QFontDialog>
#include <QFileDialog>
#include <QFont>
#include "Debugger.h"

//------------------------------------------------------------------------------
// Name: DialogOptions(QWidget *parent)
// Desc: 
//------------------------------------------------------------------------------
DialogOptions::DialogOptions(QWidget *parent) : QDialog(parent) {
	ui.setupUi(this);
}

//------------------------------------------------------------------------------
// Name: 
// Desc: 
//------------------------------------------------------------------------------
QString DialogOptions::fontFromDialog(const QString &defaultFont) {
	QFont oldFont;
	oldFont.fromString(defaultFont);
	return QFontDialog::getFont(0, oldFont, this).toString();
}

//------------------------------------------------------------------------------
// Name: 
// Desc: 
//------------------------------------------------------------------------------
QString DialogOptions::directoryFromDialog() {
	return QFileDialog::getExistingDirectory(
    	this,
    	"Choose a directory",
    	QString(),
    	QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
}

//------------------------------------------------------------------------------
// Name: 
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::on_btnTTY_clicked() {
	const QString filename = QFileDialog::getOpenFileName(
		this, 
		"Choose Your Terminal Program",
		QString(),
		QString());
		
	ui.txtTTY->setText(filename);
}

//------------------------------------------------------------------------------
// Name: on_btnStackFont_clicked()
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::on_btnStackFont_clicked() {
	ui.txtStackFont->setText(fontFromDialog(ui.txtStackFont->text()));
}

//------------------------------------------------------------------------------
// Name: on_btnMemoryFont_clicked()
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::on_btnMemoryFont_clicked() {
	ui.txtMemoryFont->setText(fontFromDialog(ui.txtMemoryFont->text()));
}

//------------------------------------------------------------------------------
// Name: on_btnRegisterFont_clicked()
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::on_btnRegisterFont_clicked() {
	ui.txtRegisterFont->setText(fontFromDialog(ui.txtRegisterFont->text()));
}

//------------------------------------------------------------------------------
// Name: on_btnDisFont_clicked()
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::on_btnDisFont_clicked() {
	ui.txtDisFont->setText(fontFromDialog(ui.txtDisFont->text()));
}

//------------------------------------------------------------------------------
// Name: on_btnSymbolDir_clicked()
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::on_btnSymbolDir_clicked() {
	const QString s = directoryFromDialog();
				
	if(!s.isEmpty()) {
		ui.txtSymbolDir->setText(s);
	}
}

//------------------------------------------------------------------------------
// Name: on_btnSessionDir_clicked()
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::on_btnSessionDir_clicked() {
	const QString s = directoryFromDialog();
				
	if(!s.isEmpty()) {
		ui.txtSessionDir->setText(s);
	}
}

//------------------------------------------------------------------------------
// Name: on_btnPluginDir_clicked()
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::on_btnPluginDir_clicked() {
	const QString s = directoryFromDialog();
	
	if(!s.isEmpty()) {
		ui.txtPluginDir->setText(s);
	}
}

//------------------------------------------------------------------------------
// Name: showEvent(QShowEvent *event)
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::showEvent(QShowEvent *event) {
	QDialog::showEvent(event);
	
	ui.rdoSytntaxATT->setChecked(syntax == ATT);
	ui.rdoSytntaxIntel->setChecked(syntax != ATT);

	ui.rdoDetach->setChecked(closeBehaviour == Detach);
	ui.rdoKill->setChecked(closeBehaviour != Detach);

	ui.rdoBPEntry->setChecked(initialBreakpoint == EntryPoint);
	ui.rdoBPMain->setChecked(initialBreakpoint != EntryPoint);
	
	ui.chkTTY->setChecked(ttyEnabled);
	ui.txtTTY->setText(ttyCommand);
	
	ui.chkZerosAreFilling->setChecked(zerosAreFilling);
	ui.chkUppercase->setChecked(uppercaseDisassembly);
	
	ui.chkFindMain->setChecked(findMain);
	ui.chkWarnDataBreakpoint->setChecked(warnOnNoExecBP);
	
	ui.spnMinAscii->setValue(minAsciiStringLength);
	
	ui.txtStackFont->setText(StackViewFont);
	ui.txtMemoryFont->setText(MemoryDumpViewFont);
	ui.txtRegisterFont->setText(RegisterViewFont);
	ui.txtDisFont->setText(DisassemblyViewFont);

	ui.txtSymbolDir->setText(symbolPath);
	ui.txtPluginDir->setText(pluginPath);
	ui.txtSessionDir->setText(sessionPath);
	
	ui.chkDataShowAddress->setChecked(DataShowAddress);
	ui.chkDataShowHex->setChecked(DataShowHex);
	ui.chkDataShowAscii->setChecked(DataShowAscii);
	ui.chkDataShowComments->setChecked(DataShowComments);
	ui.cmbDataWordWidth->setCurrentIndex(WidthToIndex(DataWordWidth));
	ui.cmbDataRowWidth->setCurrentIndex(WidthToIndex(DataRowWidth));
	
}

//------------------------------------------------------------------------------
// Name: WidthToIndex(int n)
// Desc: 
//------------------------------------------------------------------------------
int DialogOptions::WidthToIndex(int n) {
	switch(n) {
	case 16:
		return 4;
	case 8:
		return 3;
	case 4:
		return 2;
	case 2:
		return 1;
	case 1:
	default:
		return 0;
	}
}

//------------------------------------------------------------------------------
// Name: on_okButton_clicked()
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::on_okButton_clicked() {

	if(ui.rdoSytntaxIntel->isChecked()) {
		syntax = Intel;
	} else if(ui.rdoSytntaxATT->isChecked()) {
		syntax = ATT;
	}
	
	if(ui.rdoDetach->isChecked()) {
		closeBehaviour = Detach;
	} else if(ui.rdoKill->isChecked()) {
		closeBehaviour = Terminate;
	}
	
	StackViewFont			= ui.txtStackFont->text();
	MemoryDumpViewFont		= ui.txtMemoryFont->text();	
	RegisterViewFont		= ui.txtRegisterFont->text();
	DisassemblyViewFont		= ui.txtDisFont->text();
	ttyCommand				= ui.txtTTY->text();
	ttyEnabled				= ui.chkTTY->isChecked();
	zerosAreFilling			= ui.chkZerosAreFilling->isChecked();
	uppercaseDisassembly	= ui.chkUppercase->isChecked();
	
	symbolPath			= ui.txtSymbolDir->text();
	pluginPath			= ui.txtPluginDir->text();
	sessionPath			= ui.txtSessionDir->text();
	
	if(ui.rdoBPMain->isChecked()) {
		initialBreakpoint = MainSymbol;
	} else if(ui.rdoBPEntry->isChecked()) {
		initialBreakpoint = EntryPoint;
	}
	
	warnOnNoExecBP	= ui.chkWarnDataBreakpoint->isChecked();
	findMain		= ui.chkFindMain->isChecked();
	
	
	minAsciiStringLength = ui.spnMinAscii->value();
	
	DataShowAddress = ui.chkDataShowAddress->isChecked();
	DataShowHex = ui.chkDataShowHex->isChecked();
	DataShowAscii = ui.chkDataShowAscii->isChecked();
	DataShowComments = ui.chkDataShowComments->isChecked();
	DataWordWidth = 1 << ui.cmbDataWordWidth->currentIndex();
	DataRowWidth = 1 << ui.cmbDataRowWidth->currentIndex();
}
