#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QSettings>
#include "profiles.h"
#include "ui_profiles.h"
#include "objects.h"
#include <QDir>
#include <QFileDialog>
#include <QMessageBox>
#include <QInputDialog>
#include <QUrl>
#include <QDesktopServices>

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

    convertProcess.setProcessChannelMode(QProcess::MergedChannels);
    connect(&convertProcess, SIGNAL(finished(int)), this, SLOT(convertExec_finish(int)));
    joinProcess.setProcessChannelMode(QProcess::MergedChannels);
    connect(&joinProcess, SIGNAL(finished(int)), this, SLOT(joinExec_finish(int)));

    versionId = 91;
    version = "v0.91 Beta";
    setWindowTitle("EMoC - Easy Movie Converter "+version);
    fileFilter = "Video files (*.mpg *.mpeg *.mp4 *.mp2 *.vcd *.flv *.mov)";
    loadSettings();
}

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

void MainWindow::loadSettings()
{
    QSettings settings("beli.ws","emoc");
    if ((settings.contains("x"))  && (settings.contains("y")))
    {
       move(settings.value("x").toInt(), settings.value("y").toInt());
    }

    //fill profiles combobox
    ui->cmbProfiles->clear();
    profileList.clear();
    int size = settings.beginReadArray("profiles");
    for (int i = 0; i < size; ++i)
    {
        settings.setArrayIndex(i);        
        ui->cmbProfiles->addItem(settings.value("profileName").toString());
        Profile prf;
        prf.additional = settings.value("additional").toString();
        prf.bitrate = settings.value("bitrate").toInt();
        prf.bitrateIdx = settings.value("bitrateIdx").toInt();
        prf.height = settings.value("height").toInt();
        prf.join = settings.value("join").toBool();
        prf.outputFormat = settings.value("outputFormat").toInt();
        prf.profileName = settings.value("profileName").toString();
        prf.sizeIdx = settings.value("sizeIdx").toInt();
        prf.width = settings.value("width").toInt();
        profileList.append(prf);
    }
    settings.endArray();
    int lastUsedPrfIdx = -1;
    lastUsedPrfIdx = settings.value("lastUsedProfile",-1).toInt();
    if (lastUsedPrfIdx > ui->cmbProfiles->count()-1)
    {
        lastUsedPrfIdx = -1;
    }
    ui->cmbProfiles->setCurrentIndex(lastUsedPrfIdx);

    ui->edtOutputDir->setText(settings.value("outputDir").toString());
    lastFileDirectory = settings.value("lastFileDirectory").toString();
}

void MainWindow::saveSettings()
{
    QSettings settings("beli.ws","emoc");
    settings.setValue("x",this->geometry().x());
    settings.setValue("y",this->geometry().y());
    settings.setValue("versionId",this->versionId);
    settings.setValue("lastUsedProfile",ui->cmbProfiles->currentIndex());
    settings.setValue("outputDir",ui->edtOutputDir->text());
    settings.setValue("lastFileDirectory",lastFileDirectory);

    //last
    settings.sync();
}

void MainWindow::showProfiles()
{
   profiles prf;
   prf.selectToIdx = ui->cmbProfiles->currentIndex();
   prf.initialize();
   prf.exec();
   prf.saveProfiles();
   loadSettings();
}

void MainWindow::on_btnProfiles_clicked()
{
    showProfiles();
}

void MainWindow::on_actionManage_profiles_triggered()
{
    showProfiles();
}


void MainWindow::on_actionE_xit_triggered()
{
    close();
}

void MainWindow::on_btnBrowse_clicked()
{
   QDir dir(ui->edtOutputDir->text());
   QString dirName;

   if ((ui->edtOutputDir->text() == "") || (!dir.exists()))
   {
       dirName = QDir::homePath();
   }
   else
   {
       dirName = ui->edtOutputDir->text();
   }

   QString title = "Select output directory";
   const char *c_str2 = title.toLatin1().data();
   QString newDirectory = QFileDialog::getExistingDirectory(this, tr(c_str2), dirName);
   if (newDirectory == "")
   {
       newDirectory = QDir::homePath();
   }
   ui->edtOutputDir->setText(newDirectory);
}

