/****************************************************************************
** DialogFiles
**
**   Created : Tue Dec 11 22:48:00 2007
**        by : Varol Okan using XEmacs
** Copyright : (c) Varol Okan
**   License : GPL v 2.0
**
** This ialog offers an easy way to select and sort source files ( videos )
** into SourceFileEntries.
**
** This of course is helpfull if you have 100+ files
**
****************************************************************************/

#ifndef __DIALOGFILES_H__
#define __DIALOGFILES_H__


#include <qlistview.h>
#include <qmenudata.h>
#include <qlistbox.h>
#include <qprocess.h>
#include <qpixmap.h>
#include <qmap.h>

#include "qplayer/mediascanner.h"
#include "sourcefileentry.h"
#include "uidialogfiles.h"
#include "cachethumbs.h"

class QIconViewItem;
class QIconDragItem;
class QPushButton;
class QScrollView;
class QToolBox;
class QTimer;

class SourceToolBar;
class CXmlSlideshow;
class Previewer;

// Separate from global namspace because nested classes 
// are not supported by moc.
namespace Input
{

class DialogFiles; // forward declaration

class GroupView : public QListView
{
  Q_OBJECT
public:
  // This is the size for all thumbs in the list controls
  static const int m_iSize;

  class Item : public QListViewItem  {
    public:
    Item ( QListView *, QString, bool );
    Item ( QListView *, Item *, QString, bool );
    virtual ~Item ( );

    virtual void paintCell ( QPainter   *, const QColorGroup &, int, int, int );
    virtual int  width     ( const QFontMetrics &, const QListView *, int ) const;

    SourceFileInfo       *pSourceFileInfo;
    Cache::Thumbs::Entry *pCache;
    bool bAlternateColor;
  };

  GroupView ( QWidget *, QIconView *, DialogFiles *, SourceFileEntry *p=NULL );
  GroupView ( QWidget *, QIconView *, DialogFiles *, CXmlSlideshow   * );
  GroupView ( QWidget *, SourceFileEntry * );
  virtual ~GroupView  ( );

  void setSlideshow ( CXmlSlideshow * );

  CXmlSlideshow   *slideshow       ( ); // could be NULL
  SourceFileEntry *sourceFileEntry ( ); // could be NULL

  void append ( void * );

  QString groupName     ( );
  void    setGroupName  ( QString & );
protected: // member functions
  // Overloaded function
  virtual QDragObject *dragObject( );
  virtual void dropEvent         ( QDropEvent      * );
  virtual void dragEnterEvent    ( QDragEnterEvent * );
  virtual void timerEvent        ( QTimerEvent     * );

protected slots:
  virtual void slotAlternateColors ( );

private: // member variables
  QIconView       *m_pPreview;
  DialogFiles     *m_pDialog;
  SourceFileEntry *m_pSourceFileEntry;
  CXmlSlideshow   *m_pSlideshow;
};

class ScanDVDate : public QProcess
{
  Q_OBJECT
public:
  // Scanning the input video for DVDates
  ScanDVDate ( DialogFiles *, QString, QIconViewItem * );
  virtual ~ScanDVDate ( );

  bool hasExited ( );

protected slots:
  virtual void slotExited ( );

private:
  bool bExited;
  QString        qsFileName;
  QIconViewItem *pItem;
  DialogFiles   *pDialog;
};

class DialogFiles : public uiDialogFiles
{
  Q_OBJECT
  class DirItem : public QListViewItem  {
  public:
    DirItem ( QListView *, QString );
    DirItem ( DirItem *,   QString );
    virtual ~DirItem ( ) { };

    virtual void setOpen ( bool );
    QString  dir ( );
    DirItem *findSubDir ( QString );

  private:
    DirItem *pParent;
    QString  qsPathName;
    bool     bReadable;
  };
  class Manual  {
    // This class stores manual assignments of subtitles / audio tracks to video source files.
    // Instead of keeping this info around forever in the cache or project file, we limit it
    // to a working session of QDVDAuthor
  public:
    class Change  {
    public:
       Change ( );
      ~Change ( );

       void clearAudioList    ( );
       void clearSubtitleList ( );
       void copyAudioList     ( QValueList<Audio *>         & );
       void copySubtitleList  ( QValueList<SubtitleEntry *> & );
       QValueList<Audio *>         copyAudioList     ( );
       QValueList<SubtitleEntry *> copySubtitleList  ( );

       QString qsFileName;
       unsigned long long iHashValue;
       QValueList<Audio *> audioList;
       QValueList<SubtitleEntry *> subtitleList;
    };

     Manual ( );
    ~Manual ( );

     QString qsPath;  // The change is for a video file in this path
     unsigned long long iHashValue; // instead of searching path names, use a map of hash values.
     QMap<unsigned long long, Change *> mapOfChange;
  };

protected:
  // When the image is rendered the returned data is temp stored in this struct
  // to be executed in timerEvent.
  class WorkWaiting  {
  public:
     WorkWaiting ( QIconViewItem *, QImage *, bool );
    ~WorkWaiting ( );

