/***************************************************************************
 *   Project TupiTube Desk                                                 *
 *   Project Contact: info@tupitube.com                                    *
 *   Project Website: http://www.tupitube.com                              * 
 *                                                                         *
 *   Developers:                                                           *
 *   2025:                                                                 *
 *    Utopian Lab Development Team                                         *
 *   2010:                                                                 *
 *    Gustav Gonzalez                                                      *
 *   ---                                                                   *
 *   KTooN's versions:                                                     *
 *   2006:                                                                 *
 *    David Cuadrado                                                       *
 *    Jorge Cuadrado                                                       *
 *   2003:                                                                 *
 *    Fernado Roldan                                                       *
 *    Simena Dinas                                                         *
 *                                                                         *
 *   License:                                                              *
 *   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, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#include "tupvideoimporterdialog.h"
#include "tconfig.h"
#include "tseparator.h"
#include "tapptheme.h"
#include "tosd.h"
#include "tupprojectrequest.h"
#include "tseparator.h"
#include "talgorithm.h"
#include "tupaudiocutter.h"

#include <QPushButton>

TupVideoImporterDialog::TupVideoImporterDialog(const QString &filename, const QString &photogramsPath, const QSize &canvasSize,
                                               TupVideoCutter *cutter, QWidget *parent) : QDialog(parent)
{
    #ifdef TUP_DEBUG
        qDebug() << "[TupVideoImporterDialog::TupVideoImporterDialog()]";
    #endif

    setModal(true);
    videoPath = filename;
    projectSize = canvasSize;

    framesTotal = 1;
    sizeFlag = false;

    QFileInfo fileInfo(videoPath);
    setWindowTitle(tr("Photograms Extractor") + " (" + fileInfo.fileName() + ")");
    setWindowIcon(QIcon(QPixmap(THEME_DIR + "icons/scenes.png")));
    setStyleSheet(TAppTheme::themeStyles());

    videoCutter = cutter;
    connect(videoCutter, SIGNAL(imageExtracted(MediaType, int)), this, SLOT(updateMediaProgress(MediaType, int)));
    connect(videoCutter, SIGNAL(imageExtractionIsDone()), this, SLOT(startImageImportation()));

    assetsPath = photogramsPath;
    videoSize = videoCutter->getVideoSize();

    layout = new QVBoxLayout(this);
    fixSize = projectSize != videoSize;
    setDialogUI(fixSize);
}

TupVideoImporterDialog::~TupVideoImporterDialog()
{
    delete videoCutter;
}

void TupVideoImporterDialog::setDialogUI(bool fixSize)
{
    QLabel *importLabel = new QLabel(tr("Select the number of photograms to import:"));
    imagesBox = new QSpinBox;
    imagesBox->setMinimum(1);
    imagesBox->setMaximum(100);
    imagesBox->setValue(1);

    QWidget *formWidget = new QWidget;
    QHBoxLayout *formLayout = new QHBoxLayout(formWidget);
    formLayout->addStretch();
    formLayout->addWidget(importLabel);
    formLayout->addWidget(imagesBox);
    formLayout->addStretch();

    layout->addWidget(formWidget);

    if (fixSize) {
        QWidget *sizeWidget = new QWidget;
        QVBoxLayout *sizeLayout = new QVBoxLayout(sizeWidget);

        TSeparator *div = new TSeparator();

        QLabel *sizeLabel = new QLabel("<b>" + tr("Project size and video size are different:") + "</b>");
        sizeLabel->setAlignment(Qt::AlignHCenter);

        QLabel *canvasLabel = new QLabel(tr("Project Size:") + " <b>" + QString::number(projectSize.width())
                                         + "x" + QString::number(projectSize.height()) + "</b>");
        canvasLabel->setAlignment(Qt::AlignHCenter);
        QLabel *videoLabel = new QLabel(tr("Video Size:") + " <b>" + QString::number(videoSize.width())
                                         + "x" + QString::number(videoSize.height()) + "</b>");
        videoLabel->setAlignment(Qt::AlignHCenter);

        groupBox = new QGroupBox(tr("What do you want to do?"));
        checkButton1 = new QRadioButton(tr("Keep original project and video sizes"));
        checkButton2 = new QRadioButton(tr("Adjust video size to project size"));
        checkButton3 = new QRadioButton(tr("Adjust project size to video size"));
        checkButton1->setChecked(true);

        QVBoxLayout *optionsBox = new QVBoxLayout;
        optionsBox->addWidget(checkButton1);
        optionsBox->addWidget(checkButton2);
        optionsBox->addWidget(checkButton3);
        optionsBox->addStretch(1);

        groupBox->setLayout(optionsBox);

        sizeLayout->addWidget(div);

        sizeLayout->addWidget(sizeLabel);
        sizeLayout->addWidget(canvasLabel);
        sizeLayout->addWidget(videoLabel);
        sizeLayout->addWidget(groupBox);

        audioCheck = new QCheckBox(tr("Import audio if it's available"));
        sizeLayout->addWidget(audioCheck);
        sizeLayout->addWidget(div);

        layout->addWidget(sizeWidget);
    }

    progressBar = new QProgressBar;
    progressBar->setTextVisible(true);
    progressBar->setRange(0, 100);

    progressWidget = new QWidget;
    progressLabel = new QLabel("");
    progressLabel->setAlignment(Qt::AlignHCenter);

    QVBoxLayout *progressLayout = new QVBoxLayout(progressWidget);
    progressLayout->addWidget(progressLabel);
    progressLayout->addWidget(progressBar);
    progressWidget->setVisible(false);

    layout->addWidget(progressWidget);

    QPushButton *okButton = new QPushButton(QIcon(QPixmap(THEME_DIR + "icons/apply.png")), "");
    connect(okButton, SIGNAL(clicked()), this, SLOT(startMediaExtraction()));

    QPushButton *closeButton = new QPushButton(QIcon(QPixmap(THEME_DIR + "icons/close.png")), "");
    closeButton->setToolTip(tr("Close"));
    connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));

    buttonsWidget = new QWidget;
    QHBoxLayout *buttonLayout = new QHBoxLayout(buttonsWidget);
    buttonLayout->addWidget(okButton);
    buttonLayout->addWidget(closeButton);

    layout->addWidget(buttonsWidget, 1, Qt::AlignRight);
    layout->addStretch(1);
}

void TupVideoImporterDialog::startMediaExtraction()
{
    #ifdef TUP_DEBUG
        qDebug() << "[TupVideoImporterDialog::startMediaExtraction()]";
    #endif

    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
    framesTotal = imagesBox->value();
    // framesCounter = 100/framesTotal;
    framesCounter = 1;

    imagesBox->setEnabled(false);
    buttonsWidget->setVisible(false);

    if (fixSize) {
        if (checkButton2->isChecked()) {
            // Adjust photograms size
            #ifdef TUP_DEBUG
                qDebug() << "[TupVideoImporterDialog::startMediaExtraction()] - Resizing photograms...";
            #endif
            sizeFlag = true;
        } if (checkButton3->isChecked()) {
            // Adjust project size
            #ifdef TUP_DEBUG
                qDebug() << "[TupVideoImporterDialog::startMediaExtraction()] - Resizing project canvas...";
            #endif
            emit projectSizeHasChanged(videoSize);
        }
    }

    progressWidget->setVisible(true);
    progressLabel->setText(tr("Starting procedure..."));

    if (!QFile::exists(assetsPath)) {
        QDir dir;
        if (!dir.mkpath(assetsPath)) {
            #ifdef TUP_DEBUG
                qDebug() << "[TupVideoImporterDialog::startMediaExtraction()] - Fatal Error: Couldn't create images directory -> "
                         << assetsPath;
            #endif
            TOsd::self()->display(TOsd::Error, tr("Couldn't create temporary directory!"));

            return;
        }
    }

    videoCutter->setExtractionParams(framesTotal);
    if (!videoCutter->startExtraction()) {
        TOsd::self()->display(TOsd::Error, tr("Can't extract photograms!"));
        videoCutter->releaseResources();

        return;
    }
    videoCutter->releaseResources();

    // Audio extraction
    if (audioCheck->isChecked()) {
        #ifdef TUP_DEBUG
            qDebug() << "[TupVideoImporterDialog::startMediaExtraction()] - Importing audio...";
        #endif

        progressLabel->setText(tr("Importing audio..."));
        progressBar->setValue(0);
        framesCounter = 0;

        QFileInfo file(videoPath);
        QString audioName = file.baseName();

        progressLabel->setText(tr("Importing audio track from video file..."));

        audioPath = QDir::tempPath() + "/" + audioName + ".mp3";
        if (QFile::exists(audioPath))
            audioPath = QDir::tempPath() + "/mp3_audio_" + TAlgorithm::randomString(12) + ".mp3";

        TupAudioCutter *audioCutter = new TupAudioCutter(videoPath, audioPath);        
        connect(audioCutter, SIGNAL(audioExtracted(MediaType, int)),
                this, SLOT(updateMediaProgress(MediaType, int)));
        connect(audioCutter, SIGNAL(extractionIsDone(const QString &)),
                this, SIGNAL(audioExtractionIsDone(const QString &)));

        if (!audioCutter->generateMP3Audio()) {
            #ifdef TUP_DEBUG
                qDebug() << "[TupVideoImporterDialog::startMediaExtraction()] - "
                            "Error: Couldn't extract audio from video file ->" << videoPath;
            #endif
        }
    }
}

void TupVideoImporterDialog::updateMediaProgress(MediaType media, int index)
{
    #ifdef TUP_DEBUG
        qDebug() << "[TupVideoImporterDialog::updateMediaProgress()] - index ->" << index;
    #endif

    QString msg = tr("Extracting photogram %1 of %2").arg(index).arg(framesTotal);
    if (media == Audio)
        msg = tr("Extracting audio frame %1 of %2").arg(index).arg(framesTotal);

    progressLabel->setText(msg);
    progressBar->setValue(framesCounter);
    framesCounter += 1;
}

void TupVideoImporterDialog::startImageImportation()
{
    #ifdef TUP_DEBUG
        qDebug() << "[TupVideoImporterDialog::startImageImportation()] - Extraction is complete!";
        qDebug() << "[TupVideoImporterDialog::startImageImportation()] - Starting image importation...";
    #endif

    progressLabel->setText(tr("Importing images..."));
    progressBar->setValue(0);
    framesCounter = 0;
    emit imageExtractionIsDone(VideoAction, assetsPath, sizeFlag);
}

void TupVideoImporterDialog::updateStatusFromLibraryWidget(const QString &msg)
{
    #ifdef TUP_DEBUG
        qDebug() << "[TupVideoImporterDialog::updateStatusFromLibraryWidget()] - Starting image importation...";
    #endif

    progressLabel->setText(msg);
    progressBar->setValue(framesCounter);
    framesCounter += 1;
}

void TupVideoImporterDialog::endProcedure()
{
    QDir imgDir(assetsPath);
    #ifdef TUP_DEBUG
        qDebug() << "[TupVideoImporterDialog::removeTempFolder()] - Removing temporary (images) folder -> " << assetsPath;
    #endif
    if (imgDir.exists()) {
        if (!imgDir.removeRecursively()) {
            #ifdef TUP_DEBUG
                qWarning() << "[TupVideoImporterDialog::removeTempFolder()] - Error: Can't remove temporary (images) folder -> "
                           << assetsPath;
            #endif
        }
    }

    QApplication::restoreOverrideCursor();
    TOsd::self()->display(TOsd::Info, tr("Video imported successfully!"));
    close();
}
