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

#include <KLocale>

#include "ripthread.h"

RipThread::RipThread(QObject* parent, const QString &device, const QString &filetype, Solid::OpticalDisc::ContentTypes disctype): QThread(parent)
{
    m_device = device;
    m_fileType = filetype;
    m_discType = disctype;
    m_hadError = false;
    m_wasCanceled = false;
}

void RipThread::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.setProcessChannelMode(QProcess::MergedChannels);
    m_process.setWorkingDirectory(QDir::homePath());

    if (m_fileType == "mp3") {            // get icedax friendly. or something.
        m_process.start("cdda2mp3");      // this fails.
    }
    else if (m_fileType == "ogg") {
        m_process.start("cdda2ogg");
    }
    else if (m_fileType == "wav") {
        m_process.start("cdda2wav");
    }

    m_pid = (int) m_process.pid();
    m_timer.start(3000);
    exec();
}

void RipThread::processFinished(int exit_code)
{
    m_timer.stop();

    emit finished();

    if(m_wasCanceled)
        return;

    if(exit_code == QProcess::NormalExit) {
        QMessageBox::information(0, "DiscBurner", i18n("Rip completed"));
    }
}

void RipThread::processError(QProcess::ProcessError error)
{
    m_hadError = true;

    if(m_wasCanceled)
        return;

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

    case 1:
        QMessageBox::information(0, "DiscBurner", i18n("Ripping process crashed."));
        break;

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

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

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

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

void RipThread::updateProgress()
{
    QString output;

    if (m_discType == Solid::OpticalDisc::Audio) {
        output = m_process.readAll();

        foreach (const QString &line, output.split('\n')) {
            if (line.contains("Fetching")) {
                m_trackCount = line.split(" ").at(1).toInt();
                emit discCapacity(m_trackCount);
            } else if (line.contains("->")) {
                m_currentTrack = line.split(" ").at(5).toInt();
                if (m_currentTrack == m_trackCount) {
                    emit trackNumber(QString::number(m_currentTrack) + " of " + QString::number(m_trackCount));
                    emit discCapacity(100);
                    emit progressMonitor(95);
                } else {
                    emit trackNumber(QString::number(m_currentTrack) + " of " + QString::number(m_trackCount));
                    emit progressMonitor(m_currentTrack);
                }
            }
        }
    }
}

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