// @(#)root/base:$Id$
// Author: Rene Brun   28/11/94

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TDirectory
#define ROOT_TDirectory


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TDirectory                                                           //
//                                                                      //
// Describe directory structure in memory.                              //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TNamed
#include "TNamed.h"
#endif
#ifndef ROOT_TList
#include "TList.h"
#endif
#ifndef ROOT_TDatime
#include "TDatime.h"
#endif
#ifndef ROOT_TUUID
#include "TUUID.h"
#endif

class TBrowser;
class TKey;
class TFile;

class TDirectory : public TNamed {
public:
   /** @class Context
     *
     *  Small helper to keep current directory context.
     *  Automatically reverts to "old" directory
     */
   class TContext  {
   private:
      TDirectory *fDirectory;   //! Pointer to the previous current directory.
      TContext   *fPrevious;    //! Pointer to the next TContext in the implied list of context pointing to fPrevious.
      TContext   *fNext;        //! Pointer to the next TContext in the implied list of context pointing to fPrevious.
      TContext(TContext&);
      TContext& operator=(TContext&);
      void CdNull();
      friend class TDirectory;
   public:
      TContext(TDirectory* previous, TDirectory* newCurrent)
         : fDirectory(previous),fPrevious(0),fNext(0)
      {
         // Store the current directory so we can restore it
         // later and cd to the new directory.
         if ( fDirectory ) fDirectory->RegisterContext(this);
         if ( newCurrent ) newCurrent->cd();
         else CdNull();
      }
      TContext() : fDirectory(TDirectory::CurrentDirectory()),fPrevious(0),fNext(0)
      {
         // Store the current directory so we can restore it
         // later and cd to the new directory.
         if ( fDirectory ) fDirectory->RegisterContext(this);
      }
      TContext(TDirectory* newCurrent) : fDirectory(TDirectory::CurrentDirectory()),fPrevious(0),fNext(0)
      {
         // Store the current directory so we can restore it
         // later and cd to the new directory.
         if ( fDirectory ) fDirectory->RegisterContext(this);
         if ( newCurrent ) newCurrent->cd();
         else CdNull();
      }
      ~TContext()
      {
         // Destructor.   Reset the current directory to its
         // previous state.
         if ( fDirectory ) {
            fDirectory->UnregisterContext(this);
            fDirectory->cd();
         }
         else CdNull();
      }
   };

protected:

   TObject      *fMother;          //pointer to mother of the directory
   TList        *fList;            //List of objects in memory
   TUUID         fUUID;            //Unique identifier
   TString       fPathBuffer;      //!Buffer for GetPath() function
   TContext     *fContext;         //!Pointer to a list of TContext object pointing to this TDirectory
   static Bool_t fgAddDirectory;   //!flag to add histograms, graphs,etc to the directory

          Bool_t  cd1(const char *path);
   static Bool_t  Cd1(const char *path);

   virtual void   CleanTargets();
           void   FillFullPath(TString& buf) const;
           void   RegisterContext(TContext *ctxt);
           void   UnregisterContext(TContext *ctxt);
   friend class TContext;

protected:
   TDirectory(const TDirectory &directory);  //Directories cannot be copied
   void operator=(const TDirectory &); //Directorise cannot be copied

public:

