//-----------------------------------------------------------------------------
//  Copyright (C) 2002-2025 Thomas S. Ullrich
//
//  This file is part of "xyscan".
//
//  This file may be used under the terms of the GNU General Public License.
//  This project is free software; you can redistribute it and/or modify it
//  under the terms of the GNU General Public License.
//  
//  Author: Thomas S. Ullrich
//  Last update: Oct 30, 2025
//-----------------------------------------------------------------------------
#include <QtGui>
#include <QPushButton>
#include <QTextBrowser>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QSpacerItem>
#include <QMessageBox>
#include "xyscanHelpBrowser.h"
 
xyscanHelpBrowser::xyscanHelpBrowser(const QString &descFile, const QString &path) : QWidget(0)
{
	setWindowModality(Qt::NonModal);
    setWindowTitle(tr("Help"));
    setWindowIcon(QIcon(QString::fromUtf8(":/images/xyscanIcon.png")));

    QGridLayout *gridLayout = new QGridLayout(this);
    
    //
    //  Create top row buttons
    //
    QHBoxLayout *hboxLayout = new QHBoxLayout();
    mBackButton = new QPushButton(this);
    mBackButton->setText("<");
    hboxLayout->addWidget(mBackButton);
    mForwardButton = new QPushButton(this);
    mForwardButton->setText(">");
    hboxLayout->addWidget(mForwardButton);
    mHomeButton = new QPushButton(this);
    mHomeButton->setText(tr("Home"));
    hboxLayout->addWidget(mHomeButton);
    QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
    hboxLayout->addItem(spacerItem);
    mCloseButton = new QPushButton(this);
    mCloseButton->setText(tr("Close"));    
    hboxLayout->addWidget(mCloseButton);

    gridLayout->addLayout(hboxLayout, 0, 0, 1, 2);
    gridLayout->setContentsMargins(5, 5, 5, 10);
    gridLayout->setSpacing(5);
    
    //
    //  Create empty tree widget and text edit (browser) window 
    //
    mTreeWidget = new QTreeWidget(this);
    QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
    mTreeWidget->setSizePolicy(sizePolicy);
    mTreeWidget->setMaximumWidth(220);
    mTreeWidget->headerItem()->setHidden(true); // not needed
    mTreeWidget->clear();
    gridLayout->addWidget(mTreeWidget, 1, 0, 1, 1);
    
    mTextBrowser = new QTextBrowser(this);
    gridLayout->addWidget(mTextBrowser, 1, 1, 1, 1);

    resize(QSize(980, 450));

    //
    //  Setup index and search path
    //
    createIndex(descFile);
    mTextBrowser->setSearchPaths(QStringList(path));
    
    //
    //  Connect signals and slots
    //
    connect(mCloseButton, &QPushButton::clicked, this, &QWidget::hide);
    connect(mHomeButton, &QPushButton::clicked, this, &xyscanHelpBrowser::goHome);
    connect(mBackButton, &QPushButton::clicked, this, &xyscanHelpBrowser::goBackward);
    connect(mForwardButton, &QPushButton::clicked, this, &xyscanHelpBrowser::goForward);
    connect(mTextBrowser, &QTextBrowser::sourceChanged, this, &xyscanHelpBrowser::updateCaption);
    connect(mTreeWidget, &QTreeWidget::currentItemChanged, this, [this](QTreeWidgetItem* current, QTreeWidgetItem*){ itemSelected(current); });
    connect(mTextBrowser, &QTextBrowser::forwardAvailable, mForwardButton, &QPushButton::setEnabled);
    connect(mTextBrowser, &QTextBrowser::backwardAvailable, mBackButton, &QPushButton::setEnabled);

    //
    //  Start with home page (first item)
    //
    itemSelected(mTreeWidget->topLevelItem(0));
}

void xyscanHelpBrowser::createIndex(const QString &desc)
{
    QFile file(desc);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QMessageBox::warning( 0, "xyscan",
                              tr("Cannot open the index descriptor file to setup the documentation. "
                              "No online help will be available. "
                              "Check your installation and reinstall if necessary."));
        return;
    }
    
    QTextStream in(&file);
    QString line;
    QTreeWidgetItem *lastTop = nullptr;
    QTreeWidgetItem *item;
    do {
        line = in.readLine();
        if (!(line.isNull() || line.startsWith('#'))) {
            //
            // Got valid descriptor line
            //
            QStringList list = line.split(',');
            if (list.size() != 3) continue;  // need 3 items to work with
            if (list[0] == "0") {
                item = new QTreeWidgetItem(mTreeWidget);
                item->setText(0,list[1]);
                lastTop = item;
                item->setData(0, Qt::UserRole, list[2]);
                mMap.insert(list[2], item);
            }
            else if (list[0] == "1") {
                if (lastTop) {
                    item = new QTreeWidgetItem(lastTop);
                    item->setText(0,list[1]);                    
                    item->setData(0, Qt::UserRole, list[2]);
                    mMap.insert(list[2], item);
                }
            }
            // no 3 level indentation implemented
        }
    } 
    while (!in.atEnd());
}

void xyscanHelpBrowser::goHome()
{
    mTextBrowser->home();
    sync();
}

void xyscanHelpBrowser::goForward()
{
    mTextBrowser->forward();
    sync();
}

void xyscanHelpBrowser::goBackward()
{
    mTextBrowser->backward();
    sync();
}

void xyscanHelpBrowser::itemSelected(QTreeWidgetItem* item)
{
    if (item && mTreeWidget) {
        QString filename = item->data(0, Qt::UserRole).toString();
        showPage(filename);
    }
}

void xyscanHelpBrowser::showPage(const QString &filename)
{
    if (mTextBrowser) mTextBrowser->setSource(filename);
}

void xyscanHelpBrowser::sync()
{
    QString str = mTextBrowser->source().fileName();
    QTreeWidgetItem *item = mMap[str];
    mTreeWidget->setCurrentItem(item);
}

void xyscanHelpBrowser::updateCaption()
{
    setWindowTitle(tr("Help: %1").arg(mTextBrowser->documentTitle()));
}


