/*
 *
 * $Id: k3bisoimager.h 400832 2005-03-26 20:20:35Z trueg $
 * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
 *
 * This file is part of the K3b project.
 * Copyright (C) 1998-2004 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.
 */

#ifndef K3B_ISO_IMAGER_H
#define K3B_ISO_IMAGER_H

#include <k3bjob.h>
#include "k3bmkisofshandler.h"

#include <qptrqueue.h>
#include <qstringlist.h>

class K3bDataDoc;
class K3bDirItem;
class K3bDataItem;
class K3bFileItem;
class QTextStream;
class K3bProcess;
class KProcess;
class K3bDevice::Device;
class KTempFile;


class K3bIsoImager : public K3bJob, public K3bMkisofsHandler
{
 Q_OBJECT

 public:
  K3bIsoImager( K3bDataDoc*, K3bJobHandler*, QObject* parent = 0, const char* name = 0 );
  virtual ~K3bIsoImager();

  virtual bool active() const;

  int size() const { return m_mkisofsPrintSizeResult; }

  /**
   * The dummy dir is used to create dirs on the iso-filesystem.
   *
   * @return an empty dummy dir for use with K3bDirItems.
   * @param weight Since the weight of files is determined by their local
   *               path in mkisofs we need several dummy dirs for every 
   *               weight.
   */
  static QString dummyDir( int weight = 0 );

 public slots:
  virtual void start();
  virtual void cancel();
  virtual void calculateSize();

  /**
   * lets the isoimager write directly into fd instead of writing
   * to an image file.
   * Be aware that this only makes sense before starting the job.
   * To disable just set @p fd to -1
   */
  void writeToFd( int fd );

  void writeToImageFile( const QString& path );

  /**
   * If dev == 0 K3bIsoImager will ignore the data in the previous session. 
   * This is usable for CD-Extra.
   */
  void setMultiSessionInfo( const QString&, K3bDevice::Device* dev = 0 );

  K3bDevice::Device* device() const { return m_device; }
  K3bDataDoc* doc() const { return m_doc; }

 signals:
  void sizeCalculated( int exitCode, int size );

 protected:
  virtual void handleMkisofsProgress( int );
  virtual void handleMkisofsInfoMessage( const QString&, int );

  virtual bool addMkisofsParameters( bool printSize = false );

  /**
   * calls writePathSpec, writeRRHideFile, and writeJolietHideFile
   */
  bool prepareMkisofsFiles();

  void outputData();
  void init();
  virtual void cleanup();

  /**
   * @returns The number of entries written or -1 on error
   */
  virtual int writePathSpec();
  bool writeRRHideFile();
  bool writeJolietHideFile();
  bool writeSortWeightFile();

  // used by writePathSpec
  virtual int writePathSpecForDir( K3bDirItem* dirItem, QTextStream& stream );
  virtual void writePathSpecForFile( K3bFileItem*, QTextStream& stream );
  QString escapeGraftPoint( const QString& str );

  KTempFile* m_pathSpecFile;
  KTempFile* m_rrHideFile;
  KTempFile* m_jolietHideFile;
  KTempFile* m_sortWeightFile;

  K3bProcess* m_process;

  bool m_processExited;
  bool m_canceled;

 protected slots:
  virtual void slotReceivedStderr( const QString& );
  virtual void slotProcessExited( KProcess* );

 private slots:
  void slotCollectMkisofsPrintSizeStderr(KProcess*, char*, int);
  void slotCollectMkisofsPrintSizeStdout(KProcess*, char*, int);
  void slotMkisofsPrintSizeFinished();

 private:
  class Private;
  Private* d;

  K3bDataDoc* m_doc;

  bool m_noDeepDirectoryRelocation;

  bool m_importSession;
  QString m_multiSessionInfo;
  K3bDevice::Device* m_device;

  // used for mkisofs -print-size parsing
  QString m_collectedMkisofsPrintSizeStdout;
  QString m_collectedMkisofsPrintSizeStderr;
  int m_mkisofsPrintSizeResult;

  QStringList m_tempFiles;

  int m_fdToWriteTo;

  bool m_containsFilesWithMultibleBackslashes;
};


#endif
