/***************************************************************************
	  	                        vfs.h
  	                    -------------------
    begin                : Thu May 4 2000
    copyright            : (C) 2000 by Shie Erlich & Rafi Yanai
    e-mail               : krusader@users.sourceforge.net
    web site             : http://krusader.sourceforge.net
 ***************************************************************************

   A 

     db   dD d8888b. db    db .d8888.  .d8b.  d8888b. d88888b d8888b.
     88 ,8P' 88  `8D 88    88 88'  YP d8' `8b 88  `8D 88'     88  `8D
     88,8P   88oobY' 88    88 `8bo.   88ooo88 88   88 88ooooo 88oobY'
     88`8b   88`8b   88    88   `Y8b. 88~~~88 88   88 88~~~~~ 88`8b
     88 `88. 88 `88. 88b  d88 db   8D 88   88 88  .8D 88.     88 `88.
     YP   YD 88   YD ~Y8888P' `8888Y' YP   YP Y8888D' Y88888P 88   YD

                                                     H e a d e r    F i l e

 ***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef VFS_H
#define VFS_H

// QT includes
#include <tqstring.h>
#include <tqvaluelist.h>
#include <tqobject.h>
#include <tqdict.h>
// KDE includes
#include <kurl.h>
#include <kio/jobclasses.h>
// Krusader includes
#include "vfile.h"
#include "preservingcopyjob.h"
#include "krquery.h"

/**
 * The vfs class is an extendable class which by itself does (almost)
 * nothing. other VFSs like the normal_vfs inherits from this class and
 * make it possible to use a consistent API for all types of VFSs.
 */
class vfs: public TQObject{
	Q_OBJECT
  TQ_OBJECT
public:
	typedef TQDict<vfile> vfileDict;	
	enum VFS_TYPE{ERROR=0,NORMAL,FTP,TEMP,VIRT};

	/**
	 * Creates a vfs.
	 * @param panel the panel father. the VFS will connect it's signals to this object.
	 * @param quiet if true, the VFS will not display error messages
	 */
	vfs(TQObject* panel, bool quiet=false);
	virtual			~vfs();

	/// Copy a file to the vfs (physical).
	virtual void vfs_addFiles(KURL::List *fileUrls,KIO::CopyJob::CopyMode mode,TQObject* toNotify,TQString dir = "", PreserveMode pmode = PM_DEFAULT)=0;	
	/// Remove a file from the vfs (physical)
	virtual void vfs_delFiles(TQStringList *fileNames)=0;	
	/// Return a list of URLs for multiple files	
	virtual KURL::List* vfs_getFiles(TQStringList* names)=0;
	/// Return a URL to a single file	
	virtual KURL vfs_getFile(const TQString& name)=0;
	/// Create a new directory
	virtual void vfs_mkdir(const TQString& name)=0;
	/// Rename file
	virtual void vfs_rename(const TQString& fileName,const TQString& newName)=0;
	/// Calculate the amount of space occupied by a file or directory (recursive).
	virtual void vfs_calcSpace(TQString name ,KIO::filesize_t *totalSize,unsigned long *totalFiles,unsigned long *totalDirs, bool * stop);
	/// Calculate the amount of space occupied by a local file or directory (recursive).
	virtual void vfs_calcSpaceLocal(TQString name ,KIO::filesize_t *totalSize,unsigned long *totalFiles,unsigned long *totalDirs, bool * stop);

