

#ifndef CONVERT_H
#define CONVERT_H

#include <tdeio/jobclasses.h>

#include <tqobject.h>
#include <tqvaluelist.h>

#include <kprocess.h>

class Config;
class TagEngine;
class CDManager;
class FileList;
class FileListItem;
class ReplayGain;
class Logger;
class KTempFile;
//class TDEProcess;

/**
 * @short The items for the conversion (for every active file)
 * @author Daniel Faust <hessijames@gmail.com>
 * @version 0.3
 */
class ConvertItem
{
public:
    /**
     * A list of flags for knowing what to do
     */
    enum Mode {
        get               = 0x0001, // Copy the file to tmp
        get_correction    = 0x0002, // Copy the correction file to tmp
        rip               = 0x0004, // Rip the file
        decode            = 0x0008, // Decode the file
        encode            = 0x0010, // Encode the file
        replaygain        = 0x0020, // Apply replaygain
        write_tags        = 0x0040, // Write the tags to the file
        put               = 0x0080, // Move the file to the output directory
        put_correction    = 0x0100, // Move the correction file to the output directory
        execute_userscript= 0x0200  // Run the user script
    };

    /**
     * Default Constructor
     */
    ConvertItem();

    /**
     * Constructor
     * @p item A pointer to the file list item
     */
    ConvertItem( FileListItem* item );

    /**
     * Destructor
     */
    virtual ~ConvertItem();

    /** a reference to the file list item */
    FileListItem* fileListItem;

    /** for adding replay gain */
    ReplayGain* replayGain;

    /** if we need to encode, decode, etc. here we have our processes */
    TDEProcess* convertProcess;
    /** for moving the file to the temporary or output directory */
    TDEIO::Job* moveJob;

    KTempFile* tempInFile;
    KTempFile* tempWavFile;
    KTempFile* tempOutFile;

    TQString correctionInFile;
    TQString correctionOutFile;
    TQString correctionInputExtension;
    TQString correctionOutputExtension;

    //TQTime readOutputTimer;
    TQTime lastOutputTimer;

    /** what shall we do with the file? */
    Mode mode;
    /** and what are we doing with the file? */
    Mode state;

    /** the id with that the item is registered at the logger */
    int logID;
    /** the binary for special treatment */
//     TQString binary;

    /** the path and the name of the output file (needed for executing a command after conversion) */
    TQString outputFilePathName;

    /** if it is an audio cd and it should be ripped to one file: the number of tracks on the cd */
    int tracks;
    /** the current track */
    int track;
    int lastPercent;

    /** the time from the file list item splitted up */
    float getTime;
    float getCorrectionTime;
    float ripTime;
    float decodeTime;
    float encodeTime;
    float replaygainTime;
    /** the current conversion progress */
    int percent;
};


/**
 * @short The conversion engine
 * @author Daniel Faust <hessijames@gmail.com>
 * @version 0.3
 */
class Convert : public TQObject
{
    TQ_OBJECT
  
public:
    /**
     * Constructor
     */
    Convert( Config*, TagEngine*, CDManager*, FileList*, Logger* );

    /**
     * Destructor
     */
    virtual ~Convert();

    void cleanUp();

private:
    /**
     * Copy the file with the file list item @p item to a temporary directory and download or rip, when necessary
     */
    void get( ConvertItem* item );

     /**
     * Copy the correction file with the file list item @p item to a temporary directory and download or rip, when necessary
     */
    void getCorrection( ConvertItem* item );

   /**
     * Rip the file with the convert item @p item from the CD
     */
    void rip( ConvertItem* item );

    /**
     * Decode the file with the convert item @p item
     */
    void decode( ConvertItem* item );

    /**
     * Encode the file with the convert item @p item
     */
    void encode( ConvertItem* item );

    /**
     * Calculate replaygain tags of the file with the convert item @p item
     */
    void replaygain( ConvertItem* item );

    /**
     * Write the tags of the file with the convert item @p item
     */
    void writeTags( ConvertItem* item );

    /**
     * Copy the file with the convert item @p item to the output directory
     */
    void put( ConvertItem* item );

    /**
     * Copy the correction file with the convert item @p item to the output directory
     */
    void putCorrection( ConvertItem* item );

    /**
     * Run the userscript for the convert item @p item
     */
    void executeUserScript( ConvertItem* item );

    /**
     * Decide, what to do next with out item @p item
     */
    void executeNextStep( ConvertItem* item );

    /**
     * Remove item @p item and emit the state @p state
     */
    void remove( ConvertItem* item, int state = 0 );

    /** holds all active files */
    TQValueList<ConvertItem*> items;

    Config* config;
    TagEngine* tagEngine;
    CDManager* cdManager;
    FileList* fileList;
    Logger* logger;
    TQTimer* tUpdateProgressIndicator;
    TDEProcess notify;

private slots:
    /**
     * The file is being moved
     * @p job The pinter to the job
     */
    void moveProgress( TDEIO::Job* job, unsigned long percent );

    /**
     * The file has been moved
     * @p job The pinter to the job
     */
    void moveFinished( TDEIO::Job* job );

    /**
     * Get the process' output
     * @p proc The pinter to the progess
     * @p data The output data
     * @p length The length of the data
     */
    void processOutput( TDEProcess *proc, char *data, int length );

    /**
     * The process has exited
     * @p proc The pinter to the progess
     */
    void processExit( TDEProcess *proc );

    /**
     * Updates the progress indicator
     */
    void updateProgressIndicator();

public slots:
    /**
     * Add a new @p item to the item list and start
     */
    void add( FileListItem* item );

    /**
     * Stop the item with the file list item @p item in the item list and remove it
     */
    void stop( FileListItem* item );

    /**
     * Change the process priorities
     */
//     void priorityChanged( int );

signals:
    /**
     * A job was completed
     * The job with the file list item @p item was completed
     * And report the finish @p state ( 0 = ok, -1 = error, 1 = aborted )
     */
    void finished( FileListItem* item, int state );

    /**
     * Send the logger a signal
     */
    void finishedProcess( int id, int state );

    /**
     * The next track from @p device can be ripped while the track is being encoded
     */
    void rippingFinished( const TQString& device );

    void countTime( float );
    void uncountTime( float );
    void update( float );
};

#endif // CONVERT_H
