/*	Author:		Adam Brousseau
	Supervisor: Dr. Ryan Leduc
*/

#include <QtGui>
#include <QMessageBox>
#include "HelpBrowser.h"
#include "AboutHelpDlg.h"
#include "HelpPrint.h"

namespace DESpot
{
	//Page list
	QStringList allPages = (QStringList() <<
				"About.html" <<
				"TOC.html"  <<
				"Introduction.html" <<
				//"GettingStarted.html" <<
				//"Install.html" <<
				//"Startup.html" <<
				"MainWindow.html" <<
				"CreateFlat.html" <<
				"CreateHISC.html" <<
				"OpenProject.html" <<
				"CreateDES.html" <<
				"OpenDES.html" <<
				"ProjectEditorWindow.html" <<
				"FlatProjectEditor.html" <<
				"FProjectValidity.html" <<
				"FPEManageEvents.html" <<
				"FPEAddDES.html" <<
				"FPETools.html" <<
				"ExportToBDDsd.html" <<
				"HISCProjectEditor.html" <<
				"HProjectValidity.html" <<
				"HPEManageEvents.html" <<
				"HPESubsystems.html" <<
				"AddSubsystem.html" <<
				"RenameSubsystem.html" <<
				"DeleteSubsystem.html" <<
				"HPEAddDES.html" <<
				"HPETools.html" <<
				"ExportToBDDhisc.html" <<
				"BDDTools.html" <<
				"SaveProject.html" <<
				"SetName.html" <<
				"PrintProject.html" <<
				"EditDES.html" <<
				"RemoveDES.html" <<
				"DESEditor.html" <<
				"TabularEditor.html" <<
				"TABStates.html" <<
				"TABCreateState.html" <<
				"TABChangeState.html" <<
				"TABDeleteState.html" <<
				"TABInitialState.html" <<
				"TABMarkState.html" <<
				"TABEvents.html" <<
				"TABCreateEvent.html" <<
				"TABChangeEvent.html" <<		
				"TABDeleteEvent.html" <<
				"TABControlEvent.html" <<
				"TABEventType.html" <<
				"TABTransitions.html" <<
				"TABCreateTransition.html" <<
				"TABChangeTransition.html" <<
				"TABDeleteTransition.html" <<
				"TABCreateGlobalLoop.html" <<
				"TABDeleteGlobalLoop.html" <<
				"GraphicalEditor.html" <<
				"GRPHModes.html" <<
				"GRPHStates.html" <<
				"GRPHCreateState.html" <<
				"GRPHEditState.html" <<
				"GRPHDeleteState.html" <<
				"GRPHEvents.html" <<
				"GRPHCreateEvent.html" <<
				"GRPHChangeEvent.html" <<
				"GRPHDeleteEvent.html" <<
				"GRPHControlEvent.html" <<
				"GRPHEventType.html" <<
				"GRPHTransitions.html" <<
				"GRPHCreateTransition.html" <<
				"GRPHEditTransition.html" <<
				"GRPHDeleteTransition.html" <<
				"GRPHCreateGlobalLoop.html" <<
				"GRPHDeleteGlobalLoop.html" <<
				"GRPHImage.html" <<
				"GRPHGrid.html" <<
				"GRPHZoom.html" <<
				"DESTools.html" <<
				"DESConsistent.html" <<
				"SaveDES.html" <<	
				"SetDESName.html" <<
				"SetDESType.html" <<
				"PrintDES.html" <<
				"Simulator.html" <<
				"SIMConfigWiz.html" <<
				"SIMMainWindow.html" <<
				"SIMNew.html" <<
				"SIMOpen.html" <<
				"SIMSave.html" <<
				"SIMEventsPane.html" <<
				"SIMStatesPane.html" <<
				"SIMMode.html" <<
				"SIMRun.html" <<
				"SIMViewer.html"
				);


HelpBrowser::HelpBrowser(const QString &path, const QString &page, QWidget *parent) : QWidget(parent)
{
	setAttribute(Qt::WA_DeleteOnClose);
	setAttribute(Qt::WA_GroupLeader);
	
	setWindowIcon(QIcon(":/resources/help.png"));

	//setup the ui and connections
	indexTree = new QTreeWidget(this);
	indexTree->setHeaderHidden(true);
	setupIndexTree();
	indexTree->setMaximumWidth(200);
	indexTree->resizeColumnToContents(0);
	connect(indexTree, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(updatePage(QTreeWidgetItem *)));
	connect(indexTree, SIGNAL(itemCollapsed(QTreeWidgetItem *)), this, SLOT(updateColumnSize()));
	connect(indexTree, SIGNAL(itemExpanded(QTreeWidgetItem *)), this, SLOT(updateColumnSize()));

	contentTextBrowser = new QTextBrowser;
	contentTextBrowser->setSearchPaths(QStringList() << path);
	connect(contentTextBrowser, SIGNAL(sourceChanged(const QUrl &)), this, SLOT(updateWindowTitle(const QUrl &)));
	contentTextBrowser->setSource(path + "/" + page);

	homeButton = new QPushButton(QIcon(":/resources/home.png"), tr("&Home"), this);
	homeButton->setShortcut(tr("Ctrl+H"));
	homeButton->setToolTip(tr("Home (Ctrl+H)"));
	connect(homeButton, SIGNAL(clicked()), contentTextBrowser, SLOT(home()));

	backButton = new QPushButton(QIcon(":/resources/sim_backward.png"), tr("&Back"), this);
	backButton->setShortcut(tr("Backspace"));
	backButton->setToolTip(tr("Go to the previous page in history (Backspace)"));
	backButton->setEnabled(false);
	connect(contentTextBrowser, SIGNAL(backwardAvailable(bool)), backButton, SLOT(setEnabled(bool)));	
	connect(backButton, SIGNAL(clicked()), contentTextBrowser, SLOT(backward()));

	forwardButton = new QPushButton(QIcon(":/resources/sim_forward.png"), tr("&Forward"), this);
	forwardButton->setShortcut(tr("Ctrl+F"));
	forwardButton->setToolTip(tr("Go to the next page in history (Ctrl+F)"));
	forwardButton->setEnabled(false);
	connect(contentTextBrowser, SIGNAL(forwardAvailable(bool)), forwardButton, SLOT(setEnabled(bool)));
	connect(forwardButton, SIGNAL(clicked()), contentTextBrowser, SLOT(forward()));

	printButton = new QToolButton(this);
	printButton->setIcon(QIcon(":/resources/print.png"));
	printButton->setShortcut(tr("Ctrl+P"));
	printButton->setToolTip(tr("Print (Ctrl+P)"));
	connect(printButton, SIGNAL(clicked()), this, SLOT(onPrintButtonClick()));

	aboutButton = new QPushButton(QIcon(":/resources/about.png"), tr("About"), this);
	aboutButton->setShortcut(tr("F1"));
	aboutButton->setToolTip(tr("About the help file"));
	connect(aboutButton, SIGNAL(clicked()), this, SLOT(onOpenAboutHelp()));

	findLabel = new QLabel(tr("Keyword:"));
	
	findBox = new QLineEdit;
	connect(findBox, SIGNAL(returnPressed()), this, SLOT(onFindButtonClick()));
	connect(findBox, SIGNAL(textChanged(const QString &)), this, SLOT(enableFindButton(const QString &)));

	findButton = new QPushButton(tr("&Find"));
	findButton->setEnabled(false);
	connect(findButton, SIGNAL(clicked()), this, SLOT(onFindButtonClick()));

	QHBoxLayout *buttonLayout = new QHBoxLayout;
	buttonLayout->addWidget(backButton);
	buttonLayout->addWidget(forwardButton);
	buttonLayout->addWidget(homeButton);
	buttonLayout->addWidget(printButton);
	buttonLayout->addStretch();
	buttonLayout->addWidget(findLabel);
	buttonLayout->addWidget(findBox);
	buttonLayout->addWidget(findButton);
	buttonLayout->addWidget(aboutButton);

	QHBoxLayout *textLayout = new QHBoxLayout;
	textLayout->addWidget(indexTree);
	textLayout->addWidget(contentTextBrowser);

	QVBoxLayout *mainLayout = new QVBoxLayout;
	mainLayout->addLayout(buttonLayout);
	mainLayout->addLayout(textLayout);
	setLayout(mainLayout);

	setTabOrder(findBox, findButton);
	setTabOrder(findButton, aboutButton);
	setTabOrder(aboutButton, indexTree);
	setTabOrder(indexTree, contentTextBrowser);
	setTabOrder(contentTextBrowser, backButton);
	setTabOrder(backButton, forwardButton);
	setTabOrder(forwardButton, homeButton);
	setTabOrder(homeButton, printButton);
		
}

//_________________________________________________________________________________________________
/*
HelpBrowser::~HelpBrowser(void)
{
}
*/
//_________________________________________________________________________________________________

void HelpBrowser::setupIndexTree()
{

	//About
	QTreeWidgetItem *about = new QTreeWidgetItem(indexTree);
	about->setText(0, tr("About This Document"));
	about->setData(1,0, tr("About.html"));
		
	//Table of Contents
	QTreeWidgetItem *contents = new QTreeWidgetItem(indexTree);
	contents->setText(0, tr("Contents"));
	contents->setData(1, 0, tr("TOC.html"));
		
	//Introduction
	QTreeWidgetItem *intro = new QTreeWidgetItem(indexTree);
	intro->setText(0, tr("Introduction"));
	intro->setData(1,0, tr("Introduction.html"));
/*
	//Getting Started
	QTreeWidgetItem *gettingStarted = new QTreeWidgetItem(indexTree);
	gettingStarted->setText(0, tr("Getting Started"));
	gettingStarted->setData(1,0, tr("GettingStarted.html"));

		//Installing DESpot
		QTreeWidgetItem *install = new QTreeWidgetItem(gettingStarted);
		install->setText(0, tr("Installing DESpot"));
		install->setData(1,0, tr("Install.html"));

		//Starting DESpot
		QTreeWidgetItem *start = new QTreeWidgetItem(gettingStarted);
		start->setText(0, tr("Starting DESpot"));
		start->setData(1,0, tr("Startup.html"));
*/
	//Main Window
	QTreeWidgetItem *main = new QTreeWidgetItem(indexTree);
	main->setText(0, tr("DESpot Main"));
	main->setData(1,0, tr("MainWindow.html"));

		//Create Flat
		QTreeWidgetItem *createFlat = new QTreeWidgetItem(main);
		createFlat->setText(0, tr("Create a Flat Project"));
		createFlat->setData(1,0, tr("CreateFlat.html"));

		//Create HISC
		QTreeWidgetItem *createHISC = new QTreeWidgetItem(main);
		createHISC->setText(0, tr("Create an HISC Project"));
		createHISC->setData(1,0, tr("CreateHISC.html"));

		//Open project
		QTreeWidgetItem *openProject = new QTreeWidgetItem(main);
		openProject->setText(0, tr("Opening a Project"));
		openProject->setData(1,0, tr("OpenProject.html"));

		//Create DES
		QTreeWidgetItem *createDES = new QTreeWidgetItem(main);
		createDES->setText(0, tr("Creating a DES"));
		createDES->setData(1,0, tr("CreateDES.html"));

		//Open DES
		QTreeWidgetItem *openDES = new QTreeWidgetItem(main);
		openDES->setText(0, tr("Opening a DES"));
		openDES->setData(1,0, tr("OpenDES.html"));

	//Project Editor Window
	QTreeWidgetItem *projectEditor = new QTreeWidgetItem(indexTree);
	projectEditor->setText(0, tr("Project Editor"));
	projectEditor->setData(1,0, tr("ProjectEditorWindow.html"));

		//FPE window
		QTreeWidgetItem *FPE = new QTreeWidgetItem(projectEditor);
		FPE->setText(0, tr("Flat Project Editor (FPE)"));
		FPE->setData(1,0, tr("FlatProjectEditor.html"));

			//Flat Project Validity
			QTreeWidgetItem *FPEValidity = new QTreeWidgetItem(FPE);
			FPEValidity->setText(0, tr("Flat Project Validity"));
			FPEValidity->setData(1,0, tr("FProjectValidity.html"));

			//Manage Events
			QTreeWidgetItem *FPEManageEvents = new QTreeWidgetItem(FPE);
			FPEManageEvents->setText(0, tr("FPE Manage Events"));
			FPEManageEvents->setData(1,0, tr("FPEManageEvents.html"));

			//Add DES
			QTreeWidgetItem *FPEAddDES = new QTreeWidgetItem(FPE);
			FPEAddDES->setText(0, tr("FPE Add DES"));
			FPEAddDES->setData(1,0, tr("FPEAddDES.html"));

			//FPE Tools
			QTreeWidgetItem *FPETools = new QTreeWidgetItem(FPE);
			FPETools->setText(0, tr("FPE Tools"));
			FPETools->setData(1,0, tr("FPETools.html"));

			//Export to BDDsd
			QTreeWidgetItem *ExportBDDsd = new QTreeWidgetItem(FPE);
			ExportBDDsd->setText(0, tr("Export to BDDsd"));
			ExportBDDsd->setData(1,0, tr("ExportToBDDsd.html"));

		//HPE window
		QTreeWidgetItem *HPE = new QTreeWidgetItem(projectEditor);
		HPE->setText(0, tr("HISC Project Editor (HPE)"));
		HPE->setData(1,0, tr("HISCProjectEditor.html"));

			//HISC Project Validity
			QTreeWidgetItem *HPEValidity = new QTreeWidgetItem(HPE);
			HPEValidity->setText(0, tr("HISC Project Validity"));
			HPEValidity->setData(1,0, tr("HProjectValidity.html"));

			//Manage Events
			QTreeWidgetItem *HPEManageEvents = new QTreeWidgetItem(HPE);
			HPEManageEvents->setText(0, tr("HPE Manage Events"));
			HPEManageEvents->setData(1,0, tr("HPEManageEvents.html"));

			//Subsystems
			QTreeWidgetItem *subsystems = new QTreeWidgetItem(HPE);
			subsystems->setText(0, tr("Subsystems"));
			subsystems->setData(1,0, tr("HPESubsystems.html"));

				//Add Subsystem
				QTreeWidgetItem *addSubsystem = new QTreeWidgetItem(subsystems);
				addSubsystem->setText(0, tr("Add Subsystem"));
				addSubsystem->setData(1,0, tr("AddSubsystem.html"));

				//Rename Subsystem
				QTreeWidgetItem *renameSubsystem = new QTreeWidgetItem(subsystems);
				renameSubsystem->setText(0, tr("Rename Subsystem"));
				renameSubsystem->setData(1,0, tr("RenameSubsystem.html"));

				//Delete Subsystem
				QTreeWidgetItem *deleteSubsystem = new QTreeWidgetItem(subsystems);
				deleteSubsystem->setText(0, tr("Delete Subsystem"));
				deleteSubsystem->setData(1,0, tr("DeleteSubsystem.html"));

			//Add DES
			QTreeWidgetItem *HPEAddDES = new QTreeWidgetItem(HPE);
			HPEAddDES->setText(0, tr("HPE Add DES"));
			HPEAddDES->setData(1,0, tr("HPEAddDES.html"));

			//HPE Tools
			QTreeWidgetItem *HPETools = new QTreeWidgetItem(HPE);
			HPETools->setText(0, tr("HPE Tools"));
			HPETools->setData(1,0, tr("HPETools.html"));

			//Export to BDDhisc
			QTreeWidgetItem *ExportBDDhisc = new QTreeWidgetItem(HPE);
			ExportBDDhisc->setText(0, tr("Export to BDDhisc"));
			ExportBDDhisc->setData(1,0, tr("ExportToBDDhisc.html"));

		//BDD Tools
		QTreeWidgetItem *BDDTools = new QTreeWidgetItem(projectEditor);
		BDDTools->setText(0, tr("BDD Tools"));
		BDDTools->setData(1,0, tr("BDDTools.html"));

		//Save Project
		QTreeWidgetItem *saveProject = new QTreeWidgetItem(projectEditor);
		saveProject->setText(0, tr("Save Project"));
		saveProject->setData(1,0, tr("SaveProject.html"));

		//Set Project Name
		QTreeWidgetItem *setName = new QTreeWidgetItem(projectEditor);
		setName->setText(0, tr("Set Project Name"));
		setName->setData(1,0, tr("SetName.html"));

		//Print Project
		QTreeWidgetItem *printProject = new QTreeWidgetItem(projectEditor);
		printProject->setText(0, tr("Print Project"));
		printProject->setData(1,0, tr("PrintProject.html"));

		//Edit DES
		QTreeWidgetItem *editDES = new QTreeWidgetItem(projectEditor);
		editDES->setText(0, tr("Edit DES"));
		editDES->setData(1,0, tr("EditDES.html"));

		//Remove DES
		QTreeWidgetItem *removeDES = new QTreeWidgetItem(projectEditor);
		removeDES->setText(0, tr("Remove DES"));
		removeDES->setData(1,0, tr("RemoveDES.html"));

	//DES Editor
	QTreeWidgetItem *DESEditor = new QTreeWidgetItem(indexTree);
	DESEditor->setText(0, tr("DES Editor"));
	DESEditor->setData(1,0, tr("DESEditor.html"));

		//Tabular Editor
		QTreeWidgetItem *tabular = new QTreeWidgetItem(DESEditor);
		tabular->setText(0, tr("Tabular Editor"));
		tabular->setData(1,0, tr("TabularEditor.html"));

			//States
			QTreeWidgetItem *TABStates = new QTreeWidgetItem(tabular);
			TABStates->setText(0, tr("States"));
			TABStates->setData(1,0, tr("TABStates.html"));		

				//Create State
				QTreeWidgetItem *TABCreateState = new QTreeWidgetItem(TABStates);
				TABCreateState->setText(0, tr("Create State"));
				TABCreateState->setData(1,0, tr("TABCreateState.html"));

				//Change State
				QTreeWidgetItem *TABChangeState = new QTreeWidgetItem(TABStates);
				TABChangeState->setText(0, tr("Change State"));
				TABChangeState->setData(1,0, tr("TABChangeState.html"));

				//Delete State
				QTreeWidgetItem *TABDeleteState = new QTreeWidgetItem(TABStates);
				TABDeleteState->setText(0, tr("Delete State"));
				TABDeleteState->setData(1,0, tr("TABDeleteState.html"));

				//Initial State
				QTreeWidgetItem *TABInitialState = new QTreeWidgetItem(TABStates);
				TABInitialState->setText(0, tr("Initial State"));
				TABInitialState->setData(1,0, tr("TABInitialState.html"));

				//Mark State
				QTreeWidgetItem *TABMarkState = new QTreeWidgetItem(TABStates);
				TABMarkState->setText(0, tr("Marked State"));
				TABMarkState->setData(1,0, tr("TABMarkState.html"));

			//Events
			QTreeWidgetItem *TABEvents = new QTreeWidgetItem(tabular);
			TABEvents->setText(0, tr("Events"));
			TABEvents->setData(1,0, tr("TABEvents.html"));

				//Create Event
				QTreeWidgetItem *TABCreateEvent = new QTreeWidgetItem(TABEvents);
				TABCreateEvent->setText(0, tr("Create Event"));
				TABCreateEvent->setData(1,0, tr("TABCreateEvent.html"));

				//Change Event
				QTreeWidgetItem *TABChangeEvent = new QTreeWidgetItem(TABEvents);
				TABChangeEvent->setText(0, tr("Change Event"));
				TABChangeEvent->setData(1,0, tr("TABChangeEvent.html"));

				//Delete Event
				QTreeWidgetItem *TABDeleteEvent = new QTreeWidgetItem(TABEvents);
				TABDeleteEvent->setText(0, tr("Delete Event"));
				TABDeleteEvent->setData(1,0, tr("TABDeleteEvent.html"));

				//Controllable Event
				QTreeWidgetItem *TABControlEvent = new QTreeWidgetItem(TABEvents);
				TABControlEvent->setText(0, tr("Controllable Event"));
				TABControlEvent->setData(1,0, tr("TABControlEvent.html"));

				//Event Type
				QTreeWidgetItem *TABEventType = new QTreeWidgetItem(TABEvents);
				TABEventType->setText(0, tr("Event Type"));
				TABEventType->setData(1,0, tr("TABEventType.html"));

			//Transitions
			QTreeWidgetItem *TABTransitions = new QTreeWidgetItem(tabular);
			TABTransitions->setText(0, tr("Transitions"));
			TABTransitions->setData(1,0, tr("TABTransitions.html"));

				//Create Transition
				QTreeWidgetItem *TABCreateTransition = new QTreeWidgetItem(TABTransitions);
				TABCreateTransition->setText(0, tr("Create Transition"));
				TABCreateTransition->setData(1,0, tr("TABCreateTransition.html"));

				//Change Transition
				QTreeWidgetItem *TABChangeTransition = new QTreeWidgetItem(TABTransitions);
				TABChangeTransition->setText(0, tr("Change Transition"));
				TABChangeTransition->setData(1,0, tr("TABChangeTransition.html"));

				//Delete Transition
				QTreeWidgetItem *TABDeleteTransition = new QTreeWidgetItem(TABTransitions);
				TABDeleteTransition->setText(0, tr("Delete Transition"));
				TABDeleteTransition->setData(1,0, tr("TABDeleteTransition.html"));

				//Create Global Self-Loop
				QTreeWidgetItem *TABCreateGlobal = new QTreeWidgetItem(TABTransitions);
				TABCreateGlobal->setText(0, tr("Create Global Self-Loop"));
				TABCreateGlobal->setData(1,0, tr("TABCreateGlobalLoop.html"));

				//Delete Global Self-Loop
				QTreeWidgetItem *TABDeleteGlobal = new QTreeWidgetItem(TABTransitions);
				TABDeleteGlobal->setText(0, tr("Delete Global Self-Loop"));
				TABDeleteGlobal->setData(1,0, tr("TABDeleteGlobalLoop.html"));

		//Graphical Editor
		QTreeWidgetItem *graphical = new QTreeWidgetItem(DESEditor);
		graphical->setText(0, tr("Graphical Editor"));
		graphical->setData(1,0, tr("GraphicalEditor.html"));

			//Editing Modes
			QTreeWidgetItem *GRPHModes = new QTreeWidgetItem(graphical);
			GRPHModes->setText(0, tr("Editing Modes"));
			GRPHModes->setData(1,0, tr("GRPHModes.html"));

			//States
			QTreeWidgetItem *GRPHStates = new QTreeWidgetItem(graphical);
			GRPHStates->setText(0, tr("States"));
			GRPHStates->setData(1,0, tr("GRPHStates.html"));
			
				//Create State
				QTreeWidgetItem *GRPHCreateState = new QTreeWidgetItem(GRPHStates);
				GRPHCreateState->setText(0, tr("Create State"));
				GRPHCreateState->setData(1,0, tr("GRPHCreateState.html"));

				//Edit State
				QTreeWidgetItem *GRPHEditState = new QTreeWidgetItem(GRPHStates);
				GRPHEditState->setText(0, tr("Edit State"));
				GRPHEditState->setData(1,0, tr("GRPHEditState.html"));

				//Create State
				QTreeWidgetItem *GRPHDeleteState = new QTreeWidgetItem(GRPHStates);
				GRPHDeleteState->setText(0, tr("Delete State"));
				GRPHDeleteState->setData(1,0, tr("GRPHDeleteState.html"));

			//Events
			QTreeWidgetItem *GRPHEvents = new QTreeWidgetItem(graphical);
			GRPHEvents->setText(0, tr("Events"));
			GRPHEvents->setData(1,0, tr("GRPHEvents.html"));

				//Create Event
				QTreeWidgetItem *GRPHCreateEvent = new QTreeWidgetItem(GRPHEvents);
				GRPHCreateEvent->setText(0, tr("Create Event"));
				GRPHCreateEvent->setData(1,0, tr("GRPHCreateEvent.html"));

				//Change Event
				QTreeWidgetItem *GRPHChangeEvent = new QTreeWidgetItem(GRPHEvents);
				GRPHChangeEvent->setText(0, tr("Change Event"));
				GRPHChangeEvent->setData(1,0, tr("GRPHChangeEvent.html"));

				//Delete Event
				QTreeWidgetItem *GRPHDeleteEvent = new QTreeWidgetItem(GRPHEvents);
				GRPHDeleteEvent->setText(0, tr("Delete Event"));
				GRPHDeleteEvent->setData(1,0, tr("GRPHDeleteEvent.html"));

				//Controllable Event
				QTreeWidgetItem *GRPHControlEvent = new QTreeWidgetItem(GRPHEvents);
				GRPHControlEvent->setText(0, tr("Controllable Event"));
				GRPHControlEvent->setData(1,0, tr("GRPHControlEvent.html"));

				//Event Type
				QTreeWidgetItem *GRPHEventType = new QTreeWidgetItem(GRPHEvents);
				GRPHEventType->setText(0, tr("Event Type"));
				GRPHEventType->setData(1,0, tr("GRPHEventType.html"));

			//Transitions
			QTreeWidgetItem *GRPHTransitions = new QTreeWidgetItem(graphical);
			GRPHTransitions->setText(0, tr("Transitions"));
			GRPHTransitions->setData(1,0, tr("GRPHTransitions.html"));

				//Create Transition
				QTreeWidgetItem *GRPHCreateTransition = new QTreeWidgetItem(GRPHTransitions);
				GRPHCreateTransition->setText(0, tr("Create Transition"));
				GRPHCreateTransition->setData(1,0, tr("GRPHCreateTransition.html"));

				//Edit Transition
				QTreeWidgetItem *GRPHEditTransition = new QTreeWidgetItem(GRPHTransitions);
				GRPHEditTransition->setText(0, tr("Edit Transition"));
				GRPHEditTransition->setData(1,0, tr("GRPHEditTransition.html"));

				//Delete Transition
				QTreeWidgetItem *GRPHDeleteTransition = new QTreeWidgetItem(GRPHTransitions);
				GRPHDeleteTransition->setText(0, tr("Delete Transition"));
				GRPHDeleteTransition->setData(1,0, tr("GRPHDeleteTransition.html"));

				//Create Global Self-Loop
				QTreeWidgetItem *GRPHCreateGlobalLoop = new QTreeWidgetItem(GRPHTransitions);
				GRPHCreateGlobalLoop->setText(0, tr("Create Global Self-Loop"));
				GRPHCreateGlobalLoop->setData(1,0, tr("GRPHCreateGlobalLoop.html"));

				//Delete Global Self-Loop
				QTreeWidgetItem *GRPHDeleteGlobalLoop = new QTreeWidgetItem(GRPHTransitions);
				GRPHDeleteGlobalLoop->setText(0, tr("Delete Global Self-Loop"));
				GRPHDeleteGlobalLoop->setData(1,0, tr("GRPHDeleteGlobalLoop.html"));

			//Export To Image
			QTreeWidgetItem *GRPHImage = new QTreeWidgetItem(graphical);
			GRPHImage->setText(0, tr("Image"));
			GRPHImage->setData(1,0, tr("GRPHImage.html"));

			//Show Grid
			QTreeWidgetItem *GRPHGrid = new QTreeWidgetItem(graphical);
			GRPHGrid->setText(0, tr("Grid"));
			GRPHGrid->setData(1,0, tr("GRPHGrid.html"));

			//Zoom
			QTreeWidgetItem *GRPHZoom = new QTreeWidgetItem(graphical);
			GRPHZoom->setText(0, tr("Zoom"));
			GRPHZoom->setData(1,0, tr("GRPHZoom.html"));

		//DES Tools
		QTreeWidgetItem *DESTools = new QTreeWidgetItem(DESEditor);
		DESTools->setText(0, tr("DES Tools"));
		DESTools->setData(1,0, tr("DESTools.html"));

		//DES Consistency
		QTreeWidgetItem *DESConsistent = new QTreeWidgetItem(DESEditor);
		DESConsistent->setText(0, tr("DES Consistency"));
		DESConsistent->setData(1,0, tr("DESConsistent.html"));

		//Save DES
		QTreeWidgetItem *saveDES = new QTreeWidgetItem(DESEditor);
		saveDES->setText(0, tr("Save DES"));
		saveDES->setData(1,0, tr("SaveDES.html"));

		//Set DES Name
		QTreeWidgetItem *setDESName = new QTreeWidgetItem(DESEditor);
		setDESName->setText(0, tr("Set DES Name"));
		setDESName->setData(1,0, tr("SetDESName.html"));

		//Set DES Type
		QTreeWidgetItem *setDESType = new QTreeWidgetItem(DESEditor);
		setDESType->setText(0, tr("Set DES Type"));
		setDESType->setData(1,0, tr("SetDESType.html"));

		//Print DES
		QTreeWidgetItem *printDES = new QTreeWidgetItem(DESEditor);
		printDES->setText(0, tr("Print DES"));
		printDES->setData(1,0, tr("PrintDES.html"));

	//Simulator
	QTreeWidgetItem *Simulator = new QTreeWidgetItem(indexTree);
	Simulator->setText(0, tr("Simulator"));
	Simulator->setData(1,0, tr("Simulator.html"));

		//Configuration Wizard
		QTreeWidgetItem *ConfigWiz = new QTreeWidgetItem(Simulator);
		ConfigWiz->setText(0, tr("Configuration Wizard"));
		ConfigWiz->setData(1,0, tr("SIMConfigWiz.html"));

		//Main Window
		QTreeWidgetItem *SIMMainWindow = new QTreeWidgetItem(Simulator);
		SIMMainWindow->setText(0, tr("Main Window"));
		SIMMainWindow->setData(1,0, tr("SIMMainWindow.html"));

		//New Simulation
		QTreeWidgetItem *SIMNew = new QTreeWidgetItem(Simulator);
		SIMNew->setText(0, tr("New Simulation"));
		SIMNew->setData(1,0, tr("SIMNew.html"));

		//Open Simulation
		QTreeWidgetItem *SIMOpen = new QTreeWidgetItem(Simulator);
		SIMOpen->setText(0, tr("Open Simulation"));
		SIMOpen->setData(1,0, tr("SIMOpen.html"));

		//Save Simulation
		QTreeWidgetItem *SIMSave = new QTreeWidgetItem(Simulator);
		SIMSave->setText(0, tr("Save Simulation"));
		SIMSave->setData(1,0, tr("SIMSave.html"));

		//Events Pane
		QTreeWidgetItem *SIMEvents = new QTreeWidgetItem(Simulator);
		SIMEvents->setText(0, tr("Events Pane"));
		SIMEvents->setData(1,0, tr("SIMEventsPane.html"));

		//States Pane
		QTreeWidgetItem *SIMStates = new QTreeWidgetItem(Simulator);
		SIMStates->setText(0, tr("States Pane"));
		SIMStates->setData(1,0, tr("SIMStatesPane.html"));

		//Simulation Modes
		QTreeWidgetItem *SIMMode = new QTreeWidgetItem(Simulator);
		SIMMode->setText(0, tr("Simulation Modes"));
		SIMMode->setData(1,0, tr("SIMMode.html"));

		//Run Simulation
		QTreeWidgetItem *SIMRun = new QTreeWidgetItem(Simulator);
		SIMRun->setText(0, tr("Run Simulation"));
		SIMRun->setData(1,0, tr("SIMRun.html"));

		//Simulation Viewers
		QTreeWidgetItem *SIMViewer = new QTreeWidgetItem(Simulator);
		SIMViewer->setText(0, tr("Simulation Viewers"));
		SIMViewer->setData(1,0, tr("SIMViewer.html"));

	
}

//_________________________________________________________________________________________________

void HelpBrowser::updateWindowTitle(const QUrl &newPage)
{
	setWindowTitle(tr("DESpot Help: %1").arg(contentTextBrowser->documentTitle()));
	
	//update index tree selection and exapnisons
	QString data;
	QString thisPage = newPage.toString();
	QTreeWidgetItemIterator it(indexTree);
    	while (*it)
	{
		data = ((*it)->data(1,0)).toString();
		if (thisPage.contains(data)){
			(*it)->setSelected(true);
			QTreeWidgetItem *tempItem = (*it);
			while (tempItem->parent()){
				tempItem = tempItem->parent();
				tempItem->setExpanded(true);				
			}
		}else {
			(*it)->setSelected(false);}
		++it;
	}
}

//________________________________________________________________________________________________

void HelpBrowser::updateColumnSize()
{
	indexTree->resizeColumnToContents(0);
}

//_________________________________________________________________________________________________

void HelpBrowser::start()
{
	const QString startPage = "About.html";
	QString path = "qrc:/resources/helpfiles";
	HelpBrowser *browser = new HelpBrowser(path, startPage);
	browser->resize(815,600);
	browser->show();
}

//_________________________________________________________________________________________________

void HelpBrowser::setSource(QString &pageCurrent)
{
	contentTextBrowser->setSource(pageCurrent);
}

//_________________________________________________________________________________________________

void HelpBrowser::updatePage(QTreeWidgetItem *current)
{
	contentTextBrowser->setSource(current->data(1,0).toString());
}

//_________________________________________________________________________________________________

void HelpBrowser::enableFindButton(const QString &keyword)
{
	findButton->setEnabled(!keyword.isEmpty());
}

//_________________________________________________________________________________________________

void HelpBrowser::onFindButtonClick()
{
	setWindowTitle(tr("DESpot Help: Searching..."));
	QString keywords = findBox->text(), singleQuote = "'",amper = " & ", results="";
	int r, keywordsInsertIndex, resultsInsertIndex;
	
	//gather search term(s)
	QStringList searchTerms = keywords.split(",", QString::SkipEmptyParts, Qt::CaseInsensitive);

	//html template for search results
	QString outputHtml = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'><html><head><title>Search Results</title><meta http-equiv='content-type' content='text/html; charset=UTF-8'><style type='text/css'>body {margin-left: 10%;margin-right: 10%;font-family: sans-serif;}h1,h2,h3,h4,h5,h6 { margin-left: -3% }</style></head><body><h1>Search Results for </h1><hr /><p></p></body></html>";
	keywordsInsertIndex = outputHtml.indexOf("</h1>");
	
	if(searchTerms.size() <= 0)
	{
		QMessageBox::StandardButton noKeys;
   		noKeys = QMessageBox::warning(this, tr("Search Error"),
		tr("No valid search keyword entered"),
		QMessageBox::Ok);		
		return;
	}else if(searchTerms.size() >= 4)
	{
		QMessageBox::StandardButton manyKeys;
   		manyKeys = QMessageBox::warning(this, tr("Search Error"),
		tr("Please enter fewer search terms"),
		QMessageBox::Ok);		
		return;
	}

	//insert search keyword(s) in SearchResults
	outputHtml.insert(keywordsInsertIndex, singleQuote);
	keywordsInsertIndex += singleQuote.size();
	for (r = 0; r < searchTerms.size()-1; ++r)
	{
		outputHtml.insert(keywordsInsertIndex, searchTerms.at(r) + amper);
		keywordsInsertIndex += searchTerms.at(r).size() + amper.size();
	}
	outputHtml.insert(keywordsInsertIndex, searchTerms.at(r) + singleQuote);

	
	resultsInsertIndex = outputHtml.indexOf("</p>");
	
	QStringList foundPages = allPages;
	
	//narrow down pages containing only all keyword(s)
	for(int w = 0; w < searchTerms.size(); w++)
	{
		foundPages = FindPages(foundPages, searchTerms.at(w));
	}
	
	if(foundPages.size() <= 0){
		results = "No Results Found";
	}else{
		results = AssembleResults(foundPages, searchTerms);
	}

	//insert AssembledResults in SearchResults, and show results
	outputHtml.insert(resultsInsertIndex, results);
	contentTextBrowser->setHtml(outputHtml);
	setWindowTitle(tr("DESpot Help: Search Results"));
}

//_________________________________________________________________________________________________

QStringList HelpBrowser::FindPages(QStringList curPages, QString keyword)
{
	//open each page (from passed list) and search for passed keyword
	int x;
	QString curPage, currHtml, cutOff = "<div align=";
	QStringList newPages;	
	QTextCursor cursor;
	QTextDocument *document = new QTextDocument();

	for (x=0; x < curPages.size(); x++){
		curPage = ":/resources/helpfiles/" + curPages.at(x);
		QFile file(curPage);
		
		if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
		{
			QMessageBox::StandardButton ret;
   			ret = QMessageBox::warning(this, tr("Search Error"),
			tr("File: '%1' not found\n"
			"Would you like to continue searching?").arg(curPages.at(x)),
			QMessageBox::Yes | QMessageBox::No);
			if (ret == QMessageBox::No){
				return newPages;
			}			
		}
		QTextStream in(&file);
		currHtml = in.readAll();
		file.close();
		
		//remove hyperlinks at bottom of page
		currHtml.chop(currHtml.size() - currHtml.lastIndexOf(cutOff, -1, Qt::CaseInsensitive));
		document->setHtml(currHtml);
		cursor = document->find(keyword);		

		if(!cursor.isNull()){
			newPages.append(curPages.at(x));
		}
	}
	return newPages;
}

//_________________________________________________________________________________________________

QString HelpBrowser::AssembleResults(QStringList foundPages, QStringList keywordList)
{
	//open each page passed (final list of 'hit' pages) and assemble results
	int x,r,y, threshold = 50, startTitle, endTitle, keyIndex;
	QString whitespace = " ", foundText, tempText, title, sTitle = "<title>", eTitle = "</title>", results = "", curPage, currHtml, cutOff = "<div align=";
	QTextBlock textBlock;
	QTextCursor cursor, tempCursor;
	QTextDocument *document = new QTextDocument();

	for (x=0; x < foundPages.size(); x++){
		curPage = ":/resources/helpfiles/" + foundPages.at(x);
		QFile file(curPage);
		
		if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
		{
			QMessageBox::StandardButton ret;
   			ret = QMessageBox::warning(this, tr("Search Error"),
			tr("File: '%1' not found\n"
			"Would you like to continue searching?").arg(foundPages.at(x)),
			QMessageBox::Yes | QMessageBox::No);
			if (ret == QMessageBox::No){
				return results;
			}			
		}
		QTextStream in(&file);
		currHtml = in.readAll();
		file.close();
		
		//remove hyperlinks at bottom of page
		currHtml.chop(currHtml.size() - currHtml.lastIndexOf(cutOff, -1, Qt::CaseInsensitive));
		document->setHtml(currHtml);

		//get page title for search results hyperlink
		startTitle = currHtml.indexOf(sTitle,0,Qt::CaseInsensitive) + sTitle.length();
		title = currHtml.remove(0,startTitle);
		endTitle = title.indexOf(eTitle,0,Qt::CaseInsensitive);
		title.chop(title.length() - endTitle);
		
		results += "<a href='" + foundPages.at(x) + "'>" + title +"</a><br />";

		//find each keyword and extract a block of text for each one and add to results with some formating
		for(r = 0; r < keywordList.size(); r++)
		{
			cursor = document->find(keywordList.at(r));
			textBlock = cursor.block();
			foundText = textBlock.text();
			
			if(foundText.length() > threshold*2)
			{
				keyIndex = foundText.indexOf(keywordList.at(r),0,Qt::CaseInsensitive);

				if(keyIndex > threshold*2)
				{
					y = foundText.indexOf(whitespace,keyIndex-threshold,Qt::CaseInsensitive)+1;
					foundText.remove(0,y);
					foundText.insert(0,QString("..."));
					keyIndex = foundText.indexOf(keywordList.at(r),0,Qt::CaseInsensitive);
				}
				if(foundText.length() > threshold*2)
				{
					y = foundText.indexOf(whitespace,keyIndex+threshold,Qt::CaseInsensitive);
					foundText.chop(foundText.length() - y);
					foundText.append(QString("..."));
				}
			}
			//<b>BOLD</b> keyword
			foundText.insert(foundText.indexOf(keywordList.at(r),0,Qt::CaseInsensitive),QString("<b>"));
			foundText.insert(foundText.indexOf(keywordList.at(r),0,Qt::CaseInsensitive) + keywordList.at(r).length(),QString("</b>"));
			results += foundText + "<br />";
			
		}
		results += "<br />";		
	}
	return results;
}

//_________________________________________________________________________________________________

void HelpBrowser::onPrintButtonClick()
{
	try
	{
		HelpPrint print(this);
		if(print.exec()){
			bool images = print.printImages();
			if (print.printAll()){
				bool compact = print.compactForm();
				onPrintAll(images, compact);
			}else{
				onPrintPage(images);
			}
		}
	}
	catch_display_ex()
}

//_________________________________________________________________________________________________

void HelpBrowser::onPrintPage(bool &images)
{
	//determine if the source is "qrc:/resources/helpfiles/Example.html"
	//else it will be just "Example.html"
	//the 'qrc:' prefix occurs when the help browser is loaded into the
	//About.html page initially (without navigating from and then back to About.html)
	//This prefix also exits when a page has been loaded from a hyperlink either
	//from a search result or regular page link
	//The format will become ":reources/helpfiles/Example.html" once this modification
	//has been done
	QString curPage;
	if (contentTextBrowser->source().toString().contains(QString("/")))
	{
		curPage = contentTextBrowser->source().toString();
		curPage.remove(0,3);
		curPage.remove(1,1);
	}else{
		curPage = ":resources/helpfiles/" + contentTextBrowser->source().toString();
	}

	QFile file(curPage);
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		QMessageBox::StandardButton ret;
		ret = QMessageBox::warning(this, tr("Print Error"),
		tr("File: '%1' not found\n").arg(contentTextBrowser->source().toString()),
		QMessageBox::Ok);
		return;
	}