	/// Return the VFS working dir
	virtual TQString vfs_workingDir()=0;
	/// Return true if the VFS url is writable
	virtual bool vfs_isWritable() { return isWritable; }
	/// Return vfile* or 0 if not found
	inline vfile* vfs_search(const TQString& name){ return (*vfs_filesP)[name]; } 
	/// Return an empty vfile* list if not found
	TQValueList<vfile*> vfs_search(const KRQuery& filter);
	/// The total size of all the files in the VFS,
	KIO::filesize_t vfs_totalSize();
	/// The number of files in the VFS
	inline unsigned long vfs_noOfFiles() { return vfs_filesP->count(); }
	/// Returns the VFS url.
	inline KURL vfs_getOrigin()          { return vfs_origin;          }
	/// Return the VFS type.
	inline VFS_TYPE vfs_getType()        { return vfs_type;            }
	/// Returns true if vfs is busy
	inline bool vfs_isBusy()             { return vfs_busy;            }
	/// Return the first file in the VFS and set the internal iterator to the beginning of the list.
	inline vfile* vfs_getFirstFile(){ return (vfileIterator ? vfileIterator->toFirst() : 0); }
	/// Return the the next file in the list and advance the iterator.
	inline vfile* vfs_getNextFile() { return (vfileIterator ? ++(*vfileIterator) : 0);  }
	/// returns true if the vfs can be deleted without crash        
	virtual bool vfs_canDelete() { return deletePossible; } 
	/// process the application events               
	virtual bool vfs_processEvents();        
	/// process the application events               
	virtual void vfs_requestDelete();        
	/// process the application events               
	virtual bool vfs_isDeleting()    { return deleteRequested; }
   // KDE FTP proxy bug correction
   static KURL fromPathOrURL( const TQString &originIn );
   static TQString pathOrURL( const KURL &originIn, int trailingSlash = 0 );


public slots:
	/// Re-reads files and stats and fills the vfile list
	bool vfs_refresh(const KURL& origin);
	/// Used to refresh the VFS when a job finishs. it calls the refresh() slot
	/// or display a error message if the job fails
	bool vfs_refresh(KIO::Job* job);
	bool vfs_refresh();
	void vfs_setQuiet(bool beQuiet){ quietMode=beQuiet; }
	void vfs_enableRefresh(bool enable);        
	void vfs_invalidate() { invalidated = true; }          

signals:
	void startUpdate(); //< emitted when the VFS starts to refresh its list of vfiles.
	void startJob(KIO::Job* job);
	void incrementalRefreshFinished( const KURL& ); //< emitted when the incremental refresh was finished
	void addedVfile(vfile* vf);
	void deletedVfile(const TQString& name);
	void updatedVfile(vfile* vf);
	void cleared();
	void deleteAllowed();                

protected:
	/// Feel the vfs dictionary with vfiles, must be implemented for each vfs
	virtual bool populateVfsList(const KURL& origin, bool showHidden) = 0;
	/// Called by populateVfsList for each file
	void foundVfile( vfile *vf ) { vfs_tempFilesP->insert(vf->vfile_getName(),vf); }
	/// Set the vfile list pointer
	void setVfsFilesP(vfileDict* dict);
	/// clear and delete all current vfiles
	inline void clear();
	/// Add a new vfile to the list.
	inline void addToList(vfile *data){ vfs_filesP->insert(data->vfile_getName(),data); }
	/// Deletes a vfile from the list.
	inline void removeFromList(TQString name){ vfs_filesP->remove(name); }

	/// Deletes a vfile from the list.
	void calculateURLSize(KURL url,KIO::filesize_t *totalSize,unsigned long *totalFiles,unsigned long *totalDirs, bool * stop);
        
	VFS_TYPE      vfs_type;     //< the vfs type.
	KURL          vfs_origin;   //< the path or file the VFS originates from.
	bool          vfs_busy;     //< true if vfs is busy with refreshing
	bool quietMode;             //< if true the vfs won't display error messages or emit signals
	bool disableRefresh;        //< true if refresh is disabled
	bool isWritable;            //< true if it's writable
	KURL postponedRefreshURL;   //< true if vfs_refresh() was called when refresh is disabled.
	bool invalidated;           //< the content of the cache is invalidated
	bool panelConnected;        //< indicates that there's a panel connected. Important for disabling the dir watcher
	
protected slots:
	/// The slot for the KDirSize job
	void slotKdsResult(KIO::Job *job);
	void slotStatResultArrived(KIO::Job *job);
        
private:
	vfileDict*  vfs_filesP;    //< Point to a lists of virtual files (vfile).
	vfileDict*  vfs_tempFilesP;//< Temporary files are stored here
	TQDictIterator<vfile>* vfileIterator; //< Point to a dictionary of virtual files (vfile).
	
	// used in the calcSpace function
	bool* kds_busy;
	bool  stat_busy;
	bool  deletePossible;        
	bool  deleteRequested;
	KIO::UDSEntry entry;        
	KIO::filesize_t* kds_totalSize;
	unsigned long*   kds_totalFiles;
	unsigned long*   kds_totalDirs;
};

#endif