void MainWindow::on_btnAddFiles_clicked()
{
    if (lastFileDirectory == "")
    {
        lastFileDirectory = QDir::homePath();
    }
    QFileDialog dialog(this);
    dialog.setNameFilter(fileFilter);
    dialog.setViewMode(QFileDialog::Detail);
    if (lastFileDirectory != "")
    {
        QDir dir = QDir(lastFileDirectory);
        dialog.setDirectory(dir);
    }

    QStringList fileNames = QFileDialog::getOpenFileNames();
    if (fileNames.count() == 0)
    {
        return;
    }
    QString fn = fileNames.at(0);
    QStringList fs = fn.split("/");
    fs.removeLast();
    lastFileDirectory = fs.join("/");
    ui->listView->addItems(fileNames);

}

void MainWindow::showError(QString text, QString info)
{
    QMessageBox msgBox;
    msgBox.setIcon(QMessageBox::Critical);
    msgBox.setText(text);
    msgBox.setInformativeText(info);
    msgBox.setStandardButtons(QMessageBox::Ok);
    msgBox.setDefaultButton(QMessageBox::Ok);
    msgBox.exec();
}

void MainWindow::on_btnRemove_clicked()
{
    if (ui->listView->selectedItems().count() == 0)
    {
        showError("Error removing files","No files are selected");
        return;
    }   

    for (int i=ui->listView->count()-1; i>-1; --i)
    {
       if (ui->listView->item(i)->isSelected())
           delete ui->listView->item(i);
    }
}

void MainWindow::on_btnClear_clicked()
{
    ui->listView->clear();
}

void MainWindow::on_btnStart_clicked()
{
    if (ui->listView->count() == 0)
    {
        showError("Process error", "No files to process");
        return;
    }
    if (ui->cmbProfiles->currentIndex() == -1)
    {
        showError("Profile selection error", "No profile selected");
        return;
    }

    QDir dir = QDir(ui->edtOutputDir->text());
    if (!dir.exists())
    {
        showError("Directory error", "Output directory does not exists");
        return;
    }

    Profile p;
    int i;
    for (i=0; i<profileList.count(); i++)
    {
       p = profileList.at(i);
       if (ui->cmbProfiles->currentText() == p.profileName)
        break;
    }

    if (p.join && (ui->listView->count() < 2))
    {
         showError("Profile join error","When join is selected in profile you must select more than one file");
         return;
    }

    justJoin = (p.join && (p.bitrateIdx == 0) && (p.sizeIdx == 0) && (p.additional == "") && (p.outputFormat == 0));

    finalOutputFilename = "";
    if (p.join)
    {
        bool ok;
        finalOutputFilename = QInputDialog::getText(this,"Name for final video file","Enter name without extension",QLineEdit::Normal,"",&ok);

        if (ok && (finalOutputFilename == ""))
        {
            showError("Join error", "Name cannot be empty");
            return;
        }
    }

    saveSettings();
    QString prefix = "";
    QString codec = "";

    if (p.outputFormat == 1)
    {
        ext="mpg";
        codec="mp4";
    }
    else if (p.outputFormat == 2)
    {
        ext="mpg";
        codec="mpeg2video";
    }
    else if (p.outputFormat == 3)
    {
        ext="vcd";
        codec="vcd";
    }
    else if (p.outputFormat == 4)
    {
        ext="flv";
        codec="flv";
    }
    else if (p.outputFormat == 5)
    {
        ext="avi";
        codec="avi";
    }
    else if (p.outputFormat == 6)
    {
        ext="mov";
        codec="mov";
    }


    joinList.clear();
    convertList.clear();
    listToRemove.clear();

    if (justJoin)
    {
        joinList.clear();
        for (i=0; i<ui->listView->count(); ++i)
        {
            joinList.append(ui->listView->item(i)->text());
        }
        if (ext == "")
        {
            QStringList brkfn = ui->listView->item(0)->text().split(".");
            ext = brkfn.last();
        }
        startProcess();
        return;
    }

    //enter to conversion routine
    for (i=0; i<ui->listView->count(); ++i)
    {
        //FIXME
        //there must be a better way to do this!!
        QString filename = ui->listView->item(i)->text();
        QStringList d = filename.split("/");
        QString fn = d.last();
        d.removeLast();
        QString fileDir = d.join("/");

        if (ext != "")
        {
            d.clear();
            d = fn.split(".");
            d.removeLast();
            d.append(ext);
            fn = d.join(".");
        }

        if (fileDir == ui->edtOutputDir->text())
        {
            prefix = "emoc_";
        }
        else
        {
            prefix = "";
        }

        QString fileToSave = ui->edtOutputDir->text()+"/"+prefix+fn;

        QString ffmpegParams = "-i "+filename;
        if (p.bitrateIdx == 1)
            ffmpegParams += " -b "+ QString::number(p.bitrate)+"k ";
        if (p.sizeIdx == 1)
            ffmpegParams += "-s "+QString::number(p.width)+"x"+QString::number(p.height);
        if (p.additional != "")
            ffmpegParams += " "+p.additional;
        ffmpegParams += " -f "+codec+" "+fileToSave;


        //printf("command is: ffmpeg %s\n",ffmpegParams.toStdString().data());


        convertList.append(ffmpegParams);

        if (p.join)
        {
            joinList.append(fileToSave);
            listToRemove.append(fileToSave);
        }
    }

    startProcess();
}