	QString htmlContent;
	QTextStream in(&file);
	htmlContent = in.readAll();
	file.close();

	chopPageLinks(htmlContent);	

	onPrint(htmlContent, images);
}

//_________________________________________________________________________________________________

void HelpBrowser::onPrintAll(bool &images, bool &compact)
{
	//read in all pages and store as one qstring
	QString htmlContent, currHtml;
	int x;
	for (x=0; x < allPages.size(); x++){
		QString curPage = ":resources/helpfiles/" + allPages.at(x);
		QFile file(curPage);
		
		if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
		{
			QMessageBox::StandardButton ret;
   			ret = QMessageBox::warning(this, tr("Print Error"),
			tr("File: '%1' not found\n"
			"Would you like to continue printing?").arg(allPages.at(x)),
			QMessageBox::Yes | QMessageBox::No);
			if (ret == QMessageBox::No){
				return;
			}			
		}else{
			QTextStream in(&file);
			currHtml = in.readAll();
			chopPageLinks(currHtml);
			htmlContent += currHtml;
			file.close();
		}
	}

	//insert page breaks if user does not select compact form
	if (!compact){
		QString keyword = "</body>";
		QString pageBreak = "<div style='page-break-after: always'></div>";
		int x = 0;
		int y = -1;
		x = htmlContent.indexOf(keyword, x);
		while (x != -1){
			htmlContent.insert(x, pageBreak);
			x += pageBreak.size() + keyword.size();
			x = htmlContent.indexOf(keyword, x, Qt::CaseInsensitive);
			y = htmlContent.lastIndexOf(keyword, -1, Qt::CaseInsensitive);
			if (x == y){
				break;
			}
		}		
	}
	onPrint(htmlContent, images);	
}

