/*****************************************************************************/
/*  Copyright 2021 WSL Institute for Snow and Avalanche Research  SLF-DAVOS  */
/*****************************************************************************/
/* This file is part of INIshell.
   INIshell 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 3 of the License, or
   (at your option) any later version.

   INIshell 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 INIshell.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "AboutWindow.h"
#include "HelpWindow.h"
#include "src/main/inishell.h"
#include "src/main/XMLReader.h"

#include <QCoreApplication>
#include <QDesktopServices>
#include <QMenuBar>

#ifdef DEBUG
	#include <iostream>
#endif

/**
 * @class HelpWindow
 * @brief Constructor for the Help window.
 * @param[in] parent The window's parent.
 */
HelpWindow::HelpWindow(QMainWindow *parent) : QMainWindow(parent)
{

	/* create a scroll area and put a Group in it */
	help_tab_ = new SectionTab();
	this->setCentralWidget(help_tab_);

	this->setWindowTitle(tr("Help") + " ~ " + QCoreApplication::applicationName());
	createMenu();
}

/**
 * @brief Open and show the help file.
 * @param[in] dev If true, load the developer's guide. If false, load the user guide.
 */
void HelpWindow::loadHelp(const bool &dev)
{
	static bool is_loaded = false;
	if (!is_loaded | dev) {
		help_tab_->clear();
		XMLReader xmlr;
		QString err;
		QString help_file( "help.xml" );
		if (dev)
			help_file = "help_dev.xml";
		xmlr.read(":doc/" + help_file, err);
#ifdef DEBUG
		if (!err.isEmpty())
			qDebug() << "There is an error in a help XML: " << err;
#endif //def DEBUG
		QDomDocument xml(xmlr.getXml());
		buildGui(xml, help_tab_);
		is_loaded = true && !dev; //reload after opening dev
	}

	view_dev_help_->setChecked(dev);
	view_user_guide_->setChecked(!dev);
	this->show();
	this->raise();
}

/**
 * @brief Listener for key events.
 * @details Close the help on pressing ESC or display the logger.
 * @param[in] event The key press event that is received.
 */
void HelpWindow::keyPressEvent(QKeyEvent *event)
{
	if (event->key() == Qt::Key_Escape || keyToSequence(event) == QKeySequence::Close) {
		this->close();
	} else if (event->modifiers() == Qt::CTRL && event->key() == Qt::Key_L) {
		getMainWindow()->getLogger()->show();
		getMainWindow()->getLogger()->raise();
	}
}

/**
 * @brief Build the Help window's menu items.
 */
void HelpWindow::createMenu()
{
	/* FILE menu */
	QMenu *menu_file = this->menuBar()->addMenu(tr("&File"));
	auto *file_close = new QAction(getIcon("application-exit"), tr("&Close help"), menu_file);
	file_close->setShortcut(QKeySequence::Close);
	menu_file->addAction(file_close);
	connect(file_close, &QAction::triggered, this, [=]{ this->close(); });

	/* VIEW menu */
	QMenu *menu_view = this->menuBar()->addMenu(tr("&View"));
	view_user_guide_ = new QAction(tr("&User guide"), menu_view); //no icon to get checkboxes
	view_user_guide_->setCheckable(true);
	view_user_guide_->setChecked(true);
	menu_view->addAction(view_user_guide_);
	view_user_guide_->setShortcut(QKeySequence::HelpContents);
	connect(view_user_guide_, &QAction::triggered, this, [=]{ loadHelp(); });
	view_dev_help_ = new QAction(tr("&Developer's guide"), menu_view);
	view_dev_help_->setCheckable(true);
	view_dev_help_->setShortcut(Qt::Key_F2);
	menu_view->addAction(view_dev_help_);
	connect(view_dev_help_, &QAction::triggered, this, [=]{ loadHelp(true); });
	menu_view->addSeparator();
#if !defined Q_OS_MAC //we have this from the main window in unified menu
	auto *help_about = new QAction(getIcon("help-about"), tr("&About"), menu_view);
	help_about->setMenuRole(QAction::AboutRole);
	menu_view->addAction(help_about);
	connect(help_about, &QAction::triggered, this, &HelpWindow::helpAbout);
	help_about->setShortcut(QKeySequence::WhatsThis);
#endif
	auto *view_online_help = new QAction(tr("View &online help..."), menu_view);
	menu_view->addAction(view_online_help);
	connect(view_online_help, &QAction::triggered, this,
		[=]{ QDesktopServices::openUrl(QUrl("https://models.slf.ch/p/inishell-ng/doc/")); });
	auto *view_file_bugreport_ = new QAction(tr("File &bug report..."), menu_file);
	menu_view->addAction(view_file_bugreport_);
	connect(view_file_bugreport_, &QAction::triggered,
		[]{ QDesktopServices::openUrl(QUrl("https://models.slf.ch/p/inishell-ng/issues/")); });
	auto *show_paper = new QAction(tr("Show &paper..."), menu_view);
	menu_view->addAction(show_paper);
	connect(show_paper, &QAction::triggered, this, [=]{ QDesktopServices::openUrl(QUrl(":doc/paper.pdf")); });
	show_paper->setEnabled(false);
}

/**
 * @brief Display the 'About' window.
 */
void HelpWindow::helpAbout()
{
	getMainWindow()->helpAbout(); //parent to main to avoid showing twice
}
