/*
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.
*/

#ifndef DEBUGGER_20061101_H_
#define DEBUGGER_20061101_H_

#include "EDBTypes.h"
#include <QString>
#include <QStringList>

class QFileInfo;
class QWidget;
class QDialog;
class QByteArray;

class DebuggerCoreInterface;
class MemoryRegions;
class SymbolManager;
class DebugEventHandlerInterface;
class Configuration;
class State;
class BinaryInfo;
class ArchProcessor;

namespace Debugger {

	// some useful objects
	extern DebugEventHandlerInterface	*debugEventHandler;
	extern DebuggerCoreInterface		*debuggerBase;
	extern QWidget						*debuggerGUI;
	
	// get the current state object
	State &currentState();
	
	// the symbol mananger
	SymbolManager &symbolManager();
	
	// the memory region manager
	MemoryRegions &memoryRegions();
	
	// the current arch processor
	ArchProcessor *archProcessor();
	
	// breakpoint managment
	void removeBreakpoint(edb::address_t address);
	void createBreakpoint(edb::address_t address);
	void toggleBreakpoint(edb::address_t address);

	// change what the various views show
	bool dumpDataRange(edb::address_t address, edb::address_t end_address, bool newTab);
	bool dumpDataRange(edb::address_t address, edb::address_t end_address);	
	bool dumpData(edb::address_t address, bool newTab);
	bool dumpData(edb::address_t address);
	bool dumpStack(edb::address_t address, bool ScrollTo);
	bool dumpStack(edb::address_t address);
	bool jumpToAddress(edb::address_t address);
	
	// ask the user for a dword via an input box
	bool getValueFromUser(edb::reg_t &value);
	bool getValueFromUser(edb::reg_t &value, const QString &title);
	
	// ask the user for a binary string via an input box
	bool getBinaryStringFromUser(QByteArray &value, int maxLength = 0);
	bool getBinaryStringFromUser(QByteArray &value, const QString &title, int maxLength = 0);
	
	// determine if the given address is the starting point of an ASCII style string, if so, s will contain it 
	// (formatted with C-style escape chars and found length will have the original length).
	bool getASCIIStringAtAddress(edb::address_t address, QString &s, int minLength, int maxLength, int &foundLength);
	
	// list of loaded librarys
	QStringList loadedLibraries();

	// configuration
	QDialog *dialogOptions();
	const Configuration *config();

	// logging, use this instead of printf/cout
	void log(const QString &s);
	
	// a numeric version of the current version suitable for integer comparison
	unsigned long intVersion(const QString &s);
	unsigned long intVersion();
	
	// symbol resolution
	QString findFunctionSymbol(edb::address_t address, const QString &defaultValue);
	QString findFunctionSymbol(edb::address_t address, const QString &defaultValue, int *offset);
	bool findFunctionSymbolBase(edb::address_t address, QString &value, int &offset);
	
	// file related tasks
	QString basename(const QString &s);
	QString symlinkTarget(const QString &s);
	QString symlinkTarget(const QFileInfo &info);
	
	QString getProcessCurrentWorkingDirectory();
	QStringList getProcessArguments();
	
	// careful, these throw exceptions of type Error (see Expression.h)
	edb::address_t getDWORD(edb::address_t address, void *p);
	edb::address_t getVariable(const QString &s, void *p);
	
	DebugEventHandlerInterface *setDebugEventHandler(DebugEventHandlerInterface *p);
	
	bool getInstructionBytes(edb::address_t address, uint8_t *buf, int &size);
	BinaryInfo *getBinaryInfo(const QString &s);
}	

#endif
