/*************************************************************************
 *
 *  $RCSfile: sfxdir.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2000/12/07 14:33:35 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SFXDIR_HXX
#define _SFXDIR_HXX

#include <tools/string.hxx>
#include <svtools/smplhint.hxx>

DECL_OBJHINT(SfxDirEntryHint, String);

#if 0
//! (pb) don't use it anymore!

#ifndef _DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif
#ifndef _TIMER_HXX //autogen
#include <vcl/timer.hxx>
#endif
#ifndef _SFXBRDCST_HXX //autogen
#include <svtools/brdcst.hxx>
#endif
#ifndef _REF_HXX //autogen
#include <tools/ref.hxx>
#endif
#ifndef _SFXSMPLHINT_HXX //autogen
#include <svtools/smplhint.hxx>
#endif
#ifndef _DATETIME_HXX //autogen
#include <tools/datetime.hxx>
#endif
#ifndef _SFXLSTNER_HXX //autogen
#include <svtools/lstner.hxx>
#endif

class SvStream;
class SvStringsDtor;
class SfxExtDir;
class SfxExtDirEntry;
class SfxExtDirEntryArr_Impl;
class SfxExtDirDummyArr_Impl;
struct SfxExtDirEntry_Impl;

#ifndef FSYS_ACCESS_FLOPPY
// FSysAccess
#if SUPD<365
#define FSysAccess  BOOL
#else
typedef int FSysAccess;
#endif
#define FSYS_ACCESS_FLOPPY          1
#define FSYS_ACCESS_CACHED          2
#endif

//=========================================================================

DECL_OBJHINT(SfxDirEntryHint, DirEntry);
DECL_PTRHINT(SfxExtDirEntryHint, SfxExtDirEntry);

//=========================================================================

class SfxExtDirSink_Impl: public SfxListener

/*  [Beschreibung]

	Hilfsklasse aus Kompatiblitaetsgruenden bis SfxExtDir von SfxListener
	abgeleitet ist.
*/

{
	SfxExtDir*                  _pDir;

protected:
	void                        Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
public:
								SfxExtDirSink_Impl(): _pDir(0) {}

	void						SetDir( SfxExtDir *pDir ) { _pDir = pDir; }
};

//=========================================================================

enum SfxExtDirEntryState
{
	SFX_EXTDIR_UNKNOWN,
	SFX_EXTDIR_UNCHANGED,	// stimmte mit Filesystem "uberein, unver"andert
	SFX_EXTDIR_UPDATED,     // wurde im FileSystem ver"andert, up-to-date
	SFX_EXTDIR_INSERTED, 	// wurde im FileSystem neu entdeckt, up-to-date
	SFX_EXTDIR_MODIFIED		// mu\s noch ins FileSystem updated werden
};

//=========================================================================

class SfxExtDirEntry: public SvRefBase, public DirEntry

/*	[Beschreibung]

	Instanzen dieser Klasse repr"asentieren einzelne Eintr"age in einem
	Directory. Sie cachen Directory-Informationen, wie z.B. Datum und Uhrzeit
	des letzten Zugriffs, erm"oglichen auf allen Filesystemen einen langen
	Dateinamen und k"onnen Zusatzinformationen aufnehmen, um Zugriffe auf
	das eigentliche File zu vermeiden.
*/

