/*
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 "Types.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 ArchProcessorInterface;
class DebuggerPluginInterface;
class FunctionInfo;
class AnalyzerInterface;
class FunctionDB;
class SessionFileInterface;
struct ExpressionError;

#include "MemRegion.h"
#include "BinaryInfo.h"

namespace edb {
	namespace v1 {

		// some useful objects
		extern DebuggerCoreInterface	*debuggerBase;
		extern QWidget					*debuggerUI;

		// get the current state object
		State &currentState();

		// the symbol mananger
		SymbolManager &symbolManager();

		// the memory region manager
		MemoryRegions &memoryRegions();

		// the current arch processor
		ArchProcessorInterface &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 value suitable for a register via an input box
		bool getValueFromUser(edb::reg_t &value, const QString &title = QObject::tr("Input Value"));

		// ask the user for a binary string via an input box
		bool getBinaryStringFromUser(QByteArray &value, const QString &title, int maxLength = 0);

		// determine if the given address is the starting point of an string, if so, s will contain it 
		// (formatted with C-style escape chars, so foundLength will have the original length of the string in chars).
		bool getASCIIStringAtAddress(edb::address_t address, QString &s, int minLength, int maxLength, int &foundLength);
		bool getUTF16StringAtAddress(edb::address_t address, QString &s, int minLength, int maxLength, int &foundLength);

		// list of loaded librarys
		QStringList loadedLibraries();

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

		// a numeric version of the current version suitable for integer comparison
		ulong edbVersion();

		// symbol resolution
		QString findFunctionSymbol(edb::address_t address);
		QString findFunctionSymbol(edb::address_t address, const QString &defaultValue);
		QString findFunctionSymbol(edb::address_t address, const QString &defaultValue, int *offset);

		QString getProcessCurrentWorkingDirectory();
		QString getProcessExecutable();
		QStringList getProcessArguments();

		edb::address_t getDWORD(edb::address_t address, bool &ok, ExpressionError &err, void *p);
		edb::address_t getVariable(const QString &s, bool &ok, ExpressionError &err, void *p);

		DebugEventHandlerInterface *setDebugEventHandler(DebugEventHandlerInterface *p);
		DebugEventHandlerInterface *debugEventHandler();

		AnalyzerInterface *setAnalyzer(AnalyzerInterface *p);
		AnalyzerInterface *analyzer();
		
		SessionFileInterface *setSessionFileHandler(SessionFileInterface *p);
		SessionFileInterface *sessionFileHandler();

		bool getInstructionBytes(edb::address_t address, quint8 *buf, int &size);

		BinaryInfo *getBinaryInfo(const QString &s);
		const FunctionInfo *getFunctionInfo(const QString &functionName);
	
		edb::address_t locateMainFunction(const QString &file);
		
		bool registerPlugin(const QString &filename, QObject *plugin);
		const QMap<QString, QObject *> &pluginList();
		DebuggerPluginInterface *findPluginByName(const QString &name);

		void reloadSymbols();		
		void repaintCPUView();
		
		MemRegion primaryDataRegion();
		
		void popValue(State &state);
		void pushValue(State &state, edb::reg_t value);
		
		void registerBinaryInfo(BinaryInfo::createFuncPtr fptr);
		FunctionDB *setFunctionDB(FunctionDB *p);
	}
}	
#endif
