/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include "MvQHelpBrowser.h"
#include "MvQWebViewSearchLine.h"
#include "MvQSearchLinePanel.h"

#include <QAction>
#include <QApplication>
#include <QCloseEvent>
#include <QDebug>
#include <QDesktopServices>
#include <QDialogButtonBox>
#include <QFileInfo>
#include <QHBoxLayout>
#include <QHelpContentWidget>
#include <QHelpEngine>
#include <QHelpIndexWidget>
#include <QLabel>
#include <QLineEdit>
#include <QList>
#include <QNetworkAccessManager>
#include <QPushButton>
#include <QSettings>
#include <QSplitter>
#include <QString>
#include <QTabWidget>
#include <QTextBrowser>
#include <QUrl>
#include <QVariant>
#include <QVBoxLayout>
#include <QWebView>
#include <QWebPage>

MvQHelpBrowser::MvQHelpBrowser(QWidget *parent) : MvQMainWindow(parent)
{		
	//setAttribute(Qt::WA_DeleteOnClose);
	
	setWindowTitle("Metview - Help");
	
	//Initial size
	setInitialSize(1100,800);

	//--------------------------------------
	//Set the help engine
	//--------------------------------------

    //QFileInfo fileInfo("/tmp/dummy-user/metview_qt_documentation/metview_confluence/metview_collection.qhc");
	const QString share_dir = QString(getenv("METVIEW_DIR_SHARE"));
    QFileInfo fileInfo(share_dir + QString("/etc/metview_collection.qhc"));
	QHelpEngine* engine_= new QHelpEngine(fileInfo.absoluteFilePath(),this);
	engine_->setupData();

	//--------------------------------------
	//Main Layout - splitter
	//--------------------------------------

	QWidget* w = new QWidget(this);
	QVBoxLayout *mainLayout = new QVBoxLayout(w);
	mainLayout->setSpacing(0); 
	mainLayout->setContentsMargins(1,1,1,1);

	setCentralWidget(w);

	//Splitter
	splitter_=new QSplitter(this);
	mainLayout->addWidget(splitter_);

	//--------------------------------------
	//Left - tab Content
	//--------------------------------------

	
	QTabWidget* tab=new QTabWidget(this);
	splitter_->addWidget(tab);
	
	tab->addTab(engine_->contentWidget(),tr("Content"));

	//--------------------------------------
	//Left - tab Index
	//--------------------------------------

	lookFor_label_ = new QLabel(tr("Look for:"),this);
	lookFor_edit_ = new QLineEdit(this);
	lookFor_label_->setBuddy(lookFor_edit_);
	connect(lookFor_edit_ ,SIGNAL(textChanged(const QString&)),	engine_->indexWidget(),SLOT(filterIndices(const QString&)));

	QWidget* itab_w = new QWidget(this);
	QVBoxLayout* ilayout = new QVBoxLayout(itab_w);
	ilayout->addWidget(lookFor_label_);
	ilayout->addWidget(lookFor_edit_);
	ilayout->addWidget(engine_->indexWidget());

	tab->addTab(itab_w,tr("Index"));

	//--------------------------------------
	//Right - content view widget
	//--------------------------------------

	//set web view text encoding
	webView_ = new QWebView(this);
	webView_->settings()->setDefaultTextEncoding("utf-8");

	//set the documentation css style
	//QUrl myCssFileURL= QUrl("file:///tmp/dummy-user/metview_qt_documentation/metview_confluence/METV/styles/site.css");

	//ini juanjo 03.09.2013
	//QUrl myCssFileURL= QUrl(QString("file://")+share_dir+QString("/etc/help.css"));
	//webView_->settings()->setUserStyleSheetUrl(myCssFileURL);
	//end juanjo 03.09.2013


	//use a request manager able to handle "qthelp" requests
	QNetworkAccessManager *current_manager = webView_->page()->networkAccessManager();
	MvHelpNetworkAccessManager* newManager = new MvHelpNetworkAccessManager(engine_, current_manager, this);
	webView_->page()->setNetworkAccessManager(newManager);
	webView_->page()->setForwardUnsupportedContent(false);

	QWebPage *page_  = webView_->page();
	page_->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks);

	connect(engine_->contentWidget(),SIGNAL(linkActivated(const QUrl&)),this,SLOT(setWebSource(const QUrl&)));
	connect(engine_->indexWidget(),SIGNAL(linkActivated(const QUrl&,const QString &)),this,SLOT(setWebSource(const QUrl&)));
	connect(webView_,SIGNAL(linkClicked(const QUrl&)),this,SLOT(setWebSource(const QUrl&)));

	//--------------------------------------
	//Right - content view layout
	//--------------------------------------

	QWidget* rw=new QWidget(this);
	QVBoxLayout *rLayout = new QVBoxLayout(rw);
	rLayout->setSpacing(0);
	rLayout->addWidget(webView_);
	rLayout->setStretchFactor(webView_,1);

	//--------------------------
	// Right - Find widget
	//--------------------------

	search_= new MvQWebViewSearchLine(webView_,tr("&Find:"));
	searchPanel_ = new MvQSearchLinePanel();
	searchPanel_->addSearchLine(search_,webView_);
	searchPanel_->setHidden(true);
	rLayout->addWidget(searchPanel_);
	splitter_->addWidget(rw);

	//--------------------------------------
	// Setup actions for toolbars and menus
	//--------------------------------------

	setupNavigateActions();
	setupHelpActions();
	setupSearchActions();

	setupMenus(menuItems_);

	//-------------------------
	// Settings
	//-------------------------

	readSettings();

	//-------------------------
	// Load documentation home page
	//-------------------------

	docHome();
}