{
friend class SfxExtDir;

	SfxExtDir*					_pDir;      // falls in einem SfxExtDir enth.
	ULONG						_nPos;		// Position im Stream
	ULONG						_nId;		// persistente Id im soffice.dir
	String						_aTitle;	// plattformunabh"angiger Langname
	ULONG						_nSize; 	// Bytes beim letzten Speicherversuch
	DateTime					_aCreated;	// Datum+Zeit der Erzeugung
	DateTime					_aModified; // Datum+Zeit der letzten "Anderung
	DateTime					_aAccessed; // Datum+Zeit des letzten Zugriffs
	SvStringsDtor*				_pProps;	// Property-Array
	DirEntryKind				_eKind; 	// Art des Eintrags (Dir, File)
	USHORT						_nMaxSize;	// max. Gr"o\se im Stream (Bytes)
	SfxExtDirEntryState 		_eState;	// Status des Eintrag zum FileSystem
#if SUPD>358
	void*						_pUser;		// e.g. may point to ExpContent
#endif

#if 0 // _SOLAR__PRIVATE
private:
	void						SetId_Impl( ULONG nId )
								{
									DBG_ASSERT( !_nId, "SfxExtDir: already has id" );
									_nId = nId;
								}
	void						SetState_Impl( SfxExtDirEntryState eState )
								{ _eState = eState; }
	void						SetDir_Impl( SfxExtDir *pDir );
	BOOL                        IsKnown_Impl() const;
	void                        DetectTitle_Impl();
	ULONG						GetPos_Impl() const { return _nPos; }
	BOOL						Update_Impl( const FileStat &rStat );
#endif

protected:
	virtual void     			Renamed( const DirEntry& rDestDir );

public:
								SfxExtDirEntry();
								SfxExtDirEntry( SfxExtDir &rParent, const String &rTitle,
												const String &rExt, DirEntryKind eKind,
												USHORT nPos = USHRT_MAX, BOOL bUseTilde = FALSE );
								SfxExtDirEntry( const DirEntry &rPath );
								SfxExtDirEntry( const DirEntry &rPath, const FileStat &rStat );
								SfxExtDirEntry( SfxExtDir &rParent, ULONG nId,
												SvStream &rStream, ULONG nSize, DirEntryKind eKind );
	virtual 					~SfxExtDirEntry();

#if SUPD>358
	void						SetUserData( void* pUser ) { _pUser = pUser; }
	void*						GetUserData() const { return _pUser; }
#endif

	SfxExtDir*					GetDir() const { return _pDir; }

	inline SfxExtDirEntryState 	GetState() const;
	BOOL						Store( SvStream &rStream, USHORT bMaxSize = 0 );
	ULONG						GetId() const { return _nId; }

	const String&				GetTitle() const { return _aTitle; }
	ErrCode 					SetTitle( const String &rTitle );

	ULONG						GetSize() const { return _nSize; }
	DirEntryKind				GetKind() const;

	const DateTime& 			GetCreated() const { return _aCreated; }
	const DateTime& 			GetModified() const { return _aModified; }
	const DateTime& 			GetAccessed() const { return _aAccessed; }

	const String*				GetProperty( USHORT nPos ) const;
	void						SetProperty( const String& rProp, USHORT nPos );

	ErrCode						Kill() const;

	BOOL						UpdateStat();	// ohne Broadcast
	BOOL						Update();		// mit Broadcast

};

SV_DECL_IMPL_REF(SfxExtDirEntry)

//-------------------------------------------------------------------------

inline SfxExtDirEntryState SfxExtDirEntry::GetState() const

/*	[Beschreibung]

	Liefert Informationen dar"uber, wie der Eintrag im Vergleich zum
	Zustand vor <SfxExtDir::Lock()> stand:

	- schon vorhanden war und unver"andert ist: 	SFX_EXTDIR_UNCHANGED
	- schon vorhanden war ver"andert wurde: 		SFX_EXTDIR_CHANGED
	- neu eingef"ugt wurde ist: 					SFX_EXTDIR_INSERTED
	- mu\s noch ins FileSystem geschrieben werden: 	SFX_EXTDIR_MODIFIED

	Da nicht mehr vorhandene Eintr"age bereits in Lock() gel"oscht werden,
	kommt der Status SFX_EXTDIR_UNKNOWN nur tempor"ar vor.
*/

{
	return _eState;
}

//=========================================================================

class SfxExtDirFilter

/*	[Beschreibung]

	Durch Ableitung von dieser Klasse und "Uberladung der Methode
	<IsVisible()> kann das Aufnehmen bestimmter Dateien in Instanzen
	von <SfxExtDir> und deren Index-Files verhindert werden.

	Sie werden mit <SfxExtDir::SetFilter()> gesetzt.
*/

{
public:
	virtual BOOL	IsVisible( const DirEntry &rEntry ) const = 0;

	SfxExtDirFilter()
		{
		}

	virtual			~SfxExtDirFilter();
};

//=========================================================================

class SfxExtDir: public SfxExtDirEntry, public SfxBroadcaster

/*	[Bescheibung]

	Instanzen dieser Klasse bieten einen Zugriff auf ein Directory im
	File-System, das optional in einem Index-File gecached werden kann.
	Derart indizierte Directories unterst"utzen f"ur alle Plattformen
	Langnamen, die f"ur das Betriebssystem in Kurznamen gewandelt werden.
	Zus"atzlich zu den Langnamen kann der Index auch Properties aufnehmen,
	die ansonsten z.B. aus den Files gelesen werden m"u\sten.

	Eintr"age, welche selbst wieder Directories sind, werden als
	Instanzen von <SfxExtDir> erzeugt.

	Au\serdem gibt es die M"oglichkeit, das physikalische Directory
	zyklisch abscannen zu lassen, um "Anderungen von au\sen zu erkennen.

	Durch die Ableitung von <SfxBroadcaster> wird jede "Anderung an den
	in dieser Instanz gecacheten Daten gebroadcastet:

		SfxSimpleHint(SFX_HINT_DATACHANGED);

	[Beispiel]

	SfxExtDir aDir( "d:\\mi" );
	if ( ERRCODE_NONE == aDir.Lock(FALSE) )
	{
		for ( USHORT n = 0; n < aDir.Count(); ++n )
		{
			SfxExtDirEntry *pEntry = aDir.GetObject(n);
			...
		}

		aDir.Unlock(TRUE);
	}
*/

