/*
 *  Copyright (C) 2010  Giorgio Wicklein <g.wicklein@giowisys.com>
 *
 *  This file is part of DaemonFS.
 *
 *  DaemonFS 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.
 *
 *  DaemonFS 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 DaemonFS.  If not, see <http://www.gnu.org/licenses/>.
 */

//-----------------------------------------------------------------------------
// Hearders
//-----------------------------------------------------------------------------

#include <QtGui>
#include <QtNetwork/QHttp>

#include "../modules/filewatcherengine.h"
#include "mainwindow.h"
#include "startwidget.h"
#include "filewidget.h"
#include "eventswidget.h"
#include "aboutdialog.h"


//-----------------------------------------------------------------------------
// Public
//-----------------------------------------------------------------------------

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    createModules();
    createMenu();
    createCentralWidget();
    createTrayIcon();
    initComponents();
    createConnections();

#ifdef Q_WS_MAC
    //TODO: fix this
    QMessageBox::warning(this, tr("Daemonfs bug"),
                         tr("Currently DaemonFS for Mac is affected by a bug, which"
                            " causes a crash when big directories are added to "
                            "the monitoring list. We are working on this issue!"));
#endif

}

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



//-----------------------------------------------------------------------------
// Private
//-----------------------------------------------------------------------------

void MainWindow::createMenu()
{
    exitAction = new QAction(tr("Exit"), this);
    exitAction->setShortcut(QKeySequence::Quit);

    aboutAction = new QAction(tr("About DaemonFS"), this);
    aboutAction->setMenuRole(QAction::AboutRole);

    aboutQtAction = new QAction(tr("About Qt"), this);
    aboutQtAction->setMenuRole(QAction::AboutQtRole);

    updateAction = new QAction(tr("Check for updates"), this);
    updateAction->setMenuRole(QAction::ApplicationSpecificRole);

    reportBugAction = new QAction(tr("Report Bug"), this);
    askAction = new QAction(tr("Ask a question"), this);
    featureRequestAction = new QAction(tr("Request a feature"), this);

    fileMenu = new QMenu(tr("File"), this);
    helpMenu = new QMenu(tr("Help"), this);

    fileMenu->addAction(exitAction);
    helpMenu->addAction(aboutAction);
    helpMenu->addAction(aboutQtAction);
#ifndef Q_WS_MAC
    helpMenu->addSeparator();
#endif
    helpMenu->addAction(updateAction);
#ifndef Q_WS_MAC
    helpMenu->addSeparator();
#endif
    helpMenu->addAction(reportBugAction);
    helpMenu->addAction(askAction);
    helpMenu->addAction(featureRequestAction);

    menuBar()->addMenu(fileMenu);
    menuBar()->addMenu(helpMenu);

    connect(exitAction, SIGNAL(triggered()),
            qApp, SLOT(quit()));
    connect(aboutQtAction, SIGNAL(triggered()),
            qApp, SLOT(aboutQt()));
    connect(aboutAction, SIGNAL(triggered()),
            this, SLOT(aboutSlot()));
    connect(updateAction, SIGNAL(triggered()),
            this, SLOT(updateSlot()));
    connect(reportBugAction, SIGNAL(triggered()),
            this, SLOT(reportBugSlot()));
    connect(askAction, SIGNAL(triggered()),
            this, SLOT(askSlot()));
    connect(featureRequestAction, SIGNAL(triggered()),
            this, SLOT(featureRequestSlot()));
}

void MainWindow::createCentralWidget()
{
    stackedWidget = new QStackedWidget(this);
    startWidget = new StartWidget(this);
    fileWidget = new FileWidget(this);
    eventsWidget = new EventsWidget(this);
    eventsWidget->mainWindow = this; //temp workaround: casting fails

    stackedWidget->addWidget(startWidget);
    stackedWidget->addWidget(fileWidget);
    stackedWidget->addWidget(eventsWidget);

    setCentralWidget(stackedWidget);
}

void MainWindow::createModules()
{
    fswatch = new FileWatcherEngine(this);
}

void MainWindow::createTrayIcon()
{
    showAction = new QAction(tr("Show DaemonFS"), this);
    connect(showAction, SIGNAL(triggered()), this, SLOT(show()));
    hideAction = new QAction(tr("Hide DaemonFS"), this);
    connect(hideAction, SIGNAL(triggered()), this, SLOT(hide()));

    trayMenu = new QMenu(this);
    trayMenu->addAction(showAction);
    trayMenu->addAction(hideAction);

    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayMenu);
    trayIcon->setIcon(QIcon(":/icons/daemonfs.png"));
    trayIcon->setToolTip(tr("DaemonFS - watching..."));

    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
             this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason)));
}