//_________________________________________________________________________________________________

void HelpBrowser::onPrint(QString &htmlContent, bool &images)
{
	//prints the document of passed html

	//if user selects to print images call adjust image links
	if (images){
		adjustImageLinks(htmlContent);
	}

	QTextDocument *document = new QTextDocument();
	document->setHtml(htmlContent);

	QPrinter printer(QPrinter::HighResolution);

	QPrintDialog *dialog = new QPrintDialog(&printer, this);
	if (dialog->exec() != QDialog::Accepted)
		return;

	document->print(&printer);

	delete document;
}

//_________________________________________________________________________________________________

QString HelpBrowser::adjustImageLinks(QString &html)
{
	//adjusts file paths to correctly locate images
	QString keyword = "<img src=", resources = ":resources/", image = resources + "helpfiles/";
	int x = html.indexOf(keyword, 0, Qt::CaseInsensitive);
	while (x != -1){
		x += keyword.size() + 1;
		if (html[x] == '.'){	//for images in resources folder (1 dir up)
			html.remove(x,3);
			html.insert(x, resources);
		}else if(html[x] == 'i'){	//for images in help file images (sub dir)
			html.insert(x, image);
		}else{	//something is wrong with the img html tags
			QMessageBox::StandardButton invalidFile;
   			invalidFile = QMessageBox::warning(this, tr("DESpot Error"),
			tr("Some images may not be printed due to an internal error."),
			QMessageBox::Ok);
		}
		x = html.indexOf(keyword, x, Qt::CaseInsensitive);		
	}
	return html;
}

//_________________________________________________________________________________________________

QString HelpBrowser::chopPageLinks(QString &html)
{
	//removes the <div> containing the page links at end of html page
	QString lastLine = "<div", endCut = "</div>";
	html.remove(html.lastIndexOf(lastLine, -1, Qt::CaseInsensitive), html.lastIndexOf(endCut, -1, Qt::CaseInsensitive) - html.lastIndexOf(lastLine, -1, Qt::CaseInsensitive) + endCut.size());
	return html;
}

//_________________________________________________________________________________________________

void HelpBrowser::onOpenAboutHelp()
{
	try
	{
		AboutHelpDlg aboutHelp(this);
		aboutHelp.exec();
	}
	catch_display_ex()
}

} //end of namespace DESpot

