// @(#)root/base:$Id$
// Author: Christian Bormann  13/10/97

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TSystemDirectory                                                     //
//                                                                      //
// Describes an Operating System directory for the browser.             //
//                                                                      //
// Author: Christian Bormann  30/09/97                                  //
//         http://www.ikf.physik.uni-frankfurt.de/~bormann/             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TSystemDirectory.h"
#include "TSystem.h"
#include "TBrowser.h"
#include "TOrdCollection.h"
#include "TList.h"


ClassImp(TSystemDirectory);

//______________________________________________________________________________
TSystemDirectory::TSystemDirectory()
{
   // Create a system directory object.

   fDirsInBrowser  = 0;
   fFilesInBrowser = 0;
}

//______________________________________________________________________________
TSystemDirectory::TSystemDirectory(const char *dirname, const char *path) :
   TSystemFile(dirname, path)
{
   // Create a system directory object.

   fDirsInBrowser  = 0;
   fFilesInBrowser = 0;
}

//______________________________________________________________________________
TSystemDirectory::TSystemDirectory(const TSystemDirectory& sd) :
  TSystemFile(sd),
  fDirsInBrowser(sd.fDirsInBrowser),
  fFilesInBrowser(sd.fFilesInBrowser)
{
   //copy constructor
}

//______________________________________________________________________________
TSystemDirectory& TSystemDirectory::operator=(const TSystemDirectory& sd)
{
   //assignment operator
   if(this!=&sd) {
      TSystemFile::operator=(sd);
      fDirsInBrowser=sd.fDirsInBrowser;
      fFilesInBrowser=sd.fFilesInBrowser;
   }
   return *this;
}

//______________________________________________________________________________
TSystemDirectory::~TSystemDirectory()
{
   // Delete system directory object.

   delete fDirsInBrowser;
   delete fFilesInBrowser;
}

//______________________________________________________________________________
TList *TSystemDirectory::GetListOfFiles() const
{
   // Returns a TList of TSystemFile objects representing the contents
   // of the directory. It's the responsibility of the user to delete
   // the list (the list owns the contained objects).
   // Returns 0 in case of errors.

   void *dir = gSystem->OpenDirectory(GetTitle());
   if (!dir) return 0;

   const char *file = 0;
   TList *contents  = new TList;
   contents->SetOwner();
   while ((file = gSystem->GetDirEntry(dir))) {
      if (IsItDirectory(file)) {
         TString sdirpath;
         if (file[0] == '.' && file[1] == '\0')
            sdirpath = GetTitle();
         else if (file[0] == '.' && file[1] == '.' && file[2] == '.')
            sdirpath = gSystem->DirName(GetTitle());
         else {
            sdirpath = GetTitle();
            if (!sdirpath.EndsWith("/"))
               sdirpath += "/";
            sdirpath += file;
         }
         contents->Add(new TSystemDirectory(file, sdirpath.Data()));
      } else
         contents->Add(new TSystemFile(file, GetTitle()));
   }
   gSystem->FreeDirectory(dir);
   return contents;
}

//______________________________________________________________________________
void TSystemDirectory::SetDirectory(const char *name)
{
   // Create a system directory object.

   SetName(name);
   SetTitle(name);
}

//______________________________________________________________________________
Bool_t TSystemDirectory::IsItDirectory(const char *name) const
{
   // Check if name is a directory.

   Long64_t size;
   Long_t id, flags, modtime;
   const char *dirfile = GetTitle();
   TString savDir = gSystem->WorkingDirectory();

   gSystem->ChangeDirectory(dirfile);
   flags = id = size = modtime = 0;
   gSystem->GetPathInfo(name, &id, &size, &flags, &modtime);
   Int_t isdir = (Int_t)flags & 2;

   gSystem->ChangeDirectory(savDir);
   return isdir ? kTRUE : kFALSE;
}

//______________________________________________________________________________
void TSystemDirectory::Browse(TBrowser *b)
{
   // Browse OS system directories.

   // Collections to keep track of all browser objects that have been
   // generated. It's main goal is to prevent the contineous
   // allocations of new objects with the same names during browsing.
   if (!fDirsInBrowser)  fDirsInBrowser  = new TOrdCollection;
   if (!fFilesInBrowser) fFilesInBrowser = new TOrdCollection(10);

   const char *name = GetTitle();
   TSystemFile *sfile;
   TSystemDirectory *sdir;
   const char *file;

   gSystem->ChangeDirectory(name);

   if (GetName()[0] == '.' && GetName()[1] == '.')
      SetName(gSystem->BaseName(name));

   void *dir = gSystem->OpenDirectory(name);

   if (!dir)
      return;

   while ((file = gSystem->GetDirEntry(dir))) {
      if (b->TestBit(TBrowser::kNoHidden) && file[0] == '.' && file[1] != '.' )
         continue;
      if (IsItDirectory(file)) {
         TString sdirpath;
         if (!strcmp(file, "."))
            sdirpath = name;
         else if (!strcmp(file, ".."))
            sdirpath = gSystem->DirName(name);
         else {
            sdirpath =  name;
            if (!sdirpath.EndsWith("/"))
               sdirpath += "/";
            sdirpath += file;
         }
         if (!(sdir = FindDirObj(sdirpath.Data()))) {
            sdir = new TSystemDirectory(file, sdirpath.Data());
            fDirsInBrowser->Add(sdir);
         }
         b->Add(sdir, file);
      } else {
         if (!(sfile = FindFileObj(file, gSystem->WorkingDirectory()))) {
            sfile = new TSystemFile(file, gSystem->WorkingDirectory());
            fFilesInBrowser->Add(sfile);
         }
         b->Add(sfile, file);
      }
   }
   gSystem->FreeDirectory(dir);
}

//______________________________________________________________________________
TSystemDirectory *TSystemDirectory::FindDirObj(const char *name)
{
   // Method that returns system directory object if it
   // exists in list, 0 otherwise.

   int size = fDirsInBrowser->GetSize();
   for (int i = 0; i < size; i++) {
      TSystemDirectory *obj = (TSystemDirectory *) fDirsInBrowser->At(i);
      if (!strcmp(name, obj->GetTitle()))
         return obj;
   }
   return 0;
}

//______________________________________________________________________________
TSystemFile *TSystemDirectory::FindFileObj(const char *name, const char *dir)
{
   // Method that returns system file object if it exists in
   // list, 0 otherwise.

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