// @(#)root/table:$Id$
// Author: Valery Fine(fine@mail.cern.ch)   03/07/98

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

#include "TFileSet.h"
#include "TBrowser.h"
#include "TSystem.h"

#ifndef WIN32
#include <errno.h>
#endif

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TFileSet                                                             //
//                                                                      //
// TFileSet class is a class to convert the                             //
//      "native file system structure"                                  //
// into an instance of the TDataSet class                               //
//                                                                      //
//  Example:                                                            //
//    How to convert your home directory into the OO dataset            //
//                                                                      //
//  root [0] TString home = "$HOME";                                    //
//  root [1] TFileSet set(home);                                        //
//  root [2] TBrowser b("MyHome",&set);                                 //
//  root [3] set.ls("*");                                               //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

ClassImp(TFileSet)

//______________________________________________________________________________
TFileSet::TFileSet()
         : TDataSet()
{
   //to be documented
}

//______________________________________________________________________________
TFileSet::TFileSet(const TString &dirname,const Char_t *setname,Bool_t expand, Int_t maxDepth)
           : TDataSet()
{
  //
  // Creates TFileSet
  // Convert the "opearting system" file system tree into the memory resided TFileSet
  //
  //  Parameters:
  //  -----------
  //  dirname  - the name of the "native file system" directory
  //             to convert into TFileSet
  //  setname  - the name of this TFileSet (it is the "base name"
  //                                 of the "dirname" by default)
  //  expand   - flag whether the "dirname" must be "expanded
  //             (kTRUE by default)
  //  maxDeep  - the max number of the levels of the directory to read in
  //             (=10 by default)
  //  Note: If the "dirname" points to non-existent object, for examoe it is dead-link
  //  ----  the object is marked as "Zombie" and this flag is propagated upwards

   if (!maxDepth) return;

   Long64_t size;
   Long_t id, flags, modtime;
   TString dirbuf = dirname;

   if (expand) gSystem->ExpandPathName(dirbuf);
   const char *name= dirbuf;
   if (gSystem->GetPathInfo(name, &id, &size, &flags, &modtime)==0) {

      if (!setname) {
         setname = strrchr(name,'/');
         if (setname) setname++;
      }
      if (setname) SetName(setname);
      else SetName(name);

      // Check if "dirname" is a directory.
      void *dir = 0;
      if (flags & 2 ) {
         dir = gSystem->OpenDirectory(name);
         if (!dir) {
#ifndef WIN32
            perror("can not be open due error\n");
            Error("TFileSet", "directory: %s",name);
#endif
         }
      }
      if (dir) {   // this is a directory
         SetTitle("directory");
         while ( (name = gSystem->GetDirEntry(dir)) ) {
            // skip some "special" names
            if (!name[0] || strcmp(name,"..")==0 || strcmp(name,".")==0) continue;
            Char_t *file = gSystem->ConcatFileName(dirbuf,name);
            TString nextdir = file;
            delete [] file;
            TFileSet *fs = new TFileSet(nextdir,name,kFALSE,maxDepth-1);
            if (fs->IsZombie())  {
               // propagate "Zombie flag upwards
               MakeZombie();
            }
            Add(fs);
         }
         gSystem->FreeDirectory(dir);
      } else
         SetTitle("file");
   } else {
      // Set Zombie flag
      MakeZombie();
      SetTitle("Zombie");
   }
}

//______________________________________________________________________________
TFileSet::~TFileSet()
{
   //to be documented
}

//______________________________________________________________________________
Bool_t TFileSet::IsEmpty() const
{
   //to be documented
   return  strcmp(GetTitle(),"file")!=0 ? kTRUE : kFALSE ;
}

//______________________________________________________________________________
Long_t TFileSet::HasData() const
{
   // This implementation is done in the TDataSet::Purge() method in mind
   // Since this method returns non-zero for files the last are NOT "purged"
   // by TDataSet::Purge()
   //
   return strcmp(GetTitle(),"file")==0 ? 1 : 0;

   //  this must be like this:
   //  return !IsFolder() ;
   //  Alas TObject::IsFolder() isn't defined as "const" (IT IS in 2.25/03)
}