   TDirectory();
   TDirectory(const char *name, const char *title, Option_t *option="", TDirectory* motherDir = 0);
   virtual ~TDirectory();
   static  void        AddDirectory(Bool_t add=kTRUE);
   static  Bool_t      AddDirectoryStatus();
   virtual void        Append(TObject *obj, Bool_t replace = kFALSE);
   virtual void        Add(TObject *obj, Bool_t replace = kFALSE) { Append(obj,replace); }
   virtual Int_t       AppendKey(TKey *) {return 0;}
   virtual void        Browse(TBrowser *b);
   virtual void        Build(TFile* motherFile = 0, TDirectory* motherDir = 0);
   virtual void        Clear(Option_t *option="");
   virtual TObject    *CloneObject(const TObject *obj, Bool_t autoadd = kTRUE);
   virtual void        Close(Option_t *option="");
   static TDirectory *&CurrentDirectory();  // Return the current directory for this thread.
   virtual void        Copy(TObject &) const { MayNotUse("Copy(TObject &)"); }
   virtual Bool_t      cd(const char *path = 0);
   virtual void        DeleteAll(Option_t *option="");
   virtual void        Delete(const char *namecycle="");
   virtual void        Draw(Option_t *option="");
   virtual TKey       *FindKey(const char * /*keyname*/) const {return 0;}
   virtual TKey       *FindKeyAny(const char * /*keyname*/) const {return 0;}
   virtual TObject    *FindObject(const char *name) const;
   virtual TObject    *FindObject(const TObject *obj) const;
   virtual TObject    *FindObjectAny(const char *name) const;
   virtual TObject    *FindObjectAnyFile(const char * /*name*/) const {return 0;}
   virtual TObject    *Get(const char *namecycle);
   virtual TDirectory *GetDirectory(const char *namecycle, Bool_t printError = false, const char *funcname = "GetDirectory");
   template <class T> inline void GetObject(const char* namecycle, T*& ptr) // See TDirectory::Get for information
      {
         ptr = (T*)GetObjectChecked(namecycle,TBuffer::GetClass(typeid(T)));
      }
   virtual void       *GetObjectChecked(const char *namecycle, const char* classname);
   virtual void       *GetObjectChecked(const char *namecycle, const TClass* cl);
   virtual void       *GetObjectUnchecked(const char *namecycle);
   virtual Int_t       GetBufferSize() const {return 0;}
   virtual TFile      *GetFile() const { return 0; }
   virtual TKey       *GetKey(const char * /*name */, Short_t /* cycle */=9999) const {return 0;}
   virtual TList      *GetList() const { return fList; }
   virtual TList      *GetListOfKeys() const { return 0; }
   virtual TObject    *GetMother() const { return fMother; }
   virtual TDirectory *GetMotherDir() const { return fMother==0 ? 0 : dynamic_cast<TDirectory*>(fMother); }
   virtual Int_t       GetNbytesKeys() const { return 0; }
   virtual Int_t       GetNkeys() const { return 0; }
   virtual Long64_t    GetSeekDir() const { return 0; }
   virtual Long64_t    GetSeekParent() const { return 0; }
   virtual Long64_t    GetSeekKeys() const { return 0; }
   virtual const char *GetPathStatic() const;
   virtual const char *GetPath() const;
   TUUID               GetUUID() const {return fUUID;}
   virtual Bool_t      IsFolder() const { return kTRUE; }
   virtual Bool_t      IsModified() const { return kFALSE; }
   virtual Bool_t      IsWritable() const { return kFALSE; }
   virtual void        ls(Option_t *option="") const;
   virtual TDirectory *mkdir(const char *name, const char *title="");
   virtual TFile      *OpenFile(const char * /*name*/, Option_t * /*option*/ = "",
                            const char * /*ftitle*/ = "", Int_t /*compress*/ = 1,
                            Int_t /*netopt*/ = 0) {return 0;}
   virtual void        Paint(Option_t *option="");
   virtual void        Print(Option_t *option="") const;
   virtual void        Purge(Short_t /*nkeep*/=1) {}
   virtual void        pwd() const;
   virtual void        ReadAll(Option_t * /*option*/="") {}
   virtual Int_t       ReadKeys(Bool_t /*forceRead*/=kTRUE) {return 0;}
   virtual Int_t       ReadTObject(TObject * /*obj*/, const char * /*keyname*/) {return 0;}
   virtual TObject    *Remove(TObject*);
   virtual void        RecursiveRemove(TObject *obj);
   virtual void        rmdir(const char *name);
   virtual void        Save() {}
   virtual Int_t       SaveObjectAs(const TObject * /*obj*/, const char * /*filename*/="", Option_t * /*option*/="") const;
   virtual void        SaveSelf(Bool_t /*force*/ = kFALSE) {}
   virtual void        SetBufferSize(Int_t /* bufsize */) {}
   virtual void        SetModified() {}
   virtual void        SetMother(TObject *mother) {fMother = (TObject*)mother;}
   virtual void        SetName(const char* newname);
   virtual void        SetTRefAction(TObject * /*ref*/, TObject * /*parent*/) {}
   virtual void        SetSeekDir(Long64_t) {}
   virtual void        SetWritable(Bool_t) {}
   virtual Int_t       Sizeof() const {return 0;}
   virtual Int_t       Write(const char * /*name*/=0, Int_t /*opt*/=0, Int_t /*bufsize*/=0){return 0;}
   virtual Int_t       Write(const char * /*name*/=0, Int_t /*opt*/=0, Int_t /*bufsize*/=0) const {return 0;}
   virtual Int_t       WriteTObject(const TObject *obj, const char *name =0, Option_t * /*option*/="", Int_t /*bufsize*/ =0);
private:
           Int_t       WriteObject(void *obj, const char* name, Option_t *option="", Int_t bufsize=0); // Intentionaly not implemented.
public:
   template <class T> inline Int_t WriteObject(const T* obj, const char* name, Option_t *option="", Int_t bufsize=0) // see TDirectory::WriteTObject or TDirectoryWriteObjectAny for explanation
      {
         return WriteObjectAny(obj,TBuffer::GetClass(typeid(T)),name,option,bufsize);
      }
   virtual Int_t       WriteObjectAny(const void *, const char * /*classname*/, const char * /*name*/, Option_t * /*option*/="", Int_t /*bufsize*/ =0) {return 0;}
   virtual Int_t       WriteObjectAny(const void *, const TClass * /*cl*/, const char * /*name*/, Option_t * /*option*/="", Int_t /*bufsize*/ =0) {return 0;}
   virtual void        WriteDirHeader() {}
   virtual void        WriteKeys() {}

