/*
Copyright (c) 2010 by Drake Justice <djustice.kde@gmail.com>

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.
*/

#include <QDebug>
#include <QMessageBox>
#include <QProcess>
#include <QFileInfo>

#include <KLocale>

#include "burnaudioimagethread.h"

BurnAudioImageThread::BurnAudioImageThread(QObject* parent, const QString& device, const QStringList& filenames): QThread(parent)
{
    m_device = device;
    m_filenames = filenames;
    m_hadError = false;
    m_wasCanceled = false;
    m_numberOfTracks = filenames.count();
    m_currentTrackNumber = 0;
}

void BurnAudioImageThread::run()
{
    connect(&m_timer, SIGNAL(timeout()), this, SLOT(updateProgress()));
    connect(&m_process, SIGNAL(finished(int)), this, SLOT(processFinished(int)));
    connect(&m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));

    foreach(QString filename, m_filenames) {
        if(filename.right(3).toLower() == "mp3") {
            m_filenames.replaceInStrings(filename, "/tmp/discburner_audioproject/" + QFileInfo(filename).baseName() + ".wav");
        }
    }

    m_process.start("wodim -v -overburn -gracetime=0 -force -audio -pad -dev=" + m_device + " \"" + m_filenames.join("\" \"") + "\"");

    m_timer.start(1000);

    exec();
}

void BurnAudioImageThread::processFinished(int exit_code)
{
  qDebug() << "processFinished() in burnaudioimagethread";
  QString output = m_process.readAll();
  qDebug() << output;
    m_timer.stop();

    emit finished();

    if (m_hadError)
        return;

    if (m_wasCanceled)
        return;

    if(exit_code == QProcess::NormalExit)
    {
        QMessageBox::information(0, "DiscBurner", i18n("Burning completed"));
    }
    else if (exit_code == QProcess::CrashExit)
    {
        QMessageBox::information(0, "DiscBurner", i18n("Burning failed"));
    }
}

void BurnAudioImageThread::processError(QProcess::ProcessError error)
{
  qDebug() << "processError() in burnaudioimagethread";
    m_hadError = true;

    if (m_wasCanceled)
        return;

    switch(error)
    {
    case 0:
        QMessageBox::information(0, "DiscBurner", i18n("Could not start burning. Check whether you have sufficient permissions."));
        break;

    case 1:
        QMessageBox::information(0, "DiscBurner", i18n("Burning process crashed.  Has valid input been given?"));
        break;

    case 2:
        QMessageBox::information(0, "DiscBurner", i18n("Burning failed: timed out."));
        break;

    case 3:
        QMessageBox::information(0, "DiscBurner", i18n("Burning failed: cannot communicate with burning process."));
        break;

    case 4:
        QMessageBox::information(0, "DiscBurner", i18n("Burning failed due to a write error. Check disk space and permissions."));

    case 5:
        QMessageBox::information(0, "DiscBurner", i18n("Burning failed with an unknown error."));
        break;
    };
}

void BurnAudioImageThread::updateProgress()
{
  qDebug() << "updateProgress() in burnaudioimagethread";
    QString output = m_process.readAll();
    const QStringList lines = output.split('\n');
    QString burned_mbytes;
    QString track_mbytes;
    qDebug() << output;
    
    foreach (const QString& line, lines) {
        if (line.contains("written (fifo")) {
            const QStringList parts = line.simplified().trimmed().split(' ');
	    m_currentTrackNumber = parts.at(1).toInt();
	    emit trackNumber(parts.at(1));
            burned_mbytes = parts.at(2);
	    track_mbytes = parts.at(4);
	    m_currentTrackSize = track_mbytes.toInt();
            emit trackSize(track_mbytes.toInt());
        } else if (line.contains("Fixating...")) {
	    emit trackProgress(m_currentTrackSize);
	}
    }

    if((m_currentTrackNumber != m_numberOfTracks) && (burned_mbytes != track_mbytes))
	emit trackProgress(burned_mbytes.toInt());
}

void BurnAudioImageThread::cancelProcess()
{
    m_wasCanceled = true;
    m_process.kill();
}