MvQHelpBrowser::~MvQHelpBrowser()
{	

	writeSettings();
}

void MvQHelpBrowser::closeEvent(QCloseEvent* event)
{
	//emit aboutToClose(this);
	close();
	event->accept();
}

void MvQHelpBrowser::setupSearchActions()
{
	//Find
	QAction * actionFind_=MvQMainWindow::createAction(MvQMainWindow::FindAction,this);
	connect(actionFind_,SIGNAL(triggered(bool)),searchPanel_,SLOT(setHidden(bool)));

	//Find Next
	QAction *actionFindNext_=MvQMainWindow::createAction(MvQMainWindow::FindNextAction,this);
	connect(actionFindNext_,SIGNAL(triggered(bool)),searchPanel_,SLOT(slotFindNext(bool)));

	//Find Previous
	QAction *actionFindPrev_=MvQMainWindow::createAction(MvQMainWindow::FindPreviousAction,this);
	connect(actionFindPrev_,SIGNAL(triggered(bool)),searchPanel_,SLOT(slotFindPrev(bool)));

	MvQMainWindow::MenuType menuType=MvQMainWindow::EditMenu;

	menuItems_[menuType].push_back(new MvQMenuItem(actionFind_,MvQMenuItem::MenuTarget));
	menuItems_[menuType].push_back(new MvQMenuItem(actionFindNext_,MvQMenuItem::MenuTarget));
	menuItems_[menuType].push_back(new MvQMenuItem(actionFindPrev_,MvQMenuItem::MenuTarget));
}