    QIconViewItem *pItem;
    QImage        *pImage;
    QString        qsIconText;
    bool           bMarkIcon;
  };
  class ThumbnailRequest : public ExecuteJob {
  public:
    ThumbnailRequest ( DialogFiles * );
    ThumbnailRequest ( DialogFiles *, QIconViewItem *, QString, uint );
    virtual ~ThumbnailRequest ( );

    virtual bool response ( );

    QIconViewItem *pOwnerItem; 
    DialogFiles   *pParent;
    uint           iNumberOfThumbs;
  };
  class MultiThumbRequest : public ThumbnailRequest {
  public:
    MultiThumbRequest ( DialogFiles *, QIconViewItem *, QString, QImage *, uint );
    virtual ~MultiThumbRequest ( );

    virtual bool response ( );

    void createThumbs     ( );
    long iMovieLength;
    long iDelta;
    uint iSize;
    uint iCurrentThumb;
    QImage **arrayOfThumbs;
  };
  class Thumbs {
  public:
     Thumbs ( );
    ~Thumbs ( );

    bool findTracks    ( );
    void clearAudio    ( );
    void clearSubtitles( );
    bool audioTrackEnabled    ( QString & );
    bool subtitleTrackEnabled ( QString & );
    void toggleAudioTrack     ( Audio          *  );
    void toggleSubtitleTrack  ( SubtitleEntry  *  );
    bool getManualChange      ( Manual::Change *& );
    bool getManualChange      ( Manual *&, Manual::Change *&, unsigned long long &, unsigned long long & );

    QIconViewItem *pOwnerItem;
    QPixmap      **arrayOfPix; // these pixmaps are the scaled versions of pEntry->arrayOfThumbs
    uint           iNumberOfPix;
    uint           iCurrentPix;

    // we need a pointer to the corresponding cache object in here
    Cache::Thumbs::Entry *pCache;
    SourceFileInfo *pSourceFileInfo;          // only set if the item is created through a drop from a GroupView.
    QValueList<Audio *>         audioList;    // the list of associated Audio tracks
    QValueList<SubtitleEntry *> subtitleList; // the list of associated subtitle tracks
  };

public:
  class VFSelectItem : public QListBoxText  { //QListBoxItem {
  public:
    VFSelectItem ( bool, QListBox *, const QString &t=QString::null );
    virtual void paint ( QPainter * );
    virtual int height ( const QListBox * ) const;

    bool bAlternate;
  };

public: // public strctures ...
  DialogFiles ( QWidget *, bool b=false, const char *n=0, WFlags f=0 );
  virtual ~DialogFiles ( );

  static void clearMapOfChange ( );

  void initMe        ( );
  void initWork      ( QIconViewItem *, QImage *, bool );
  bool initScanDV    ( Thumbs * );
  void addProgress   ( int );
  uint thumbnailSize ( );
  static bool isMyself ( DialogFiles * );

  SourceFileInfo *findSourceFileInfo ( QIconViewItem * );
  QValueList<SourceFileEntry *> &getGroups ( );

protected:
  virtual void initGroups( );
  void createScrollView  ( );
  void copyEntry         ( SourceFileEntry *, SourceFileEntry * );
  GroupView *addGroup    ( QString &, QStringList & );
  void addSourceToGroup  ( GroupView * );
  QString uniqueGroupName( QString );
  bool findDesktopDir    ( QString );
  void initVirtualFolders( );
  void initMapOfChange   ( );
  void initDirectories   ( );
  void createIconStars   ( );
  bool isValid           ( Thumbs * );
  bool isValid           ( QIconViewItem * );
  bool removeThumb       ( QIconViewItem * );
  void addPlayButton     ( QIconViewItem *, QPixmap * );
  void recreateThumbs    ( Thumbs  * );
  void createPix         ( Thumbs  *, uint );
  void createPix         ( QPixmap *, QImage *, float f=0.0f, int i=-1 );
  void markIcon          ( QIconViewItem *, int );

  void setTreeDir        ( QString );
  void setQuickDir       (     int );
  void setCurrentDir     ( QString );
  QString currentDir     ( );

  void setVirtualFolder  ( int );
  void toSourceGroup     ( int );
  void toVirtualFolder   ( int );
  void registerRequest   ( MultiThumbRequest * );
  void append            ( Thumbs  * );
  void clearPreview      ( );
  void updateTitlebar    ( );
  void resizeIcons       ( int );
  Thumbs *createFromCache( Cache::Thumbs::Entry * );
  QPixmap &createMenuHeader   ( QString,  QSize   );
  void currentSourceToPreview ( );
  void allSourcesToPreview    ( );
  void stopThumbing           ( );
  void play                ( Cache::Thumbs::Entry *, QIconViewItem *p=NULL );
  void lock                ( );
  void unlock              ( );
  bool lockDialog          ( );
  void unlockDialog        ( );
  bool isImageDialog       ( );
  bool isImageDialog       ( QString );
  void applyManualChange   ( SourceFileEntry  * );
  void mergeAudioTracks    ( QValueList<Audio *> &, SourceFileInfo * );
  void mergeSubtitleTracks ( QValueList<SubtitleEntry *> &, SourceFileInfo * );

