/*
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 <QMessageBox>
#include <QDebug>

#include <KLocale>

#include "burnimagethread.h"

BurnImageThread::BurnImageThread(QObject* parent, const QString& device, const QString& filename): QThread(parent)
{
    m_device = device;
    m_filename = filename;
    m_hadError = false;
    m_wasCanceled = false;
}

void BurnImageThread::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)));

    m_process.start("wodim -v -gracetime=0 -force -overburn -dev=" + m_device + " \"" + m_filename + "\"");

    m_timer.start(1000);

    exec();
}

void BurnImageThread::processFinished(int exit_code)
{
    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 BurnImageThread::processError(QProcess::ProcessError error)
{
    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."));
        break;

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

void BurnImageThread::updateProgress()
{
    QString output = m_process.readAll();
  qDebug() << output;
    foreach (const QString& line, output.split('\n'))
    {
        if(line.contains("written (fifo"))
        {
            const QStringList parts = line.simplified().trimmed().split(' ', QString::SkipEmptyParts);
            emit imageSize(parts.at(4).toInt());
            emit progress(parts.at(2).toInt());
        }
    }
}

void BurnImageThread::cancelProcess()
{
    m_wasCanceled = true;
    QProcess::startDetached("killall -9 wodim");
    m_process.kill();
}