void MvQHelpBrowser::setupNavigateActions()
{
 	//Back
	actionBack_ = new QAction(this);
	actionBack_->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowLeft));
    actionBack_->setToolTip(tr("Back"));
	actionBack_->setText(tr("Back"));
    actionBack_->setShortcut(tr("Alt+Left"));

	connect(actionBack_,SIGNAL(triggered()),webView_, SLOT(back()));

	//Forward
	actionForward_ = new QAction(this);
	actionForward_->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowRight));
	actionForward_->setToolTip(tr("Forward"));
	actionForward_->setText(tr("Forward"));
    actionForward_->setShortcut(tr("Alt+Right"));

	connect(actionForward_,SIGNAL(triggered()),webView_,SLOT(forward()));

	//Home
	actionHome_= new QAction(this);
	actionHome_->setIcon(QPixmap(QString::fromUtf8(":/desktop/home.svg")));
    actionHome_->setToolTip(tr("Metview Documentation home"));
	actionHome_->setText(tr("Mv Doc home"));
	actionHome_->setIconText(tr("home"));
    actionHome_->setShortcut(tr("Alt+Home"));

	connect(actionHome_,SIGNAL(triggered()),this,SLOT(docHome()));

	QAction *sep=new QAction(this);
	sep->setSeparator(true);

	MvQMainWindow::MenuType menuType=MvQMainWindow::NavigateMenu;

	menuItems_[menuType].push_back(new MvQMenuItem(actionBack_));
	menuItems_[menuType].push_back(new MvQMenuItem(actionForward_));
	menuItems_[menuType].push_back(new MvQMenuItem(sep,MvQMenuItem::MenuTarget));
	menuItems_[menuType].push_back(new MvQMenuItem(actionHome_));

}

void MvQHelpBrowser::setupHelpActions()
{
	// About
	QAction *actionAbout = new QAction(this);
	actionAbout->setObjectName(QString::fromUtf8("actionAbout"));
	QIcon icon;
	icon.addPixmap(QPixmap(QString::fromUtf8(":/window/metview_logo")), QIcon::Normal, QIcon::Off);
	actionAbout->setIcon(icon);
	actionAbout->setText(tr("&About HelpBrowser"));

	connect(actionAbout, SIGNAL(triggered()), this, SLOT(slotShowAboutBox()));

	MvQMainWindow::MenuType menuType=MvQMainWindow::HelpMenu;

	menuItems_[menuType].push_back(new MvQMenuItem(actionAbout,MvQMenuItem::MenuTarget));
}

void MvQHelpBrowser::docHome()
{
	webView_->load(QUrl("qthelp://int.wcmwf.metview.userguide/doc/METV/index.html"));
}

void MvQHelpBrowser:: setWebSource(const QUrl &url)
{
	//qDebug() << "setWebSource url=" << url.toString();
	if (url.scheme() == "qthelp")
		webView_->load(url);
	else
		QDesktopServices::openUrl(url);
	//for(int i=0; i < webView_->history()->count(); i++) qDebug() << "item" << i << webView_->history()->itemAt(i).url();
}

void MvQHelpBrowser::writeSettings()
{
	QSettings settings("ECMWF","MV4-HelpBrowser");

	settings.clear();

	settings.beginGroup("mainWindow");
	settings.setValue("geometry",saveGeometry());
	settings.setValue("splitter",splitter_->saveState());
	settings.endGroup();
}

void MvQHelpBrowser::readSettings()
{
	QSettings settings("ECMWF","MV4-HelpBrowser");

	settings.beginGroup("mainWindow");
	restoreGeometry(settings.value("geometry").toByteArray());
	splitter_->restoreState(settings.value("splitter").toByteArray());
	settings.endGroup();
}

///////////////////////////////////////
//#include "MvHelpNetworkAccessManager.h"
#include <QByteArray>
#include <QHelpEngine>
#include <QIODevice>
#include <QNetworkAccessManager>
#include <QNetworkProxy>
#include <QPointer>
#include <QTimer>
#include <QNetworkReply>

MvHelpNetworkReply::MvHelpNetworkReply(const QUrl& url, QHelpEngineCore* help_engine): QNetworkReply(help_engine)
{
    Q_ASSERT(help_engine);

    d_help_engine = help_engine;
    setUrl(url);
    QTimer::singleShot(0, this, SLOT(process()));
}

void MvHelpNetworkReply::process()
{
    if (d_help_engine) {
        QByteArray rawData = d_help_engine->fileData(url());
        d_buffer.setData(rawData);
        d_buffer.open(QIODevice::ReadOnly);

        open(QIODevice::ReadOnly|QIODevice::Unbuffered);
        setHeader(QNetworkRequest::ContentLengthHeader, QVariant(rawData.size()));
        setHeader(QNetworkRequest::ContentTypeHeader, "text/html");
        emit readyRead();
        emit finished();
    }
}
