/* 
 *
 * $Id: k3bmkisofshandler.cpp 400832 2005-03-26 20:20:35Z trueg $
 * Copyright (C) 2005 Sebastian Trueg <trueg@k3b.org>
 *
 * This file is part of the K3b project.
 * Copyright (C) 1998-2005 Sebastian Trueg <trueg@k3b.org>
 *
 * 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.
 * See the file "COPYING" for the exact licensing terms.
 */

#include "k3bmkisofshandler.h"

#include <k3bexternalbinmanager.h>
#include <k3bjob.h>

#include <kdebug.h>
#include <klocale.h>

#include <cmath>



class K3bMkisofsHandler::Private
{
public:
  const K3bExternalBin* mkisofsBin;
  double firstProgressValue;
  bool readError;
};


K3bMkisofsHandler::K3bMkisofsHandler()
{
  d = new Private;
  d->mkisofsBin = 0;
}


K3bMkisofsHandler::~K3bMkisofsHandler()
{
  delete d;
}


bool K3bMkisofsHandler::mkisofsReadError() const
{
  return d->readError;
}


void K3bMkisofsHandler::initMkisofs( const K3bExternalBin* bin )
{
  d->mkisofsBin = bin;
  d->firstProgressValue = -1;
  d->readError = false;
}


void K3bMkisofsHandler::handleMkisofsOutput( const QString& line )
{
  if( !line.isEmpty() ) {
    if( line.startsWith( d->mkisofsBin->path ) ) {
      // error or warning
      QString errorLine = line.mid( d->mkisofsBin->path.length() + 2 );
      if( errorLine.startsWith( "Input/output error. cannot read from" ) ) {
	handleMkisofsInfoMessage( i18n("Read error from file '%1'").arg( errorLine.mid( 38, errorLine.length()-40 ) ), 
				  K3bJob::ERROR );
	d->readError = true;
      }
    }
    else if( line.contains( "done, estimate" ) ) {
      int p = parseMkisofsProgress( line );
      if( p != -1 )
	handleMkisofsProgress( p );
    }
    else if( line.contains( "extents written" ) ) {
      handleMkisofsProgress( 100 );
    }
    else {
      kdDebug() << "(mkisofs) " << line << endl;
    }
  }
}


int K3bMkisofsHandler::parseMkisofsProgress( const QString& line )
{
  //
  // in multisession mode mkisofs' progress does not start at 0 but at (X+Y)/X
  // where X is the data already on the cd and Y the data to create
  // This is not very dramatic but kind or ugly.
  // We just save the first emitted progress value and to some math ;)
  //

  QString perStr = line;
  perStr.truncate( perStr.find('%') );
  bool ok;
  double p = perStr.toDouble( &ok );
  if( !ok ) {
    kdDebug() << "(K3bMkisofsHandler) Parsing did not work for " << perStr << endl;
    return -1;
  }
  else {
    if( d->firstProgressValue < 0 )
      d->firstProgressValue = p;
    
    return( (int)::ceil( (p - d->firstProgressValue)*100.0/(100.0 - d->firstProgressValue) ) );
  }
}