void MainWindow::startProcess()
{
    if (convertList.count() > 0)
    {
        doConvert();
    }
    else
    {
        doJoin();
    }
}

void MainWindow::doConvert()
{
    if (convertList.count() > 0)
    {
        ui->btnStart->setEnabled(false);
        this->setCursor(Qt::BusyCursor);
        QString params = convertList.at(0);
        convertList.removeAt(0);
        QString program = "ffmpeg";
        convertProcess.start(program,params.split(" "));
    }
}

void MainWindow::doJoin()
{
    if (joinList.count() > 0)
    {
        ui->btnStart->setEnabled(false);
        this->setCursor(Qt::BusyCursor);
        QString files = joinList.join(" ");
        joinList.clear();
        files += " -ovc copy -oac pcm -o "+ui->edtOutputDir->text()+"/"+finalOutputFilename+"."+ext;
        QString program = "mencoder";
        joinProcess.start(program,files.split(" "));
    }
}


void MainWindow::convertExec_finish(int)
{
    if (convertList.count() > 0)
    {
        doConvert();
    }
    else
    {
        ui->btnStart->setEnabled(true);
        this->setCursor(Qt::ArrowCursor);
        doJoin();
    }
}

void MainWindow::joinExec_finish(int)
{
    if (listToRemove.count() > 0)
    {
        QString program = "rm";
        QString files = listToRemove.join(" ");
        listToRemove.clear();
        joinProcess.start(program,files.split(" "));
    }
    ui->btnStart->setEnabled(true);
    this->setCursor(Qt::ArrowCursor);
}

void MainWindow::on_actionOnline_Help_triggered()
{
    QUrl url("http://www.beli.ws/apps/emoc/emoc_hlp.html");
    QDesktopServices::openUrl(url);
}

void MainWindow::on_actionAbout_triggered()
{
    QMessageBox msgBox;
    msgBox.setIcon(QMessageBox::Information) ;
    msgBox.setText("EMoC - Easy Movie Converter");
    QString info = +"Program for converting and joining of video files\n\n";
    info+= "Version: ";
    info+=this->version ;
    info+="\nAuthor: Emil Beli\n";
    info+="Contact: beli0135@gmail.com\n\n";
    info+="License: GNU/GPL v3\n";

    msgBox.setInformativeText(info);
    msgBox.setStandardButtons(QMessageBox::Ok);
    msgBox.setDefaultButton(QMessageBox::Ok);
    msgBox.exec();
}
