/*
 * Copyright (C) 2009-2010  Lorenzo Bettini <http://www.lorenzobettini.it>
 * See COPYING file that comes with this distribution
 */

#include <QtGui>

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "source-highlight-ide.h"
#include "assistant.h"
#include "customhelpform.h"

#include <srchilite/versions.h>
#include <srchilite/settings.h>
#include <srchiliteqt/SourceHighlightSettingsDialog.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QString binDir = QCoreApplication::applicationDirPath ();
    qDebug() << "application path: " << binDir;

    // detect help path
    if (QFile::exists(binDir + "/../share/doc/source-highlight-ide/html/index.html")) {
        helpPath = binDir + "/../share/doc/source-highlight-ide/html";
    } else {
        // fall back to source dir
        helpPath = QString(SOURCEDIR) + "/doc/share/doc/source-highlight-ide/html";
    }

    assistant = new Assistant(helpPath);
    qDebug() << "help path: " << helpPath;

    windowMapper = new QSignalMapper(this);
    connect(windowMapper, SIGNAL(mapped(QWidget *)),
            this, SLOT(setActiveSubWindow(QWidget *)));

    createActions();
    createMenus();

    ui->mdiArea->setViewMode(QMdiArea::TabbedView);

    setWindowTitle("Source-Highlight-Ide");

    //SourceHighlightIde *ideWindow = new SourceHighlightIde();
    //ui->mdiArea->addSubWindow(ideWindow, Qt::Window);

    readSettings();

    if (!checkSourceHighlightSettings())
        return;
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void MainWindow::newFile()
{
    SourceHighlightIde *ideWindow = new SourceHighlightIde();
    ui->mdiArea->addSubWindow(ideWindow);
    ideWindow->show();
}

void MainWindow::openInput()
{
    QString fileName = QFileDialog::getOpenFileName
                       (this, tr("Open a lang file"), "",
                        tr("Lang files (*.lang);;All Files (*)"));
    if (!fileName.isEmpty()) {
        SourceHighlightIde *ideWindow = new SourceHighlightIde();
        ui->mdiArea->addSubWindow(ideWindow);
        ideWindow->openLangFile(fileName);
        ideWindow->show();
    }
}

void MainWindow::createActions()
{
    connect(ui->actionNew, SIGNAL(triggered()), this, SLOT(newFile()));
    connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(openInput()));

    connect(ui->actionExit, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));

    connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));

    connect(ui->actionAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));

    // these are not created in a ui file since they are used
    // to build the Window menu dynamically
    closeAct = new QAction(tr("Cl&ose"), this);
    closeAct->setShortcut(tr("Ctrl+F4"));
    closeAct->setStatusTip(tr("Close the active window"));
    connect(closeAct, SIGNAL(triggered()),
            ui->mdiArea, SLOT(closeActiveSubWindow()));

    closeAllAct = new QAction(tr("Close &All"), this);
    closeAllAct->setStatusTip(tr("Close all the windows"));
    connect(closeAllAct, SIGNAL(triggered()),
            ui->mdiArea, SLOT(closeAllSubWindows()));

    tileAct = new QAction(tr("&Tile"), this);
    tileAct->setStatusTip(tr("Tile the windows"));
    connect(tileAct, SIGNAL(triggered()), ui->mdiArea, SLOT(tileSubWindows()));

    cascadeAct = new QAction(tr("&Cascade"), this);
    cascadeAct->setStatusTip(tr("Cascade the windows"));
    connect(cascadeAct, SIGNAL(triggered()), ui->mdiArea, SLOT(cascadeSubWindows()));

    nextAct = new QAction(tr("Ne&xt"), this);
    nextAct->setShortcuts(QKeySequence::NextChild);
    nextAct->setStatusTip(tr("Move the focus to the next window"));
    connect(nextAct, SIGNAL(triggered()),
            ui->mdiArea, SLOT(activateNextSubWindow()));

    previousAct = new QAction(tr("Pre&vious"), this);
    previousAct->setShortcuts(QKeySequence::PreviousChild);
    previousAct->setStatusTip(tr("Move the focus to the previous "
                                 "window"));
    connect(previousAct, SIGNAL(triggered()),
            ui->mdiArea, SLOT(activatePreviousSubWindow()));

    separatorAct = new QAction(this);
    separatorAct->setSeparator(true);

    connect(ui->actionHelp, SIGNAL(triggered()), this, SLOT(showDocumentation()));

    connect(ui->actionSourceHighlightSettings, SIGNAL(triggered()), this, SLOT(configureSourceHighlight()));
}

void MainWindow::createMenus()
{
    updateWindowMenu();
    connect(ui->windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu()));
}

