/*
Copyright (C) 2006 - 2009 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 "Debugger.h"

#include <QFontDialog>
#include <QFileDialog>
#include <QFont>
#include <QCloseEvent>
#include <QToolBox>

//------------------------------------------------------------------------------
// Name: DialogOptions(QWidget *parent)
// Desc: 
//------------------------------------------------------------------------------
DialogOptions::DialogOptions(QWidget *parent) : QDialog(parent), m_ToolBox(0) {
	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: 
//------------------------------------------------------------------------------
void DialogOptions::addOptionsPage(QWidget *page) {
	
	if(m_ToolBox == 0) {
		delete ui.tabWidget->findChild<QLabel *>("label_plugins");
		QWidget *const tab			= ui.tabWidget->findChild<QLabel *>("tab_plugins");
		QGridLayout *const layout	= ui.tabWidget->findChild<QGridLayout *>("tab_plugins_layout");
		m_ToolBox = new QToolBox(tab);
		layout->addWidget(m_ToolBox, 0, 0, 1, 1);
	}
	
	m_ToolBox->addItem(page, QIcon(":/debugger/images/edb32-preferences-plugin.png"), page->windowTitle());
}

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

//------------------------------------------------------------------------------
// Name: 
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::on_btnTTY_clicked() {
	const QString filename = QFileDialog::getOpenFileName(
		this, 
		tr("Choose Your Terminal Program"));
		
	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.spnMinString->setValue(minStringLength);
	
	ui.txtStackFont->setText(stackFont);
	ui.txtMemoryFont->setText(dataFont);
	ui.txtRegisterFont->setText(registersFont);
	ui.txtDisFont->setText(disassemblyFont);

	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));
	
	ui.chkAddressSemicolon->setChecked(showAddressSeperator);
}

//------------------------------------------------------------------------------
// 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;
	default:
		return 0;
	}
}

//------------------------------------------------------------------------------
// Name: closeEvent(QCloseEvent *event)
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::closeEvent(QCloseEvent *event) {

	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;
	}
	
	stackFont				= ui.txtStackFont->text();
	dataFont				= ui.txtMemoryFont->text();	
	registersFont			= ui.txtRegisterFont->text();
	disassemblyFont			= 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();
	
	showAddressSeperator	= ui.chkAddressSemicolon->isChecked();

	minStringLength			= ui.spnMinString->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();
	
	event->accept();
}

//------------------------------------------------------------------------------
// Name: 
// Desc: 
//------------------------------------------------------------------------------
void DialogOptions::accept() {
	close();
}