  QValueList<QListViewItem *> getSelectedVirtual ( );

  // Virtual functions
  virtual void timerEvent          ( QTimerEvent   * );
  virtual void load                ( QStringList   & );
  virtual void setIconText         ( Thumbs        * );
  virtual void setIconText         ( QIconViewItem * );
  virtual void newThumbnailRequest ( QIconViewItem * );
  virtual void showBasicMenu       ( const QPoint &  );
  virtual void showContextMenu     ( const QPoint &, QIconViewItem * );
  virtual GroupView *addGroup      ( SourceFileEntry * );
  virtual QString getDirFilter     ( );

protected slots:
  virtual void slotToVirtualFolder       ( QListBoxItem  * );
  virtual void slotToSourceGroup         ( QListBoxItem  * );
  virtual void slotAllToVirtualFolder    ( QListBoxItem  * );
  virtual void slotAllToSourceGroup      ( QListBoxItem  * );
  virtual void slotSourceToVirtualFolder ( QListBoxItem  * );
  virtual void slotSourceToSourceGroup   ( QListBoxItem  * );
  virtual void slotDirectoryChanged      ( QListViewItem * );
  virtual void slotGroupContextMenu      ( QListViewItem *, const QPoint &, int );
  virtual void slotPreviewClicked        ( int, QIconViewItem *, const QPoint & );
  virtual void slotPreviewPressed        (      QIconViewItem *, const QPoint & );
  virtual void slotDroppedOnPreview      ( QDropEvent *, const QValueList<QIconDragItem> & );
  virtual void slotVirtualChanged        ( );
  virtual void slotIconSelectionChanged  ( );
  virtual void slotAutoOpen              ( );
  virtual void slotQuickDir              ( );
  virtual void slotScanDir               ( );
  virtual void slotThumbing              ( );
  virtual void slotSelectByStars         ( );
  virtual void slotSizeReleased          ( );
  virtual void slotSizeChanged           ( int );
  virtual void slotAudioSubtitle         ( int );
  virtual void slotRegisterRequests      ( );
  virtual void slotAddGroup              ( );
  virtual void slotEditGroup             ( );
  virtual void slotDeleteGroup           ( );
  virtual void slotAddVirtual            ( );
  virtual void slotEditVirtual           ( );
  virtual void slotCloneVirtual          ( );
  virtual void slotDeleteVirtual         ( );
  virtual void slotPlay                  ( );
  virtual void accept                    ( );
  virtual void reject                    ( );
  virtual void slotResizeScrollView      ( );
  virtual void slotAutoGroup             ( );
  virtual void slotReload                ( );
  virtual void slotRefresh               ( );
  virtual void slotSetProgress           ( );
  virtual void slotAttrib                ( bool );
  virtual void slotShowVirtual           ( QListViewItem *, const QPoint &, int );
  virtual void slotVirtualContextMenu    ( QListViewItem *, const QPoint &, int );

protected:
  static bool m_bStars;
  static bool m_bName;
  static bool m_bDate;
  static bool m_bLength;
  static int  m_iThumbnailSize;
  static QMap<unsigned long long, Manual *> m_mapOfManualChange; // keep manual changes around for the duration of ths session
  bool        m_bTooSmallForText;    // less then 50x50 which is too small to display text
  bool        m_bExitScannFunction;  // For the ImageDialog to exit slotCheckWorker

  QTimer     *m_pTimerAutoOpen;
  QTimer     *m_pTimerScanDir;
  QTimer     *m_pTimerThumbing;
  QListBox   *m_pVirtualFolderDialog;
  Previewer  *m_pPreviewer;
  QPopupMenu *m_pContextMenu;

  QString   m_qsProjectDir;
  QString   m_qsDocumentsDir;
  QString   m_qsDesktopDir;
  QString   m_qsHomeDir;
  QString   m_qsRootDir;
  QString   m_qsTempDir;
  QString   m_qsCurrentDir;
  QPushButton *m_pActiveQuickButton;

  QPixmap   m_pixMenuStars[6];
  QPixmap   m_pixIconStars[7];

  bool      m_bCanClose;
  bool      m_bCanChangeIcons;
  bool      m_bIsImageDialog;   // Dialog can either be Image or Video dialog.
  uint      m_iProgress;
  uint      m_iMultiThumbNumber;

  QMutex    m_mutex;
  QMutex    m_mutexDialog;
  QMutex    m_mutexRequest;

  static DialogFiles *m_pIAmAlive;

  QValueList<ScanDVDate  *>       m_listOfDVScansToDo;
  QValueList<WorkWaiting *>       m_listOfWorkToDo;
  QValueList<MultiThumbRequest *> m_listOfRequests;

  Thumbs *m_pActiveThumbs;
  QValueList<Thumbs *>            m_listOfThumbs;
  QValueList<SourceFileEntry *>   m_listOfGroups;

  friend class GroupView;

  // Create the ScrollView or the Groups
  QScrollView *m_pScrollView;
  QToolBox    *m_pToolbox;
};

}; // end namespace Input

#endif // __DIALOGFILES_H__