   static Bool_t       Cd(const char *path);
   static void         DecodeNameCycle(const char *namecycle, char *name, Short_t &cycle, const size_t namesize = 0);
   static void         EncodeNameCycle(char *buffer, const char *name, Short_t cycle);

   ClassDef(TDirectory,5)  //Describe directory structure in memory
};

#ifndef __CINT__
#define gDirectory (TDirectory::CurrentDirectory())

#elif defined(__MAKECINT__)
// To properly handle the use of gDirectory in header files (in static declarations)
R__EXTERN TDirectory *gDirectory;
#endif

#endif
 TDirectory.h:1
 TDirectory.h:2
 TDirectory.h:3
 TDirectory.h:4
 TDirectory.h:5
 TDirectory.h:6
 TDirectory.h:7
 TDirectory.h:8
 TDirectory.h:9
 TDirectory.h:10
 TDirectory.h:11
 TDirectory.h:12
 TDirectory.h:13
 TDirectory.h:14
 TDirectory.h:15
 TDirectory.h:16
 TDirectory.h:17
 TDirectory.h:18
 TDirectory.h:19
 TDirectory.h:20
 TDirectory.h:21
 TDirectory.h:22
 TDirectory.h:23
 TDirectory.h:24
 TDirectory.h:25
 TDirectory.h:26
 TDirectory.h:27
 TDirectory.h:28
 TDirectory.h:29
 TDirectory.h:30
 TDirectory.h:31
 TDirectory.h:32
 TDirectory.h:33
 TDirectory.h:34
 TDirectory.h:35
 TDirectory.h:36
 TDirectory.h:37
 TDirectory.h:38
 TDirectory.h:39
 TDirectory.h:40
 TDirectory.h:41
 TDirectory.h:42
 TDirectory.h:43
 TDirectory.h:44
 TDirectory.h:45
 TDirectory.h:46
 TDirectory.h:47
 TDirectory.h:48
 TDirectory.h:49
 TDirectory.h:50
 TDirectory.h:51
 TDirectory.h:52
 TDirectory.h:53
 TDirectory.h:54
 TDirectory.h:55
 TDirectory.h:56
 TDirectory.h:57
 TDirectory.h:58
 TDirectory.h:59
 TDirectory.h:60
 TDirectory.h:61
 TDirectory.h:62
 TDirectory.h:63
 TDirectory.h:64
 TDirectory.h:65
 TDirectory.h:66
 TDirectory.h:67
 TDirectory.h:68
 TDirectory.h:69
 TDirectory.h:70
 TDirectory.h:71
 TDirectory.h:72
 TDirectory.h:73
 TDirectory.h:74
 TDirectory.h:75
 TDirectory.h:76
 TDirectory.h:77
 TDirectory.h:78
 TDirectory.h:79
 TDirectory.h:80
 TDirectory.h:81
 TDirectory.h:82
 TDirectory.h:83
 TDirectory.h:84
 TDirectory.h:85
 TDirectory.h:86
 TDirectory.h:87
 TDirectory.h:88
 TDirectory.h:89
 TDirectory.h:90
 TDirectory.h:91
 TDirectory.h:92
 TDirectory.h:93
 TDirectory.h:94
 TDirectory.h:95
 TDirectory.h:96
 TDirectory.h:97
 TDirectory.h:98
 TDirectory.h:99
 TDirectory.h:100
 TDirectory.h:101
 TDirectory.h:102
 TDirectory.h:103
 TDirectory.h:104
 TDirectory.h:105
 TDirectory.h:106
 TDirectory.h:107
 TDirectory.h:108
 TDirectory.h:109
 TDirectory.h:110
 TDirectory.h:111
 TDirectory.h:112
 TDirectory.h:113
 TDirectory.h:114
 TDirectory.h:115
 TDirectory.h:116
 TDirectory.h:117
 TDirectory.h:118
 TDirectory.h:119
 TDirectory.h:120
 TDirectory.h:121
 TDirectory.h:122
 TDirectory.h:123
 TDirectory.h:124
 TDirectory.h:125
 TDirectory.h:126
 TDirectory.h:127
 TDirectory.h:128
 TDirectory.h:129
 TDirectory.h:130
 TDirectory.h:131
 TDirectory.h:132
 TDirectory.h:133
 TDirectory.h:134
 TDirectory.h:135
 TDirectory.h:136
 TDirectory.h:137
 TDirectory.h:138
 TDirectory.h:139
 TDirectory.h:140
 TDirectory.h:141
 TDirectory.h:142
 TDirectory.h:143
 TDirectory.h:144
 TDirectory.h:145
 TDirectory.h:146
 TDirectory.h:147
 TDirectory.h:148
 TDirectory.h:149
 TDirectory.h:150
 TDirectory.h:151
 TDirectory.h:152
 TDirectory.h:153
 TDirectory.h:154
 TDirectory.h:155
 TDirectory.h:156
 TDirectory.h:157
 TDirectory.h:158
 TDirectory.h:159
 TDirectory.h:160
 TDirectory.h:161
 TDirectory.h:162
 TDirectory.h:163
 TDirectory.h:164
 TDirectory.h:165
 TDirectory.h:166
 TDirectory.h:167
 TDirectory.h:168
 TDirectory.h:169
 TDirectory.h:170
 TDirectory.h:171
 TDirectory.h:172
 TDirectory.h:173
 TDirectory.h:174
 TDirectory.h:175
 TDirectory.h:176
 TDirectory.h:177
 TDirectory.h:178
 TDirectory.h:179
 TDirectory.h:180
 TDirectory.h:181
 TDirectory.h:182
 TDirectory.h:183
 TDirectory.h:184
 TDirectory.h:185
 TDirectory.h:186
 TDirectory.h:187
 TDirectory.h:188
 TDirectory.h:189
 TDirectory.h:190
 TDirectory.h:191
 TDirectory.h:192
 TDirectory.h:193
 TDirectory.h:194
 TDirectory.h:195
 TDirectory.h:196
 TDirectory.h:197
 TDirectory.h:198
 TDirectory.h:199
 TDirectory.h:200
 TDirectory.h:201
 TDirectory.h:202
 TDirectory.h:203
 TDirectory.h:204
 TDirectory.h:205
 TDirectory.h:206
 TDirectory.h:207
 TDirectory.h:208
 TDirectory.h:209
 TDirectory.h:210
 TDirectory.h:211
 TDirectory.h:212
 TDirectory.h:213
 TDirectory.h:214
 TDirectory.h:215
 TDirectory.h:216
 TDirectory.h:217
 TDirectory.h:218
 TDirectory.h:219
 TDirectory.h:220
 TDirectory.h:221
 TDirectory.h:222
 TDirectory.h:223
 TDirectory.h:224
 TDirectory.h:225