void MainWindow::updateWindowMenu()
{
    ui->windowMenu->clear();
    ui->windowMenu->addAction(closeAct);
    ui->windowMenu->addAction(closeAllAct);
    ui->windowMenu->addSeparator();
    ui->windowMenu->addAction(tileAct);
    ui->windowMenu->addAction(cascadeAct);
    ui->windowMenu->addSeparator();
    ui->windowMenu->addAction(nextAct);
    ui->windowMenu->addAction(previousAct);
    ui->windowMenu->addAction(separatorAct);

    QList<QMdiSubWindow *> windows = ui->mdiArea->subWindowList();
    separatorAct->setVisible(!windows.isEmpty());

    for (int i = 0; i < windows.size(); ++i) {
        SourceHighlightIde *child = qobject_cast<SourceHighlightIde *>(windows.at(i)->widget());

        QString text;
        if (i < 9) {
            text = tr("&%1 %2").arg(i + 1)
                               .arg(child->userFriendlyCurrentFile());
        } else {
            text = tr("%1 %2").arg(i + 1)
                              .arg(child->userFriendlyCurrentFile());
        }
        QAction *action  = ui->windowMenu->addAction(text);
        action->setCheckable(true);
        action ->setChecked(child == activeMdiChild());
        connect(action, SIGNAL(triggered()), windowMapper, SLOT(map()));
        windowMapper->setMapping(action, windows.at(i));
    }
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    writeSettings();
    ui->mdiArea->closeAllSubWindows();
    if (ui->mdiArea->currentSubWindow()) {
        event->ignore();
    } else {
        event->accept();
    }
}

void MainWindow::readSettings()
{
    QSettings settings("Source-Highlight-Ide", "Source-Highlight-Ide");

    settings.beginGroup("mainwindow");
    QPoint pos = settings.value("winpos", QPoint(200, 200)).toPoint();
    QSize size = settings.value("winsize", QSize(400, 400)).toSize();
    settings.endGroup();

    move(pos);
    resize(size);

    settings.beginGroup("sourcehighlight");
    sourceHighlightDataDir = settings.value("sourceHighlightDataDir", "").toString();
    // set the global value for data dir
    srchilite::Settings::setGlobalDataDir(sourceHighlightDataDir.toStdString());
    settings.endGroup();

    int editors = settings.beginReadArray("editors");
    for (int i = 0; i < editors; ++i) {
         settings.setArrayIndex(i);
         SourceHighlightIde *ideWindow = new SourceHighlightIde();
         ui->mdiArea->addSubWindow(ideWindow, Qt::Window);
         ideWindow->readSettings(settings);

         //qDebug() << "after readSettings";
         //qDebug() << "pos: " << ideWindow->pos();
         //qDebug() << "size: " << ideWindow->size();
    }
    settings.endArray();
}

void MainWindow::writeSettings()
{
    QList<QMdiSubWindow *> windows = ui->mdiArea->subWindowList();
    QListIterator<QMdiSubWindow *> i(windows);
    while (i.hasNext()) {
        SourceHighlightIde *w = qobject_cast<SourceHighlightIde *>(i.next()->widget());
        qDebug() << w->windowTitle();
    }

    QSettings settings("Source-Highlight-Ide", "Source-Highlight-Ide");

    settings.beginGroup("mainwindow");
    settings.setValue("winpos", pos());
    settings.setValue("winsize", size());
    settings.endGroup();

    settings.beginGroup("sourcehighlight");
    settings.setValue("sourceHighlightDataDir",
                      sourceHighlightDataDir);
    settings.endGroup();

    settings.beginWriteArray("editors");
    QListIterator<QMdiSubWindow *> it(windows);
    int index = 0;
    while (it.hasNext()) {
         settings.setArrayIndex(index);

         SourceHighlightIde *w = qobject_cast<SourceHighlightIde *>(it.next()->widget());
         w->writeSettings(settings);

         ++index;
    }
    settings.endArray();
}

void MainWindow::setActiveSubWindow(QWidget *window)
{
    if (!window)
        return;
    ui->mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window));
}


SourceHighlightIde *MainWindow::activeMdiChild()
{
    if (QMdiSubWindow *activeSubWindow = ui->mdiArea->activeSubWindow())
        return qobject_cast<SourceHighlightIde *>(activeSubWindow->widget());
    return 0;
}

void MainWindow::showDocumentation() {
    if (!assistant->showDocumentation("index.html")) {
        // revert to a custom help viewer
        CustomHelpForm *helpForm = new CustomHelpForm(this, Qt::Window);
        if (helpForm->setHtmlHelpFileDir(helpPath)) {
            helpForm->setWindowTitle("Custom Help Viewer");
            helpForm->show();
        }
    }
}

bool MainWindow::checkSourceHighlightSettings() {
    if (!srchilite::Settings::checkSettings()) {
        QMessageBox::critical(this, tr("Source-Highlight-Ide"),
                              tr("Source-highlight settings are wrong!\n"
                                 "Please configure it correctly\n"
                                 "otherwise the application may be come unstable"));
        return false;
    }

    return true;
}

void MainWindow::configureSourceHighlight()
{
    srchiliteqt::SourceHighlightSettingsDialog dialog(this);
    if (sourceHighlightDataDir != "")
        dialog.setSourceHighlightDataDirPath(sourceHighlightDataDir);

    if (dialog.exec() == QDialog::Accepted) {
        if (sourceHighlightDataDir != dialog.getSourceHighlightDataDirPath()) {
            qDebug() << "new source-highlight data dir: " << dialog.getSourceHighlightDataDirPath();
            sourceHighlightDataDir = dialog.getSourceHighlightDataDirPath();
            srchilite::Settings::setGlobalDataDir(sourceHighlightDataDir.toStdString());
        }
    }

}

void MainWindow::about()
{
      QMessageBox::about(this, tr("About Source-Highlight-Ide"),
            tr("<b>Source-Highlight-Ide</b> a small Qt4 ide for GNU Source-highlight,"
                  " using the <a href=\"http://srchiliteqt.sourceforge.net\">Source-highlight Qt library</a>. ") +
                  + "<br><br><i>" +
                  QString(srchilite::Versions::getCompleteVersion().c_str()) + "</i>");
}

