/***************************************************************************
 *   Copyright (C) 2007-2014 by Vegeta                                     *
 *                                                                         *
 *   This program 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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "QtGain.h"
#include "Preferences.h"

#include <QFileDialog>
#include <QMessageBox>
#include <QSettings>
#include <QDragEnterEvent>
#include <QUrl>
#include <QAction>
#include <QTimer>
#include <QDirIterator>
#include <QProcess>
#include <QTextEdit>
#include <QMimeData>
#include <QRegularExpression>

// #include <QDebug>

const QString VERSION = "QtGain 1.0.0";

QtGain::QtGain(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags),  ui(new Ui::QtGainClass), isForceRecalulation(false){
    ui->setupUi(this);
    ui->progressBar->setVisible(false);

    startupInitiations();
    loadSettings();

    setWindowTitle(VERSION);
    show();

    // Check for command line arguments
    QStringList arguments = qApp->arguments();

    if (arguments.size() > 1){
        QList<QUrl> fileList;
        isForceRecalulation = arguments.contains("-forceRecalculation", Qt::CaseInsensitive);

        for (int i = 1; i < arguments.size(); ++i) fileList << "file://" + arguments[i];

        processRawFileList(fileList);
    } else if (isShowBrowserAtStatup()) openDirectoryDialog();
}

QtGain::~QtGain(){
    saveSettings();
}

// *********************************************************************************************
// Generate Contextmenu, Timer etc.
// *********************************************************************************************
void QtGain::startupInitiations(){

    actionAbout = new QAction(QIcon(":/Icons/lsongs.png"), tr("About..."), this);
    connect(actionAbout, SIGNAL(triggered()), this, SLOT(showAboutDialog()));

    actionCancelOperation = new QAction(QIcon(":/Icons/Stop.png"), tr("&Stop..."), this);
    actionCancelOperation->setShortcut(tr("Ctrl+S"));

    connect(actionCancelOperation, &QAction::triggered, [&] {

        setOperationCanceled(true);

        TrackGainProcess->close();
        AlbumGainProcess->close();
        FlacAlbumGainProcess->close();

        setGUI_To(RESET_ALL);
    });



    QAction *actionDonate= new QAction(QIcon(":/Icons/Donate.png"), tr("Donate"), this);
    connect(actionDonate, &QAction::triggered, [&] {
        // Donate message, please do not change
        openDialog(tr("<h2>Donate</h2>"
                      "Thank you for your interest in donating money to the QtGain project to support further development."
                      "<hr><center>You can donate via PayPal"
                      "<h4>%1</h4>"
                      "or"
                      "<h4>%2</h4>"
                      "by clicking on the above links.</center><hr>"
                      "Thank you for your support!"
                      )
                   .arg("<a href='https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=URQFHPDHQW336'>5 Euro</a>")
                   .arg("<a href='https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=T62B9KWHB7UWU'>10 Euro</a>")
                   );
    });

    actionQuit = new QAction(QIcon(":/Icons/Exit.png"), tr("E&xit"), this);
    actionQuit->setShortcut(tr("Ctrl+X"));
    connect(actionQuit, SIGNAL(triggered()), qApp, SLOT(quit()));


    actionShowSettings = new QAction(QIcon(":/Icons/Preferences.png"), tr("&Configure"), this);
    actionShowSettings->setShortcut(tr("Ctrl+C"));
    connect(actionShowSettings, SIGNAL(triggered()), this, SLOT(showPreferencesDialog()));

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


    this->addAction(actionAbout);
    this->addAction(actionCancelOperation);
    this->addAction(actionShowSettings);
    this->addAction(Separator);
    this->addAction(actionDonate);
    this->addAction(actionQuit);

    actionCancelOperation->setEnabled(false);
    ui->centralWidget->setContextMenuPolicy(Qt::ActionsContextMenu);

    // Timer
    Timer = new QTimer(this);
    connect(Timer, &QTimer::timeout, [&] {
        ui->Time->setText(TimeUpdateString());
    });

    // Processes
    TrackGainProcess = new QProcess(this);
    TrackGainProcess->setReadChannelMode(QProcess::MergedChannels);
    connect(TrackGainProcess, SIGNAL(finished(int)), this, SLOT(processFiles_TrackGain()));

    AlbumGainProcess = new QProcess(this);
    AlbumGainProcess->setReadChannelMode(QProcess::MergedChannels);
    connect(AlbumGainProcess, SIGNAL(readyRead()),   this, SLOT(processOutput_AlbumGain()));

    FlacAlbumGainProcess = new QProcess(this);
    connect(FlacAlbumGainProcess, SIGNAL(finished(int)), this, SLOT(setGUI_To()));
}


// *********************************************************************************************
// Start gaining AlbumGain
// *********************************************************************************************
void QtGain::processFiles_AlbumGain(){


    QStringList Parameter;

    for (int i=allFiles.size() - 1; i>=0; i--){

        // MP3
        if (allFiles[i].endsWith(".mp3", Qt::CaseInsensitive)){
            ui->FileFormatIcon->setPixmap(QPixmap(":/Icons/mp3.png"));

            isForceRecalulation ? Parameter << "-s" << "r" << "-d" << QString("%1.0").arg(Volume() - 89) << allFiles[finishedFiles()] : Parameter << "-d" << QString("%1.0").arg(Volume() - 89) << "-r" << "-c" << allFiles[finishedFiles()];

            AlbumGainProcess->start(MP3GainBinaryPath(), Parameter);
        }

        // MP4 / m4a
        else if (allFiles[i].contains(QRegularExpression("\\.(mp4|m4a)$", QRegularExpression::CaseInsensitiveOption))){
            ui->FileFormatIcon->setPixmap(QPixmap(":/Icons/m4a.png"));

            Parameter << "-a" << "-k" << "-c" << "-p" << allFiles[i];;

            AlbumGainProcess->start(MP4GainBinaryPath(), Parameter);
        }


        // Ogg-Vorbis
        else if (allFiles[i].endsWith(".ogg", Qt::CaseInsensitive)){
            ui->FileFormatIcon->setPixmap(QPixmap(":/Icons/ogg.png"));

            Parameter << "-a" << allFiles[i];

            AlbumGainProcess->start(VorbisGainBinaryPath(), Parameter);
        }

        // FLAC
        else if (allFiles[i].endsWith(".flac", Qt::CaseInsensitive)){

            ui->FileFormatIcon->setPixmap(QPixmap(":/Icons/flac.png"));
            Parameter << "--add-replay-gain" << "--preserve-modtime" << allFiles[i];

            // MetaFlac generates no output so we can't say something about the progress till it ends
            ui->Statustext->setText("Executing Metaflac, please wait");
            ui->progressBar->setMaximum(0);
            FlacAlbumGainProcess->start(FlacGainBinaryPath(), Parameter);
        }
        // no supported media file
        else allFiles.removeAt(i);
    }


    // Update GUI
    processOutput_AlbumGain();
}


// *********************************************************************************************
// AlbumGain-Output Analysis
// *********************************************************************************************
void QtGain::processOutput_AlbumGain(){

    QString Output = AlbumGainProcess->readAllStandardOutput();
    if (!m_lastAlbumGainOutput.isEmpty() && Output.contains(m_lastAlbumGainOutput)) return;

    // Check for early finish (MP3 and MP4)
    if (Output.contains(QRegularExpression("No changes to .* are necessary", QRegularExpression::CaseInsensitiveOption))) {
        setGUI_To(RESET_ALL, "No need to update files");
        return;
    }


    // Check Vorbisgain-Output
    if (finishedFiles() < allFiles.size()){
        if (Output.contains(QRegularExpression("100%.*\\.(ogg|mp4|m4a)", QRegularExpression::CaseInsensitiveOption)) || // VorbisGain and AACGain
                Output.contains(QRegularExpression(QString("\\[%1/%2\\] 9\\d+% of \\d+ bytes analyzed").arg(finishedFiles() + 1).arg(allFiles.size())))// MP3Gain

                ) addFinishedFiles();

        // Once again check finishedFiles() < allFiles.size()
        QString Info;
        if (finishedFiles() < allFiles.size()) {
            QFileInfo file(allFiles[finishedFiles()]);
            Info = file.path().mid(file.path().lastIndexOf("/") + 1).left(30);
        }

        updateGUIInfos(ui->Statustext->text(),
                       Info,
                       FilenameWithoutPath(finishedFiles()).left(30),
                       qMax(0, allFiles.size() - finishedFiles()),
                       Errors(),
                       skippedFiles(),
                       qMax(0, finishedFiles() - skippedFiles() - Errors()),
                       finishedFiles(),
                       allFiles.size(),
                       false);
    }

    m_lastAlbumGainOutput = Output;
}




// *********************************************************************************************
// Start TrackGain
// *********************************************************************************************
void QtGain::processFiles_TrackGain(){

    // Cancel gaining
    if (isOperationCanceled()){
        setGUI_To(RESET_ALL);
        resetVariables();
        return;
    }

    // ******************************************
    // New code for skipping FLAC files 1/4
    if (m_lastFileSkipped) {
        addSkippedFiles();
        if (isLogSkippedFiles()) addToErrorlog(tr("<font color='green'>File already gained -> skipped</font> :: %1<br>").arg(currentFileName()));
    } else {
        // Check output of replay gain tools
        processOutput();
    }
    m_lastFileSkipped = false;
    //


    if (finishedFiles() < allFiles.size()){

        QStringList Parameter;
        QFileInfo file(allFiles[finishedFiles()]);
        ui->Foldername->setText(file.path().mid(file.path().lastIndexOf("/") + 1).left(30));
        ui->Filename->setText(FilenameWithoutPath(finishedFiles()).left(30));

        // MP3
        if (allFiles[finishedFiles()].endsWith(".mp3", Qt::CaseInsensitive)){
            ui->FileFormatIcon->setPixmap(QPixmap(":/Icons/mp3.png"));

            isForceRecalulation ? Parameter << "-s" << "r" << "-d" << QString("%1.0").arg(Volume() - 89) << allFiles[finishedFiles()] : Parameter << "-d" << QString("%1.0").arg(Volume() - 89) << "-r" << "-c" << allFiles[finishedFiles()];

            TrackGainProcess->start(MP3GainBinaryPath(), Parameter);
        }

        // MP4 / m4a
        else if (allFiles[finishedFiles()].contains(QRegularExpression("\\.(mp4|m4a)$", QRegularExpression::CaseInsensitiveOption))){
            ui->FileFormatIcon->setPixmap(QPixmap(":/Icons/m4a.png"));

            Parameter << "-d" << QString("%1.0").arg(Volume() - 89) << "-r" << "-c" << allFiles[finishedFiles()];
            TrackGainProcess->start(MP4GainBinaryPath(), Parameter);
        }

        // Ogg-Vorbis
        else if (allFiles[finishedFiles()].endsWith(".ogg", Qt::CaseInsensitive)){
            ui->FileFormatIcon->setPixmap(QPixmap(":/Icons/ogg.png"));
            Parameter << "-f" << allFiles[finishedFiles()]; // vorbisgain allways gains to 89dB in track mode
            TrackGainProcess->start(VorbisGainBinaryPath(), Parameter);
        }

        // FLAC
        else if (allFiles[finishedFiles()].endsWith(".flac", Qt::CaseInsensitive)){
            ui->FileFormatIcon->setPixmap(QPixmap(":/Icons/flac.png"));

            // ******************************************
            // New code for skipping FLAC files 2/4
            // Check if flac file is already gained, metaflac does not do this by itself
            QProcess checkProcess;
            checkProcess.start(FlacGainBinaryPath(), QStringList() << "--show-tag" << "REPLAYGAIN_TRACK_GAIN" << allFiles[finishedFiles()]);
            checkProcess.waitForFinished();
            QString output(checkProcess.readAllStandardOutput());
            if (output.contains("REPLAYGAIN_TRACK_GAIN=")) {
                this->m_lastFileSkipped = true;
            } else {
                Parameter << "--add-replay-gain" << allFiles[finishedFiles()];
                TrackGainProcess->start(FlacGainBinaryPath(), Parameter);
            }
            //

        }
    }

    // Update GUI
    updateGUIInfos(ui->Statustext->text(),
                   ui->Foldername->text(),
                   ui->Filename->text(),
                   allFiles.size() - finishedFiles(),
                   Errors(),
                   skippedFiles(),
                   qMax(0, finishedFiles() - skippedFiles() - Errors()),
                   finishedFiles(),
                   allFiles.size(),
                   false);

    if (allFiles.size() == finishedFiles()) {

        setGUI_To(IDLE);
        resetVariables();
        if (isAutoExit()) qApp->quit();
        return;

        setIsDragDropAllowed(false);
    }
    else {
        setCurrentFileName(allFiles[finishedFiles()]);
        addFinishedFiles();

        // ******************************************
        // New code for skipping FLAC files 3/4
        if (this->m_lastFileSkipped) QMetaObject::invokeMethod(this, "processFiles_TrackGain", Qt::QueuedConnection);
        //
    }
}


// *********************************************************************************************
// Check the output of Replay gain tools
// *********************************************************************************************
void QtGain::processOutput(){

    QString Output(TrackGainProcess->readAll());

    // No media file
    if (Output.contains("not a layer III file")                            ||
            Output.contains("File does not contain Vorbis data")           ||
            Output.contains("The file does not appear to be a FLAC file.") ||
            Output.contains("Can't find any valid MP3 frames in file")
            ){
        addErrors();
        addToErrorlog(tr("<font color='red'>Not a valid media file</font> :: %1<br>").arg(currentFileName()));
    }

    // Cannot access file
    else if (Output.contains("for reading")){
        addErrors();
        addToErrorlog(tr("<font color='red'>Cannot read file</font> :: %1<br>").arg(currentFileName()));
    }

    // Cannot write
    else if (Output.contains("Permission denied") || Output.contains("for modifying")){
        addErrors();
        addToErrorlog(tr("<font color='red'>Cannot write file</font> :: %1<br>").arg(currentFileName()));
    }

    // File already gained (only MP3 and Ogg-Vorbis)
    else if (Output.contains("are necessary") || Output.contains("Tags present;")){

        // File was fully analyzed but no need to update the file only tags:
        // we count this as Gained (mp3gain)
        if (!Output.contains("but tag needs update:")){
            addSkippedFiles();
            if (isLogSkippedFiles()) addToErrorlog(tr("<font color='green'>File already gained -> skipped</font> :: %1<br>").arg(currentFileName()));
        }
    }
}


// *********************************************************************************************
// Search for all files, including subdirs
// *********************************************************************************************
void QtGain::findFiles(const QString &dirName){
    if (!Timer->isActive()) setGUI_To(BUSY, tr("Scanning directories..."));
    setOperationCanceled(false);

    QDirIterator it(dirName, QDirIterator::Subdirectories);
    QString temp;
    while (it.hasNext()) {
        qApp->processEvents(QEventLoop::AllEvents);

        // Cancel scanning
        if (isOperationCanceled()){
            setGUI_To(RESET_ALL);
            resetVariables();
            return;
        }

        ui->sumFilesUnprocessed->display(allFiles.size() - finishedFiles());
        temp = it.next();
        if (
                ((temp.endsWith(".mp3",  Qt::CaseInsensitive) && isMP3GainFound())    ||
                 (temp.endsWith(".ogg",  Qt::CaseInsensitive) && isVorbisGainFound()) ||
                 (temp.endsWith(".flac", Qt::CaseInsensitive) && isFlacGainFound())   ||
                 (temp.contains(QRegularExpression("\\.(mp4|m4a)$", QRegularExpression::CaseInsensitiveOption)) && isMP4GainFound())
                 ) && !allFiles.contains(temp)) allFiles << temp;
    }

    ui->sumFilesUnprocessed->display(allFiles.size() - finishedFiles());
}


void QtGain::dragEnterEvent(QDragEnterEvent *event){
    // Drag & Drop is only allowed during gaining or idle state
    if (!isDragDropAllowed()) event->ignore();
    else if (event->mimeData()->hasFormat("text/uri-list")) event->acceptProposedAction();
}


// *********************************************************************************************
// Add files/directories via drag & drop
// *********************************************************************************************
void QtGain::dropEvent(QDropEvent *event){
    QList<QUrl> urls = event->mimeData()->urls();
    if (urls.isEmpty()) return;

    processRawFileList(urls);
}


void QtGain::processRawFileList(QList<QUrl> &urls){
    QFileInfo Tempfile;
    QString temp;

    for (int i = 0; i < urls.count(); ++i){
        qApp->processEvents(QEventLoop::AllEvents);

        Tempfile = urls[i].toLocalFile();
        temp = Tempfile.absoluteFilePath();

        if (
                ((temp.endsWith(".mp3",  Qt::CaseInsensitive) && isMP3GainFound())    ||
                 (temp.endsWith(".ogg",  Qt::CaseInsensitive) && isVorbisGainFound()) ||
                 (temp.endsWith(".flac", Qt::CaseInsensitive) && isFlacGainFound())   ||
                 (temp.contains(QRegularExpression("\\.(mp4|m4a)$", QRegularExpression::CaseInsensitiveOption)) && isMP4GainFound())
                 ) && !Tempfile.isDir() && !allFiles.contains(temp)) allFiles << temp;
        else if (Tempfile.isDir()) findFiles(Tempfile.absoluteFilePath());

        // Cancel
        if (isOperationCanceled()){
            setGUI_To(RESET_ALL);
            resetVariables();
            return;
        }
    }
    processFoundFiles();
}


// *********************************************************************************************
// Show file dialog at startup
// *********************************************************************************************
void QtGain::openDirectoryDialog(){
    QString directory = QFileDialog::getExistingDirectory(this, tr("Please choose a directory"),
                                                          QDir::homePath() + "/Desktop", QFileDialog::DontResolveSymlinks | QFileDialog::ShowDirsOnly);
    if (directory.isEmpty()) return;

    findFiles(directory);
    processFoundFiles();
}

// *********************************************************************************************
// Used by openDirectoryDialog and processRawFileList
// *********************************************************************************************
void QtGain::processFoundFiles(){

    if (allFiles.size() > 0){

        setGUI_To(BUSY);
        // ******************************************
        // New code for skipping FLAC files 4/4
        this->m_lastFileSkipped = false;
        //
        isTrackGain() ? processFiles_TrackGain() : processFiles_AlbumGain();
    } else {
        setGUI_To(IDLE, tr("No media files found..."));
        resetVariables();
    }
}



// *********************************************************************************************
// Show settings dialog
// *********************************************************************************************
void QtGain::showPreferencesDialog(){

    Preferences Preferences(this);

    Preferences.MP3GainPfad->setText(MP3GainBinaryPath());
    Preferences.MP4GainPfad->setText(MP4GainBinaryPath());
    Preferences.VorbisGainPfad->setText(VorbisGainBinaryPath());
    Preferences.FlacGainPfad->setText(FlacGainBinaryPath());
    Preferences.setIcons();

    Preferences.Pegel->setValue(Volume());
    Preferences.isAlbumGain->setChecked(!isTrackGain());
    Preferences.isStartBrowserAtStartup->setChecked(isShowBrowserAtStatup());
    Preferences.isLogSkippedFiles->setChecked(isLogSkippedFiles());
    Preferences.isAutoExit->setChecked(isAutoExit());

    Preferences.exec();


    if (Preferences.result() == QDialog::Accepted){
        // Save new settings
        setMP3GainBinaryPath(Preferences.MP3GainPfad->text());
        setMP4GainBinaryPath(Preferences.MP4GainPfad->text());
        setVorbisGainBinaryPath(Preferences.VorbisGainPfad->text());
        setFlacGainBinaryPath(Preferences.FlacGainPfad->text());
        setVolume(Preferences.Pegel->value());
        setTrackGain(Preferences.isTrackGain->isChecked());
        setShowBrowserAtStatup(Preferences.isStartBrowserAtStartup->isChecked());
        setIsLogSkippedFiles(Preferences.isLogSkippedFiles->isChecked());
        setIsAutoExit(Preferences.isAutoExit->isChecked());


        // Check if Replay gain tools are available
        setIsMP3GainFound   (QFile::exists(MP3GainBinaryPath()));
        setIsMP4GainFound   (QFile::exists(MP4GainBinaryPath()));
        setIsVorbisGainFound(QFile::exists(VorbisGainBinaryPath()));
        setIsFlacGainFound  (QFile::exists(FlacGainBinaryPath()));
    }
}


// *********************************************************************************************
// Load settings
// *********************************************************************************************
void QtGain::loadSettings(){
    QSettings settings("Vegeta", "QtGain");

    restoreGeometry(settings.value("windowGeometrie").toByteArray());
    setMP3GainBinaryPath   (settings.value("MP3Gain",    "/usr/bin/mp3gain").toString());
    setMP4GainBinaryPath   (settings.value("aacgain",    "/usr/bin/aacgain").toString());
    setVorbisGainBinaryPath(settings.value("VorbisGain", "/usr/bin/vorbisgain").toString());
    setFlacGainBinaryPath  (settings.value("FlacGain",   "/usr/bin/metaflac").toString());
    setVolume(settings.value("Volume", 89).toInt());

    setTrackGain(settings.value("TrackGain",                    true).toBool());
    setShowBrowserAtStatup(settings.value("ShowBrowser",        false).toBool());
    setStatistic(settings.value("filesProcessed", 0).toInt(), settings.value("filesGained", 0).toInt(), settings.value("installDate", QDate::currentDate()).toDate());
    setIsLogSkippedFiles(settings.value("isLogSkippedFiles",   false).toBool());
    setIsAutoExit(settings.value("isAutoExit",                 false).toBool());

    // Fallback falls Replay-Gain-Tools über die geladenen Infos nicht gefunden werden können
    if (!QFile::exists(MP3GainBinaryPath()))    setMP3GainBinaryPath("/usr/bin/mp3gain");
    if (!QFile::exists(MP4GainBinaryPath()))    setMP4GainBinaryPath("/usr/bin/aacgain");
    if (!QFile::exists(VorbisGainBinaryPath())) setVorbisGainBinaryPath("/usr/bin/vorbisgain");
    if (!QFile::exists(FlacGainBinaryPath()))   setFlacGainBinaryPath("/usr/bin/metaflac");

    // Check if Replay gain tools are available
    setIsMP3GainFound   (QFile::exists(MP3GainBinaryPath()));
    setIsMP4GainFound   (QFile::exists(MP4GainBinaryPath()));
    setIsVorbisGainFound(QFile::exists(VorbisGainBinaryPath()));
    setIsFlacGainFound  (QFile::exists(FlacGainBinaryPath()));

    if (!isMP3GainFound() && !isMP4GainFound() && !isVorbisGainFound() && !isFlacGainFound()) {
        ui->Statustext->setText(tr("<font color=red>No replay gain tools found!</font>"));
        showPreferencesDialog();
    }
}


// *********************************************************************************************
// Save settings
// *********************************************************************************************
void QtGain::saveSettings(){
    QSettings settings("Vegeta", "QtGain");
    settings.setValue("windowGeometrie",      saveGeometry());
    settings.setValue("MP3Gain",              MP3GainBinaryPath());
    settings.setValue("aacgain",              MP4GainBinaryPath());
    settings.setValue("VorbisGain",           VorbisGainBinaryPath());
    settings.setValue("FlacGain",             FlacGainBinaryPath());
    settings.setValue("Volume",               Volume());
    settings.setValue("TrackGain",            isTrackGain());
    settings.setValue("ShowBrowser",          isShowBrowserAtStatup());
    settings.setValue("isLogSkippedFiles",    isLogSkippedFiles());
    settings.setValue("isAutoExit",           isAutoExit());
    settings.setValue("SearchEngine",         searchEngine());


    int filesProcessed, filesGained;
    QDate installDate;
    Statistic(filesProcessed, filesGained, installDate);
    settings.setValue("filesProcessed",    filesProcessed);
    settings.setValue("filesGained",       filesGained);
    settings.setValue("installDate",       installDate);
}


void QtGain::closeEvent(QCloseEvent *event){
    Q_UNUSED(event);
    qApp->quit();
}


// *********************************************************************************************
// About dialog
// *********************************************************************************************
void QtGain::showAboutDialog() {

    int filesProcessed, filesGained;
    QDate installDate;
    Statistic(filesProcessed, filesGained, installDate);

    openDialog(tr("<h2>%1</h2>"
                  "Replay Gain frontend for MP3Gain, VorbisGain, AACGain and Metaflac.<br>"
                  "Uses id3v2 to rename files/folders of MP3 files.<br>"
                  "Cover Arts Downloader via Amazon or Google Picture Search.<br><br>"
                  "(c) 2007-2016, Vegeta<br><br>"
                  "<a href='http://qt-apps.org/content/show.php/QtGain?content=56842'>Website</a><br><br>"
                  "This program 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 2 of the License, or (at your option) any later version.<br>"
                  "<h4>Thanks to the following translator(s):</h4>"
                  "%5"
                  "<h4>Statistic:</h4>QtGain has %2 files processed (%3 files were replay gained) since %4.").arg(VERSION).arg(filesProcessed).arg(filesGained).arg(installDate.toString("dd.MM.yyyy"))
               .arg("Pavel Fric (Czech)<br>")
               );
}




// *********************************************************************************************
// Show Error-Log
// *********************************************************************************************
void QtGain::showErrors() {
    if (ErrorLog().isEmpty()) return;

    QDialog window(this);
    QTextEdit Text;
    Text.setReadOnly(true);
    Text.setText(ErrorLog());
    window.setWindowTitle(tr("Errorlog"));
    window.setMinimumSize(850, 500);
    QPushButton showMessageButton(tr("Close"));
    showMessageButton.setDefault(true);

    QGridLayout messageLayout;
    messageLayout.addWidget(&Text,0,0);
    messageLayout.addWidget(&showMessageButton);
    window.setLayout(&messageLayout);

    connect(&showMessageButton, SIGNAL(clicked()), &window, SLOT(close()));
    window.exec();
}


// *********************************************************************************************
// Change state of GUI
// *********************************************************************************************
void QtGain::setGUI_To(int const &Status, QString Message){
    if (Status == IDLE || Status == RESET_ALL){
        actionCancelOperation->setEnabled(false);
        Timer->stop();

        if (Message.isEmpty()) isOperationCanceled() ? ui->Statustext->setText(tr("Operation aborted...")) : ui->Statustext->setText(isTrackGain() ? tr("TrackGain finished!") : tr("AlbumGain finished!"));
        else ui->Statustext->setText(Message);
        ui->Foldername->clear();
        ui->Filename->clear();
        ui->FileFormatIcon->setPixmap(QPixmap(":/Icons/audio.png"));

        // Context menu
        actionAbout->setEnabled(true);
        actionShowSettings->setEnabled(true);
        actionQuit->setEnabled(true);

        ui->line->setVisible(true);
        ui->progressBar->setVisible(false);

        showErrors();
        resetVariables();
        resetErrorlog();

        if (Status == RESET_ALL){
            ui->progressBar->setMaximum(100);
            ui->progressBar->reset();
            updateGUIInfos(ui->Statustext->text(), "", "", 0, 0, 0, 0, 0, 100, false);

            ui->Time->setText("00:00:00");
            ui->FolderIcon->setPixmap(QPixmap(":/Icons/folder.png"));
            FlacAlbumGainProcess->close();
            TrackGainProcess->close();
            AlbumGainProcess->close();
        }

        if (!isOperationCanceled() && isAutoExit()) {
            qApp->quit();
            return;
        }


    } else if (Status == BUSY) {
        ui->line->setVisible(false);
        ui->progressBar->setVisible(true);

        actionCancelOperation->setEnabled(true);
        setStartTime();
        Timer->start(1000);

        updateGUIInfos(Message.isEmpty() ? (isTrackGain() ? tr("TrackGain in process...") : tr("AlbumGain in process...")) : Message, "", "", 0, 0, 0, 0, 0, 100, false);

        actionAbout->setEnabled(false);
        actionShowSettings->setEnabled(false);
        actionQuit->setEnabled(false);

        ui->Time->setText("00:00:00");
    }
}


// *********************************************************************************************
// Update GUI-Infos via Slot/Signal
// *********************************************************************************************
void QtGain::updateGUIInfos(QString Statustext,
                            QString Foldertext,
                            QString Filetext,
                            int ToDo,
                            int Error,
                            int Skipped,
                            int Gained,
                            int progressBarValue,
                            int progressBarMax,
                            bool setDownloadIcon){

    ui->Statustext->setText(Statustext);
    ui->Foldername->setText(Foldertext);
    ui->Filename->setText(Filetext);
    ui->sumFilesUnprocessed->display(ToDo);
    ui->sumErrors->setNum(Error);
    ui->sumFilesSkipped->setNum(Skipped);
    ui->sumFilesGained->setNum(Gained);

    if (progressBarMax > 0) ui->progressBar->setValue((progressBarValue * 100) / progressBarMax);
    else ui->progressBar->reset();


    if (setDownloadIcon){
        ui->FolderIcon->setPixmap(QPixmap(":/Icons/Download.png"));
        ui->FileFormatIcon->clear();
        ui->Filename->clear();
        ui->sumFilesGained->setEnabled(false);
        ui->labelText_Gained->setEnabled(false);
    } else {
        ui->sumFilesGained->setEnabled(true);
        ui->labelText_Gained->setEnabled(true);
    }
}




// *********************************************************************************************
// Open standard dialog (QMessageBox can't open html links in KDE)
// *********************************************************************************************
void QtGain::openDialog(QString Text){
    QDialog Dialog(this);
    QLabel text(&Dialog);
    QPushButton pushButton("Okay", &Dialog);
    QGridLayout gridLayout(&Dialog);

    Dialog.setWindowTitle("QtGain");
    Dialog.setMaximumSize(800,800);
    pushButton.setMaximumWidth(150);

    text.setWordWrap(true);
    text.setOpenExternalLinks(true);
    text.setText(Text);

    gridLayout.addWidget(&text, 0, 0, 1, 2);
    gridLayout.addWidget(&pushButton, 1, 1, 1, 1);

    connect(&pushButton, SIGNAL(clicked()), &Dialog, SLOT(accept()));
    Dialog.exec();
}
