/*
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 "DialogReferences.h"
#include "DebuggerCoreInterface.h"
#include "Debugger.h"
#include "Util.h"
#include "MemoryRegions.h"

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


//------------------------------------------------------------------------------
// Name: showEvent(QShowEvent *)
// Desc: 
//------------------------------------------------------------------------------
void DialogReferences::showEvent(QShowEvent *) {
	ui.listWidget->clear();
	ui.progressBar->setValue(0);
}

//------------------------------------------------------------------------------
// Name: on_btnFind_clicked()
// Desc: find button event handler
//------------------------------------------------------------------------------
void DialogReferences::on_btnFind_clicked() {
	bool ok;
	const edb::address_t address = ui.txtAddress->text().toUInt(&ok, 16);
	
	ui.listWidget->clear();
	ui.progressBar->setValue(0);
	if(ok) {
		Debugger::memoryRegions().sync();
		const QVector<MemoryRegions::Region> r = Debugger::memoryRegions().regions();

		int i = 0;
		foreach(MemoryRegions::Region region, r) {
			edb::address_t potentialReference;
			const edb::address_t howMany = region.end - region.start;
			
			// a short circut for speading things up
			if(ui.chkSkipNoAccess->isChecked() && !region.accessible()) {
				ui.progressBar->setValue(CalculatePercentage(++i, r.size(), howMany, howMany));
				continue;
			}

			
			for(edb::address_t addr = region.start; addr != region.end; addr += sizeof(edb::address_t)) {
				if(Debugger::debuggerBase->readBytes(addr, &potentialReference, sizeof(potentialReference))) {
					if(potentialReference == address) {
						ui.listWidget->addItem(QString().sprintf("%08x", addr));
					}
				}
				ui.progressBar->setValue(CalculatePercentage(i, r.size(), (addr - region.start), howMany));
			}
			++i;
		}
		ui.progressBar->setValue(100);
	}
}

//------------------------------------------------------------------------------
// Name: on_listWidget_itemDoubleClicked(QListWidgetItem *item)
// Desc: follows the foudn item in the data view
//------------------------------------------------------------------------------
void DialogReferences::on_listWidget_itemDoubleClicked(QListWidgetItem *item) {
	bool ok;
	const QString s = item->text();
	const edb::address_t addr = s.toUInt(&ok, 16);
	if(ok) {
		Debugger::dumpData(addr);
	}
}