{
	void*					_pUserData; 		// nach aussen
	DirEntry				_aIndex;			// Name der Index-Datei
	ULONG					_nEndOfRecords; 	// Position hinter letztem Rec
	ULONG					_nLastKnownRevision;// Abgleich mit Cache-File
	ULONG					_nLastUsedId;		// h"ochste verwendete Entry-ID
	Dir*					_pUpdater;			// beim asynchronen Update
	SvStream*				_pStream;			// nur solange gelockt
	AutoTimer*				_pTimer;			// f"ur AutoUpdate+asynch
	SfxExtDirFilter*		_pFilter;			// unterdr"ucken von Entries
	SfxExtDirEntryArr_Impl* _pEntries;			// Array der Eintr"age
	SfxExtDirDummyArr_Impl* _pDummies;			// Array der Leer-Eintr"age
	SfxExtDirSink_Impl		_aSink; 			// f"ur Notify
	USHORT					_nRecordsInFile;	// Anzahl der Eintr"age im File
	USHORT					_nFreeRecords;		// Anzahl unbenutzer Eintr"age
	USHORT					_nLocks;			// Anzahl der Locks auf File
	BOOL					_bDirty;			// noch nicht committed

public:
#if SUPD<364
							SfxExtDir( const String &rPath );
#endif
							SfxExtDir( const DirEntry &rPath );
							SfxExtDir( const DirEntry &rPath, const FileStat &rStat );
							SfxExtDir( SfxExtDir &rParent, ULONG nId,
									   SvStream &rStream, ULONG nOffset, DirEntryKind eKind );
							SfxExtDir( SfxExtDir &rParent, const String &rTitle,
									   const String &rExt, DirEntryKind eKind,
									   USHORT nPos = USHRT_MAX );
							~SfxExtDir();

	void					SetAutoUpdateTimeout( ULONG nMilliSecs );
	ErrCode 				Commit( BOOL bAll = FALSE );
	ErrCode 				Lock( BOOL bReScan = FALSE, ULONG nTimeoutMilliSecs = 30*1000L );
	ErrCode 				Lock( BOOL bReScan, ULONG nTimeoutMilliSecs, BOOL bAll );
	ErrCode 				Unlock( BOOL bCommit = FALSE );
	ErrCode 				Update( BOOL bReScan = FALSE );
	ErrCode 				Update( BOOL bReScan, BOOL bAll );
	inline BOOL             UpdateActive() const;

	USHORT					Count() const;
	SfxExtDirEntry* 		GetObject( USHORT n ) const;

	SfxExtDirEntry* 		FindById( ULONG nId, USHORT *pPos = 0 ) const;
	SfxExtDirEntry* 		FindByName( const String &rName, USHORT *pPos = 0 ) const;

	ErrCode 				Insert( SfxExtDirEntry *pEntry, USHORT nPos = USHRT_MAX );
	ErrCode 				Remove( USHORT nPos );
	void    				RemoveOnly( USHORT nPos );

	void					SetFilter( SfxExtDirFilter *pFilter );

	static BOOL				IsIndexed( const DirEntry &rPath );
	BOOL             		IsIndexed() const;
	ErrCode 				RemoveIndex();

	ErrCode 				CreateIndex( BOOL bLock = FALSE );

	void*					GetUserData() { return _pUserData; }
	const void* 			GetUserData() const { return _pUserData; }
	void					SetUserData( void* pUserData ) { _pUserData = pUserData; }

	void                    EnableAppUpdate( BOOL bEnable );

#if 0 // _SOLAR__PRIVATE
	DECL_LINK				(AutoUpdate_Impl, void*);
	ErrCode 				Update_Impl( BOOL bAll = FALSE );
	void 					Clear_Impl();
	static void             Test_Impl();
#endif
};

// inlines ********************************************************************

inline BOOL SfxExtDir::UpdateActive() const
/*
  [Beschreibung]
  Die Methode gibt an, ob eine asynchrone Aktualisierung laeuft.
  */
{
	return _pUpdater != NULL;
}

SV_DECL_IMPL_REF(SfxExtDir)

#endif // 0

#endif // #ifndef _SFXDIR_HXX

