/* vokoscreenNG - A desktop recorder
 * Copyright (C) 2017-2019 Volker Kohaupt
 * 
 * Author:
 *      Volker Kohaupt <vkohaupt@freenet.de>
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 *
 * 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * --End_License--
 */

#include "QvkHelp.h"
#include "QvkLocale.h"
#include "global.h"

#include <QMessageBox>
#include <QLabel>
#include <QDir>
#include <QTextDocument>
#include <QSettings>

/*
 * The remote HTML-file and the toolbutton have the same name.
 *
 * Example:
 * QToolbutton -> help_screencast_fullscreen
 * Remote file -> help_screencast_fullscreen.html
 *
 * We write as snake_case, so the underline character is the seperator.
 * The first section is help, this we need for set for icon and installEventFilter, see constructor.
 * The second section is the tab in the sidebar and the subdir on remote.
 * The third section is the name from the function that we want help.
 * See also QvkHelp::eventFilter(QObject *object, QEvent *event)
 */

QvkHelp::QvkHelp( Ui_formMainWindow *ui_mainwindow ) : uiHelp(new(Ui::help))
{
    ui = ui_mainwindow;
    uiHelp->setupUi( this );

    slot_NetworkAccessibility( networkAccessManager.networkAccessible() );
    connect( &networkAccessManager, SIGNAL( networkAccessibleChanged( QNetworkAccessManager::NetworkAccessibility ) ),
                                    SLOT( slot_NetworkAccessibility( QNetworkAccessManager::NetworkAccessibility ) ) );

    resize( 800, 600 );
    setWindowTitle( QString( tr( "Help") ) );

    QIcon icon;
    icon.addFile( QString::fromUtf8( ":/pictures/logo/logo.png" ), QSize(), QIcon::Normal, QIcon::Off );
    setWindowIcon( icon );

    QStringList helpStringList;
    helpStringList << "https:/"
                   << "vokoscreen.volkoh.de"
                   << "3.0"
                   << "help";

    vk_helpPath = helpStringList.join( "/" ).append( "/");

    QvkLocale *vkLocale = new QvkLocale();
    connect( vkLocale, SIGNAL( signal_locale( QStringList) ), this, SLOT( slot_parse_locale( QStringList ) ) );

    vkDownloadHTML = new QvkDownloader( temporaryDirLocal.path() );
    vkDownloadFiles = new QvkDownloader( temporaryDirLocal.path() );

    QIcon iconHelp( ":/pictures/help/information.png" );
    QList<QToolButton *> listToolButton = ui->centralWidget->findChildren<QToolButton *>();
    for ( int i = 0; i < listToolButton.count(); i++ )
    {
        if ( listToolButton.at(i)->objectName().contains( QRegExp( "^help_") ) )
        {
            listToolButton.at(i)->setIcon( iconHelp );
            listToolButton.at(i)->installEventFilter( this );
        }
    }
}


QvkHelp::~QvkHelp()
{
}


void QvkHelp::slot_parse_locale( QStringList list )
{
    for ( int i = 0; i < list.count(); i++  )
    {
       QLocale locale( list.at( i ) );
       ui->comboBoxOnlineHelp->addItem( locale.nativeLanguageName() + " " + "(" + list.at(i) + ")", list.at( i ) );
    }

    QSettings settings( QSettings::IniFormat, QSettings::UserScope, global::name, global::name, Q_NULLPTR );
    QString valueText = settings.value( ui->comboBoxOnlineHelp->objectName(), "" ).toString();
    int valueInt = ui->comboBoxOnlineHelp->findText( valueText );
    if ( valueInt > -1 )
    {
        ui->comboBoxOnlineHelp->setCurrentIndex( valueInt );
    }
}


void QvkHelp::slot_NetworkAccessibility( QNetworkAccessManager::NetworkAccessibility accessible )
{
    QList<QToolButton *> listToolButton = ui->centralWidget->findChildren<QToolButton *>();
    for ( int i = 0; i < listToolButton.count(); i++ )
    {
        if ( listToolButton.at(i)->objectName().contains( QRegExp( "^help_") ) )
        {
            if ( accessible == QNetworkAccessManager::Accessible )
            {
               listToolButton.at(i)->setEnabled( true );
            }

            if ( accessible == QNetworkAccessManager::NotAccessible )
            {
               listToolButton.at(i)->setEnabled( false );
            }
        }
    }

    if ( accessible == QNetworkAccessManager::Accessible )
    {
        ui->comboBoxOnlineHelp->setEnabled( true );
    }

    if ( accessible == QNetworkAccessManager::NotAccessible )
    {
        ui->comboBoxOnlineHelp->setEnabled( false );
    }
}


bool QvkHelp::eventFilter(QObject *object, QEvent *event)
{
    QToolButton *toolButton = qobject_cast<QToolButton *>(object);

    // Automatic language detection is set in combobox for the online help.
    if ( ( event->type() == QEvent::MouseButtonRelease ) and
         ( toolButton->isEnabled() == true ) and
         ( ui->comboBoxOnlineHelp->currentIndex() == 0 ) )
    {

        QString language;
        if ( ui->comboBoxOnlineHelp->findText( "(" + QLocale::system().name() + ")", Qt::MatchEndsWith ) > -1 )
        {
            language = QLocale::system().name();
        }
        else
        {
            language = "en";
        }

        QString vk_helpPath_locale = vk_helpPath + language + "/";

        loadHTML( vk_helpPath_locale + object->objectName().section( "_", 1, 1 ) + "/" + object->objectName() + ".html" );
        uiHelp->labelURL->setText( vk_helpPath_locale + object->objectName().section( "_", 1, 1 ) + "/" + object->objectName() + ".html" );

        return false;
    }

    // Selected Language is set in combobox
    if ( ( event->type() == QEvent::MouseButtonRelease ) and
         ( toolButton->isEnabled() == true ) and
         ( ui->comboBoxOnlineHelp->currentIndex() > 0 ) )
    {
        QString language = ui->comboBoxOnlineHelp->currentText().section( "(", 1 ).replace( ")", "" );
        QString vk_helpPath_locale = vk_helpPath + language + "/";
        loadHTML( vk_helpPath_locale + object->objectName().section( "_", 1, 1 ) + "/" + object->objectName() + ".html" );
        uiHelp->labelURL->setText( vk_helpPath_locale + object->objectName().section( "_", 1, 1 ) + "/" + object->objectName() + ".html" );
        return false;
    }
    else
    {
        return QObject::eventFilter( object, event );
    }
}


