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

#ifndef DEBUGGERUI_20090811_H_
#define DEBUGGERUI_20090811_H_

#include "ByteStreamRegion.h"
#include <QSharedPointer>
#include <QMessageBox>
#include "DataViewInfo.h"
#include "ui_debuggerui.h"

#include <QMainWindow>
#include <QProcess>
#include <QVector>

#include <cstring>

class QToolButton;


class DebuggerUI : public QMainWindow {
	Q_OBJECT

public:
	DebuggerUI(QWidget *parent = 0);
	virtual ~DebuggerUI();
	
protected:
	enum GUI_STATE {
		PAUSED,
		RUNNING,
		TERMINATED
	};
	
public:
	int currentTab() const;
	QSharedPointer<DataViewInfo> currentDataViewInfo() const;
	void finishPluginSetup(const QMap<QString, QObject *> &plugins);
	
protected:
	void updateMenuState(GUI_STATE state);
	QString createTTY();
	void setDebuggerCaption(const QString &appname);
	void deleteDataTab();
	void createDataTab();
	edb::address_t getGotoExpression(bool &ok);
	
	template <class T>
	edb::address_t getFollowAddress(const T &hv, bool &ok) {
		ok = false;

		Q_CHECK_PTR(hv);

		if(hv->hasSelectedText()) {
			const QByteArray data = hv->selectedBytes();

			if(data.size() == sizeof(edb::address_t)) {
				edb::address_t d;
				std::memcpy(&d, data.data(), sizeof(edb::address_t));

				ok = true;
				return d;
			}
		}

		QMessageBox::information(this, 
			tr("Invalid Selection"), 
			tr("Please select a %1 bytes to use this function.").arg(sizeof(edb::address_t)));

		return 0;
	}
	
	edb::reg_t getFollowRegister(bool &ok) const;
	
private Q_SLOTS:
	void ttyProcFinished(int exitCode, QProcess::ExitStatus exitStatus);
	
protected:
	QToolButton								*m_AddTab;
	QToolButton								*m_DelTab;
	QProcess								*m_TTYProc;
	GUI_STATE								m_GUIState;
	QString									m_TTYFile;
	QVector<QSharedPointer<DataViewInfo> >	m_DataRegions;
	DataViewInfo							m_StackViewInfo;
	
public:
	Ui::DebuggerUI ui;
};

#endif

