

#ifndef REPLAYGAINFILELIST_H
#define REPLAYGAINFILELIST_H

#include <tdelistview.h>

#include <tqdatetime.h>


class TagEngine;
class TagData;
class ReplayGain;
class Config;
class Logger;

class TQSimpleRichText;
class KProgress;

class TDEPopupMenu;
class TDEAction;
class TDEActionCollection;
class TDEProcess;

// FIXME differ diffrent sampling rates, too!

/**
 * @short The items for the file list of the Replay Gain scanner
 * @author Daniel Faust <hessijames@gmail.com>
 * @version 0.3
 */
class ReplayGainFileListItem : public TDEListViewItem
{
public:
    enum Type {
        File,
        Album
    };

    enum Mode {
        remove            = 0x0001,
        force             = 0x0002
    };

    /**
     * Constructor
     * @param parent The parent list view
     */
    ReplayGainFileListItem( TQListView* parent );

    /*
     * Constructor
     * @param parent The parent list view
     * @param after The item, the new item should be placed after
     */
    //ReplayGainFileListItem( TQListView* parent, TQListViewItem* after );

    /**
     * Constructor
     * @param parent The parent list view item
     */
    ReplayGainFileListItem( ReplayGainFileListItem* parent );

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

    virtual void paintCell( TQPainter* p, const TQColorGroup& cg, int column, int width, int alignment );

    int compare( TQListViewItem* item, int column, bool ascending ) const;

    void updateReplayGainCells( TagData* );

    ReplayGainFileListItem* firstChild() const { return static_cast<ReplayGainFileListItem*>( TDEListViewItem::firstChild() ); }
    ReplayGainFileListItem* nextSibling() const { return static_cast<ReplayGainFileListItem*>( TDEListViewItem::nextSibling() ); }
    //ReplayGainFileListItem* itemBelow() { return static_cast<ReplayGainFileListItem*>( TDEListViewItem::itemBelow() ); }
    ReplayGainFileListItem* parent() const { return static_cast<ReplayGainFileListItem*>( TDEListViewItem::parent() ); }

    Type type() { return m_type; }
    void setType( Type );

    // FIXME file list

    /* TODO check sampling rate, too
     * metaflac: 8, 11.025, 12, 16, 22.05, 24, 32, 44.1, or 48 kHz.
     */

    TQString filePathName;       // the path and name of the file
    //TQString fileName;           // just the _name_ of the file
    TQString mimeType;           // the mime type of the file / the mime type of all files in this album
    TQString fileFormat;         // just the _format_ of the file / the format of all files in this album (for easier use)
    TQString originalFileFormat; // after renaming we need to re-rename the file
    bool addingReplayGain;      // are we adding replay gain tags at the moment?
    bool queued;                // is this item queued for adding/removing replay gain?
    Mode mode;
    float time;                 // the duration of the track, used for the calculation of the progress bar

private:
    Type m_type;
};


/**
 * @short The file list of the Replay Gain scanner
 * @author Daniel Faust <hessijames@gmail.com>
 * @version 0.3
 */
class ReplayGainFileList : public TDEListView
{
    TQ_OBJECT
  
public:
    /**
     * Constructor
     * @param parent The parent widget
     * @param name The name of the file list
     */
    ReplayGainFileList( TagEngine*, Config*, Logger*, TQWidget *parent=0, const char *name=0 );

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

    ReplayGainFileListItem* firstChild() const { return static_cast<ReplayGainFileListItem*>( TDEListView::firstChild() ); }
    ReplayGainFileListItem* itemAt( const TQPoint& point ) const { return static_cast<ReplayGainFileListItem*>( TDEListView::itemAt(point) ); }

    int columnByName( const TQString& name );

protected:
    virtual bool acceptDrag( TQDropEvent *e ) const;

private slots:
    void columnResizeEvent( int, int, int );
    void openAlbums();
    void closeAlbums();
    void update();

public slots:
    void addFile( const TQString& );
    void addDir( const TQString&, const TQStringList& filter = "", bool recursive = true );
    void calcAllReplayGain( bool force );
    void removeAllReplayGain();
    void cancelProcess();

private:
    /** Lists all file in a directory and adds them to the file list, if @p fast is false. The number of listed files is returned */
    int listDir( const TQString& directory, TQStringList filter, bool recursive = true, bool fast = false, int count = 0 );

    /** A progressbar, that is shown, when a directory is added recursive */
    KProgress* pScanStatus;

    TagEngine* tagEngine;
    Config* config;
    Logger* logger;

    TDEProcess* process;
    ReplayGain* replayGain;
    int logID;

    void contentsDragEnterEvent( TQDragEnterEvent *e );
    void contentsDragMoveEvent( TQDragMoveEvent *e );
    void contentsDropEvent( TQDropEvent *e );

    void viewportPaintEvent( TQPaintEvent* );
    void viewportResizeEvent( TQResizeEvent* );

    TQSimpleRichText* bubble;

    void startProcess();

    void processNextFile();

    void calcReplayGain( ReplayGainFileListItem* );
    void removeReplayGain( ReplayGainFileListItem* );

    bool queue;
    ReplayGainFileListItem::Mode mode;
    ReplayGainFileListItem* currentItem;

    TQTimer* tUpdateProgress;
    bool processing;        // true, if the progress is active (hide some options in the context menu)
    int percent;            // the progress of the current file / album
    int lastPercent;        // cache the last percent in order to record a 'track change'
    float time;             // track length of all files
    float processedTime;    // the sum of all track lengths of the processed files
    int files;              // the number of files in the current album
    int file;               // the file that is being 'replay gained'
    float timeCount;        // the sum of all track lengths in the current album / the track length of the current file

    /** The context menu for editing or starting the files */
    TDEPopupMenu* contextMenu;

    TDEActionCollection* actionCollection;
    TDEAction* calc_gain;
    TDEAction* remove_gain;
    TDEAction* newalbum;
    TDEAction* remove;
    TDEAction* paste;
    TDEAction* open_albums;
    TDEAction* close_albums;

private slots:
    void showContextMenu( TQListViewItem*, const TQPoint&, int );

    /**
     * Remove selected items from the file list
     */
    void removeSelectedItems();

    /**
     * Creates a new 'album' item in the list view
     */
    void createNewAlbum();

    /**
     * Calculates the replay gain tags of the selected items
     */
    void calcSelectedItemsGain();

    /**
     * Remove the replay gain tags of the selected items
     */
    void removeSelectedItemsGain();

    void slotDropped( TQDropEvent*, TQListViewItem*, TQListViewItem* ); // NOTE rename?

    void processOutput( TDEProcess*, char*, int );
    void processExit( TDEProcess* );

signals:
    //void calcGain();
    //void removeGain();
//     void addFile( const TQString& filename );

    void processStarted();
    void processStopped();
    void updateProgress( int, int );

};

#endif // REPLAYGAINFILELIST_H