void QvkHelp::slot_cleanUp()
{
    temporaryDirLocal.remove();
}


/*
 * To first we load the html file ...
 */
void QvkHelp::loadHTML( QString value )
{
    QFileInfo fileInfo( value );
    remotePath = fileInfo.path();
    remoteBasename = fileInfo.baseName();
    disconnect( vkDownloadHTML, nullptr, nullptr, nullptr );
    connect( vkDownloadHTML, SIGNAL( signal_fileDownloaded( QString ) ), this, SLOT( slot_parseHTML( QString ) ) );
    vkDownloadHTML->doDownload( value );
}


bool QvkHelp::isFileInLine( QString line )
{
    bool value = false;
    for ( int i = 0; i < toDownloadFiles.count(); i++ )
    {
        if ( line.contains( toDownloadFiles.at(i), Qt::CaseInsensitive ) )
        {
            value = true;
            break;
        }
        else
        {
            value = false;
        }
    }
    return value;
}


int QvkHelp::getCountFileToDownload( QString tempPathFileName )
{
    QFile file( tempPathFileName );
    if( !file.open( QIODevice::ReadOnly ) )
    {
        qDebug().noquote() << global::nameOutput << "QvkHelp::getCountFileToDownload" << tempPathFileName  << file.errorString();
        //QMessageBox::information( nullptr, "Help error", "QvkHelp::getCountFileToDownload\n" + tempPathFileName + "\n" + file.errorString() );
    }

    int count = 0;
    QTextStream textStream( &file );
    while( !textStream.atEnd() )
    {
        QString line = textStream.readLine();
        if ( isFileInLine( line ) )
        {
            count++;
        }
    }
    file.close();
    return count;
}


/*
 * ... then we parse *.html of files and download all files from remote Url and save local in tmp ...
 */
void QvkHelp::slot_parseHTML( QString tempPathFileName )
{
    localFiles.clear();
    localFiles << tempPathFileName;

    QFileInfo fileInfo( tempPathFileName );
    QString tmpPath = fileInfo.absolutePath();

    QFile file( tempPathFileName );
    if( !file.open( QIODevice::ReadOnly ) )
    {
        qDebug().noquote() << global::nameOutput << "QvkHelp::slot_parseHTML" << tempPathFileName  << file.errorString();
        //QMessageBox::information( nullptr, global::name + " " + global::version, "QvkHelp::slot_parseHTML\n" + tempPathFileName + "\n" + file.errorString() );
        return;
    }

    int countFiles = getCountFileToDownload( tempPathFileName );
    int counter = 0;
    QTextStream textStream( &file );
    while( !textStream.atEnd() )
    {
        QString line = textStream.readLine();
        if ( isFileInLine( line ) )
        {
            QString fileForHTML = line.section( "\"", 1, 1 );
            counter++;
            if ( counter == countFiles )
            {
                disconnect( vkDownloadFiles, nullptr, nullptr, nullptr );
                connect( vkDownloadFiles, SIGNAL( signal_fileDownloaded( QString ) ), this, SLOT( slot_showHelp( QString ) ) );
            }
            vkDownloadFiles->doDownload( remotePath + "/" + fileForHTML );
            localFiles << tmpPath + + "/" + fileForHTML;
        }
    }

    if ( counter == 0 )
    {
        // "dummy.png" is a fake, we need this if no file is downlowded
        slot_showHelp( tmpPath + "/" + "dummy.png");
    }

    file.close();
}

/*
 * ... then we show the html file
 */
void QvkHelp::slot_showHelp( QString tempPathFileName )
{
    QDir dir;
    QString currentdir = dir.currentPath();

    QFileInfo fileInfo( tempPathFileName );
    QString tmpPath = fileInfo.absolutePath();
    dir.setCurrent( tmpPath );

    QString htmlFile = tmpPath + "/" + remoteBasename + ".html";
    QFile file( htmlFile );
    if( !file.open( QIODevice::ReadOnly ) )
    {
        qDebug().noquote() << global::nameOutput << "QvkHelp::slot_showHelp" << tempPathFileName  << file.errorString();
        //QMessageBox::information( nullptr, "Help error", "QvkHelp::slot_showHelp\n" + tempPathFileName + "\n" + file.errorString() );
    }

    QString value = QString::fromUtf8( file.readAll() );

    // Antialiasing for Font
    QFont font = uiHelp->textBrowser->font();
    font.setStyleStrategy( QFont::PreferAntialias );
    uiHelp->textBrowser->setFont(font);

    uiHelp->textBrowser->setText( value );

    file.close();

    show();

    dir.setCurrent( currentdir );

    // remove all tmp files
    for ( int i = 0; i < localFiles.count(); i++  )
    {
        QFile file( localFiles.at( i ) );
        file.remove();
    }
}
