/*

 BabbleMud - A MUD server

 Author:  Nick Gammon 
          http://www.gammon.com.au/ 

(C) Copyright Nick Gammon 2004. Permission to copy, use, modify, sell and
distribute this software is granted provided this copyright notice appears
in all copies. This software is provided "as is" without express or implied
warranty, and with no claim as to its suitability for any purpose.
 
*/

#ifdef WIN32
#include <windows.h>
// Windows needs some special help for directory scanning :-)
//    -dhaley aug-15-04
struct dirent
{
	char * d_name;
};

struct DIR
{
	HANDLE hDirectory;
	WIN32_FIND_DATA	Win32FindData;
	struct dirent	dirinfo;
	char sDirName[MAX_PATH];
};

DIR *opendir(const char * sDirName);
struct dirent *readdir (DIR * dp);
void closedir(DIR * dp);
#else

#include <dirent.h>

#endif


#include <string>

using namespace std; 

// see Ruminations on C++ p 280

// handy interface to directory-reading routines.

// example usage:

/*  

  // directory name
  string dirName = "./some_dir/";
  
  // constructor opens it
  Dir dir (dirName);

  // optionally check for error 
  // (it you don't, you just don't get any files returned)
  if (!dir.ok ())
    throw runtime_error (dirName + " not found");
  
  // process every file - in this case look for suffix .xml
  string file;
  while (!(file = dir.read ()).empty ())
    if (file.size () >= 5 && 
        tolower (file.substr (file.size () - 4, 4)) == ".xml")
          ProcessThisFile (dirName + file);    
 */
 
class Dir
  {
  public:
    // ctor
    Dir (const string & file) : dp_ (opendir (file.c_str ())) {}
    // dtor
    ~Dir () { if (dp_) closedir (dp_); }
    // returns true if directory opened OK
    const bool ok () const { return dp_ != NULL; }
    // read next entry - returns empty string if no more found
    const string read (const bool wantDotFiles = false)
      {
      if (!dp_)
        return "";
      for ( ; ; )
        {
        dirent * r = readdir (dp_);
        if (!r)
          return "";    // end of directory
        // skip files starting with . (eg. directories, temporary files)
        if (r->d_name [0] != '.' || wantDotFiles) 
          return r->d_name;
        }
      } // end of read
  
  private:
    DIR * dp_;
    // no copying
    Dir (const Dir &);
    Dir & operator= (const Dir &);
  };  // end of class Dir