void MainWindow::initComponents()
{
    BUILD = 2;
    this->setWindowTitle(tr("DaemonFS"));
    qApp->setWindowIcon(QIcon(":/icons/daemonfs.png"));
    qApp->setApplicationName(tr("DaemonFS"));

    aboutDialog = new AboutDialog(0);
    http = new QHttp(this);
}

void MainWindow::createConnections()
{
    connect(startWidget, SIGNAL(monitorButtonClicked()),
            this, SLOT(monitorButtonClicked()));
    connect(startWidget, SIGNAL(aboutButtonClicked()),
            this, SLOT(aboutSlot()));
    connect(fileWidget, SIGNAL(backButtonClicked()),
            this, SLOT(backButtonClicked()));
    connect(fileWidget, SIGNAL(startButtonClicked()),
            this, SLOT(startButtonClicked()));
    connect(eventsWidget, SIGNAL(backButtonClicked()),
            this, SLOT(backButtonClicked()));
    connect(eventsWidget, SIGNAL(stopButtonClicked()),
            this, SLOT(stopButtonClicked()));
    connect(fswatch, SIGNAL(fschanged(QString)),
            this, SLOT(fschanged(QString)));
    connect(eventsWidget, SIGNAL(hideSignal()),
            this, SLOT(hide()));
    connect(eventsWidget, SIGNAL(trayMessage(QString)),
            this, SLOT(trayMessage(QString)));
    connect(fswatch, SIGNAL(addToTableSignal(QString)),
            eventsWidget, SLOT(addToTableSlot(QString)));
    connect(http, SIGNAL(done(bool)), this, SLOT(updateDoneSlot(bool)));
}


//-----------------------------------------------------------------------------
// Private slots
//-----------------------------------------------------------------------------

void MainWindow::aboutSlot()
{
    aboutDialog->show();
}

void MainWindow::monitorButtonClicked()
{
    stackedWidget->setCurrentIndex(1);
}

void MainWindow::backButtonClicked()
{
    stackedWidget->setCurrentIndex(stackedWidget->currentIndex() - 1);
}

void MainWindow::startButtonClicked()
{
    QProgressDialog progress(tr("Indexing files..."), tr("Please wait"), 0, 0, this, Qt::Sheet);
    progress.show();

    qApp->processEvents();

    QStringList a = fileWidget->getFilesList();
    fswatch->addPaths(a);
    stackedWidget->setCurrentIndex(2);
    trayIcon->show();
}

void MainWindow::stopButtonClicked()
{
    fswatch->clear();
    trayIcon->hide();
}

void MainWindow::fschanged(QString path)
{
    eventsWidget->addEvent(path);
}

void MainWindow::trayActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) {
        case QSystemTrayIcon::DoubleClick:
            if (isHidden())
                show();
            else
                hide();
            break;
        default:
            ;
     }
}

void MainWindow::trayMessage(QString message)
{
    trayIcon->showMessage(tr("DaemonFS"), message, QSystemTrayIcon::NoIcon);
}

void MainWindow::updateSlot()
{
    QUrl url("http://update.giowisys.com/daemonfs/updates");

    http->setHost(url.host(), url.port(80));
    http->get(url.path());
}

void MainWindow::updateDoneSlot(bool error)
{
    if (error) {
        QMessageBox::warning(this, tr("Error"), tr("Could not check for updates"));
        return;
    }

    int lastBuild = 0;
    lastBuild = QString(http->readAll()).toInt();

    if (lastBuild > BUILD) {
        int r = QMessageBox::question(this, tr("DaemonFS update"),
                                 tr("New software version available!\n"
                                    "Do you want to download the new version?"),
                                 QMessageBox::Yes | QMessageBox::No);

        if (r == QMessageBox::Yes)
            QDesktopServices::openUrl(QUrl("http://giowisys.com/products/daemonfs/"));

    } else {
        QMessageBox::information(this, tr("No updates available"), tr("You are using the last version"));
    }
}

void MainWindow::reportBugSlot()
{
    QDesktopServices::openUrl(QUrl("https://bugs.launchpad.net/deamonfs"));
}

void MainWindow::askSlot()
{
    QDesktopServices::openUrl(QUrl("https://answers.launchpad.net/deamonfs"));
}

void MainWindow::featureRequestSlot()
{
    QDesktopServices::openUrl(QUrl("https://blueprints.launchpad.net/deamonfs"));
}