//______________________________________________________________________________
Bool_t TFileSet::IsFolder() const
{
   // If the title of this TFileSet is "file" it is NOT folder
   // see: TFileSet(TString &dirname,const Char_t *setname,Bool_t expand)
   //
   return strcmp(GetTitle(),"file")!=0;
}
 TFileSet.cxx:1
 TFileSet.cxx:2
 TFileSet.cxx:3
 TFileSet.cxx:4
 TFileSet.cxx:5
 TFileSet.cxx:6
 TFileSet.cxx:7
 TFileSet.cxx:8
 TFileSet.cxx:9
 TFileSet.cxx:10
 TFileSet.cxx:11
 TFileSet.cxx:12
 TFileSet.cxx:13
 TFileSet.cxx:14
 TFileSet.cxx:15
 TFileSet.cxx:16
 TFileSet.cxx:17
 TFileSet.cxx:18
 TFileSet.cxx:19
 TFileSet.cxx:20
 TFileSet.cxx:21
 TFileSet.cxx:22
 TFileSet.cxx:23
 TFileSet.cxx:24
 TFileSet.cxx:25
 TFileSet.cxx:26
 TFileSet.cxx:27
 TFileSet.cxx:28
 TFileSet.cxx:29
 TFileSet.cxx:30
 TFileSet.cxx:31
 TFileSet.cxx:32
 TFileSet.cxx:33
 TFileSet.cxx:34
 TFileSet.cxx:35
 TFileSet.cxx:36
 TFileSet.cxx:37
 TFileSet.cxx:38
 TFileSet.cxx:39
 TFileSet.cxx:40
 TFileSet.cxx:41
 TFileSet.cxx:42
 TFileSet.cxx:43
 TFileSet.cxx:44
 TFileSet.cxx:45
 TFileSet.cxx:46
 TFileSet.cxx:47
 TFileSet.cxx:48
 TFileSet.cxx:49
 TFileSet.cxx:50
 TFileSet.cxx:51
 TFileSet.cxx:52
 TFileSet.cxx:53
 TFileSet.cxx:54
 TFileSet.cxx:55
 TFileSet.cxx:56
 TFileSet.cxx:57
 TFileSet.cxx:58
 TFileSet.cxx:59
 TFileSet.cxx:60
 TFileSet.cxx:61
 TFileSet.cxx:62
 TFileSet.cxx:63
 TFileSet.cxx:64
 TFileSet.cxx:65
 TFileSet.cxx:66
 TFileSet.cxx:67
 TFileSet.cxx:68
 TFileSet.cxx:69
 TFileSet.cxx:70
 TFileSet.cxx:71
 TFileSet.cxx:72
 TFileSet.cxx:73
 TFileSet.cxx:74
 TFileSet.cxx:75
 TFileSet.cxx:76
 TFileSet.cxx:77
 TFileSet.cxx:78
 TFileSet.cxx:79
 TFileSet.cxx:80
 TFileSet.cxx:81
 TFileSet.cxx:82
 TFileSet.cxx:83
 TFileSet.cxx:84
 TFileSet.cxx:85
 TFileSet.cxx:86
 TFileSet.cxx:87
 TFileSet.cxx:88
 TFileSet.cxx:89
 TFileSet.cxx:90
 TFileSet.cxx:91
 TFileSet.cxx:92
 TFileSet.cxx:93
 TFileSet.cxx:94
 TFileSet.cxx:95
 TFileSet.cxx:96
 TFileSet.cxx:97
 TFileSet.cxx:98
 TFileSet.cxx:99
 TFileSet.cxx:100
 TFileSet.cxx:101
 TFileSet.cxx:102
 TFileSet.cxx:103
 TFileSet.cxx:104
 TFileSet.cxx:105
 TFileSet.cxx:106
 TFileSet.cxx:107
 TFileSet.cxx:108
 TFileSet.cxx:109
 TFileSet.cxx:110
 TFileSet.cxx:111
 TFileSet.cxx:112
 TFileSet.cxx:113
 TFileSet.cxx:114
 TFileSet.cxx:115
 TFileSet.cxx:116
 TFileSet.cxx:117
 TFileSet.cxx:118
 TFileSet.cxx:119
 TFileSet.cxx:120
 TFileSet.cxx:121
 TFileSet.cxx:122
 TFileSet.cxx:123
 TFileSet.cxx:124
 TFileSet.cxx:125
 TFileSet.cxx:126
 TFileSet.cxx:127
 TFileSet.cxx:128
 TFileSet.cxx:129
 TFileSet.cxx:130
 TFileSet.cxx:131
 TFileSet.cxx:132
 TFileSet.cxx:133
 TFileSet.cxx:134
 TFileSet.cxx:135
 TFileSet.cxx:136
 TFileSet.cxx:137
 TFileSet.cxx:138
 TFileSet.cxx:139
 TFileSet.cxx:140
 TFileSet.cxx:141
 TFileSet.cxx:142
 TFileSet.cxx:143
 TFileSet.cxx:144
 TFileSet.cxx:145
 TFileSet.cxx:146
 TFileSet.cxx:147
 TFileSet.cxx:148
 TFileSet.cxx:149
 TFileSet.cxx:150
 TFileSet.cxx:151
 TFileSet.cxx:152
 TFileSet.cxx:153
 TFileSet.cxx:154
 TFileSet.cxx:155