#ifndef FILEINFO_H
#define FILEINFO_H
///////////////////////////////////////////////////////////////////////
//  fileInfo.h  -  manage file information extracted from Win32 API  //
//  ver 2.8                                                          //
//  Language:      Visual C++, ver 7.1                               //
//  Platform:      Dell Dimension 9150, Windows XP Pro, SP2          //
//  Application:   CSE687 Project #1, Spring 2006                    //
//  Author:        Jim Fawcett, Syracuse University CST 2-187,       //
//                 (315) 443-3948, jfawcett@twcny.rr.com             //
///////////////////////////////////////////////////////////////////////
/*
    class fileInfo Operations:
    --------------------------
    FileInfo provides a convenient way of finding all the files in
    a specific directory, as well as their associated attributes.

    The fileInfo class acquires file information from win32 API
    functions and returns parts of the information on demand.
    Specifically a fileInfo object extracts file name, size,
    and time and date of last modification for each file matching
    a pattern in the current directory.

    A fileInfo object saves the current directory path when created
    and its destructor restores that original path before the object
    is destroyed.  One function, setPath(const string&), will throw
    an exception if the path is invalid.  Handling of this exception
    is deferred to application code as fileInfo doesn't know what to
    do about that condition.  The test stub shows how an application
    can do that.

    Public Interface:
    -----------------
      fileInfo fi;                     void construct
      fileInfo fi(d:\test);            constructor setting path
      fileInfo fi2 = fi1;              copy constructor
      bool b = fi.firstFile("*.cpp");  find first file matching in
                                       current dir, true if exists
      bool b = fi.nextFile();          find next file matching
                                       pattern in current dir
      fi.closeFile();                  close file search
      string n = fi.name();            file name
      string d = fi.date();            file date last modified
      string t = fi.time();            file time last modified
      unsigned long int s = fi.size(); file size
      if(fi1 <  fi2) {...}             test file name order
      if(fi1 == fi2) {...}             test file name equality
      if(fi1.later(fi2)) {...}         test file time
      if(fi1.earlier(fi2)) {...}       test file time
      if(fi1.smaller(fi2)) {...}       test file size
      if(fi1.larger (fi2)) {...}       test file size
      fi.showData(cout);               display file data
      fi.showData(cout,'');            display with no return

      FILETIME ft = fi.getFILETIME();  return this file's FILETIME structure
      retVal = fi.compareFileTime(ft); return 1, 0, -1 if ft is earlier
                                         same, or later, respectively
      string path = fi.getPath();      get name of current dir
      fi.setPath(const string &path);  set current dir to path
      path = fi.getPath();             return current path
      path = fi.lastSetPath();         returns last path set

    See test stub for example of how to use fileInfo object with STL
    containers to get sets of files, sorted by name, date, or size.
*/
//
///////////////////////////////////////////////////////////////
//                      maintenance page                     //
///////////////////////////////////////////////////////////////
//  Build Process                                            //
//                                                           //
//  Files Required:                                          //
//    fileInfo.h, fileInfo.cpp                               //
//                                                           //
//  Building with Visual C++ , 8.0, from command line:       //
//    cl -EHsc -DTEST_FILEINFO fileInfo.cpp                  //
//                                                           //
///////////////////////////////////////////////////////////////
/*
    Maintenance History
    ===================
    ver 2.8 : 10 Feb 06
    - moved three functor classes: lessNoCase, earlier, and smaller
      into the fileInfo.cpp test stub.  They are private, used only
      by the test stub, so belong there.
    ver 2.7 : 19 Jan 05
    - added case insensitive file name comparisons
    - modified display in showData
    - eliminated some warnings with an appropriate static_cast
    - fixed constructor and operator= initialization bugs
    ver 2.6 : 22 Jan 05
    - added manual page information about exception handling
    ver 2.5 : 17 Jan 05
    - added display options and made cosmetic changes
    ver 2.4 : 03 May 04
    - added lastSetPath() to retrieve the last path searched.
    ver 2.3 : 01 May 04
    - the last fix broke recursion, reported by Kurt Denhoff, now
      fixed and uploaded to class code folder in getfiles and 
      fileInfo subfolders
    ver 2.2 : 27 Apr 04
    - added support for extracting and comparing FILETIME structures
    - setPath(const std::string&) now throws an invalid_argument
      exception if the path does not exist
    ver 2.1 : 23 Jan 04
    - cosmetic changes - eliminated a couple of comments and an
      unused line of code.
    ver 2.0 : 04 Apr 01
    - changed design so that directories are never set.  Now uses
      a specified path for file finding without changing the
      current directory
    ver 1.5 : 12 Jun 00
      - added extraction of attributes
    ver 1.4 : 29 Jan 00
      - added tests for earlier and smaller member functions in 
        test stub
    ver 1.3 : 14 Jul 99
      - more cosmetic modification to header file
    ver 1.2 : 11 Jul 99
      - added member function fileClose()
      - cosmetic modifications to both header and implem. files.
    ver 1.1 : 05 Jul 99
      - modified member function args, removing WIN32_FIND_DATA
        structures from all member function parameter lists
      - added firstFile(...) and nextFile() functions
      - save and restore original path
    ver 1.0 : 07 Feb 98
      - first release
*/
//
///////////////////////////////////////////////////////////////
//                         Declarations                      //
///////////////////////////////////////////////////////////////

#include <windows.h>
#include <string>

class fileInfo 
{
public:

  // object management
  fileInfo();
  fileInfo(const fileInfo &fi);
  fileInfo(const std::string &path);
  ~fileInfo();
  fileInfo& operator=(const fileInfo &fi);

  // search
  bool firstFile(const std::string &filePattern);
  bool nextFile();
  void closeFile();

  // file information
  std::string       name() const;
  unsigned long int size() const;
  std::string       date() const;
  std::string       time() const;
  FILETIME          getFILETIME();
  int               compareFileTime(FILETIME& ft);
  std::string       attributes() const;
  bool isArchive()    const;
  bool isCompressed() const;
  bool isDirectory()  const;
  bool isEncrypted()  const;
  bool isHidden()     const;
  bool isNormal()     const;
  bool isOffLine()    const;
  bool isReadOnly()   const;
  bool isSystem()     const;
  bool isTemporary()  const;

  // name comparisons
  bool operator< (const fileInfo &fi) const;
  bool operator==(const fileInfo &fi) const;

  // time comparisons
  bool earlier   (const fileInfo &fi) const;
  bool later     (const fileInfo &fi) const;

  // size comparisons
  bool smaller   (const fileInfo &fi) const;
  bool larger    (const fileInfo &fi) const;

  // directory management
  std::string lastSetPath();
  static std::string getPath();
  void setPath(const std::string& s);

//

  // quick display
  void showData(std::ostream &out,char ch='\n',int width=20) const;
  void showSize(bool show_size=true);
  void showSeconds(bool show_seconds=false);
  void showTime(bool show_time=true);
  void showDate(bool show_date=true);
  void showAttributes(bool show_attrib=true);

private:
  WIN32_FIND_DATA data;
  HANDLE _handle;
  SYSTEMTIME DateAndTime() const;
  std::string _OrigPath;
  std::string _CurrPath;
  bool showSize_;
  bool showSeconds_;
  bool showTime_;
  bool showDate_;
  bool showAttrib_;
};

//----< return last path searched >----------------------------

inline std::string fileInfo::lastSetPath() { return _CurrPath; }

//----< return file name >-------------------------------------

inline std::string fileInfo::name() const { return data.cFileName; }

//----< less than operator >-----------------------------------

inline bool fileInfo::operator<(const fileInfo &fd) const 
{
  return (strcmp(data.cFileName,fd.data.cFileName) == -1);
}

//----< comparison operator >----------------------------------

inline bool fileInfo::operator==(const fileInfo &fi) const 
{  
  return (strcmp(data.cFileName,fi.data.cFileName) == 0);
}

//----< comparison of file time and date >---------------------

inline bool fileInfo::earlier(const fileInfo &fi) const 
{
  return (
    CompareFileTime(&data.ftLastWriteTime,&fi.data.ftLastWriteTime) == -1
  );
}

//----< comparison of file time and date >---------------------

inline bool fileInfo::later(const fileInfo &fi) const 
{
  return (
    CompareFileTime(&data.ftLastWriteTime,&fi.data.ftLastWriteTime) == 1
  );
}
//
//----< display size? >----------------------------------------

inline void fileInfo::showSize(bool show_size)
{
  showSize_ = show_size;
}
//----< display time? >----------------------------------------

inline void fileInfo::showTime(bool show_time)
{
  showTime_ = show_time;
}
//----< display seconds in file time? >------------------------

inline void fileInfo::showSeconds(bool show_seconds)
{
  showSeconds_ = show_seconds;
}
//----< display date? >----------------------------------------

inline void fileInfo::showDate(bool show_date)
{
  showDate_ = show_date;
}
//----< display attributes? >----------------------------------

inline void fileInfo::showAttributes(bool show_attrib)
{
  showAttrib_ = show_attrib;
}

#endif
///////////////////////////////////////////////////////////////////////
//  fileInfo.cpp - manage file information extracted from Win32 API  //
//  ver 2.8                                                          //
//  Language:      Visual C++, ver 7.1                               //
//  Platform:      Dell Dimension 8300, Windows XP Pro, SP2          //
//  Application:   CSE687 Project #1, Spring 2005                    //
//  Author:        Jim Fawcett, Syracuse University CST 2-187,       //
//                 (315) 443-3948, jfawcett@twcny.rr.com             //
///////////////////////////////////////////////////////////////////////

#pragma warning(disable : 4786)
#include <iostream>
#include <iomanip>
#include <set>
#include "fileInfo.h"

//----< void constructor >-------------------------------------

fileInfo::fileInfo()
        : showSeconds_(false), showTime_(true), showDate_(true),
          showSize_(true), showAttrib_(true)
{ 
  _CurrPath = _OrigPath = getPath();
}
//----< constructor taking path >------------------------------

fileInfo::fileInfo(const std::string &path) 
        : showSeconds_(false), showTime_(true), showDate_(true),
          showSize_(true), showAttrib_(true)
{
  _OrigPath = getPath();
  setPath(path);
}
//
//----< copy constructor >-------------------------------------

fileInfo::fileInfo(const fileInfo &fi) 
: showSeconds_(fi.showSeconds_), showTime_(fi.showTime_),
showDate_(fi.showDate_), showSize_(fi.showSize_), showAttrib_(fi.showAttrib_)
{
  data.dwFileAttributes    = fi.data.dwFileAttributes;
  data.ftCreationTime      = fi.data.ftCreationTime;  
  data.ftLastAccessTime    = fi.data.ftLastAccessTime;
  data.ftLastWriteTime     = fi.data.ftLastWriteTime; 
  data.nFileSizeHigh       = fi.data.nFileSizeHigh;
  data.nFileSizeLow        = fi.data.nFileSizeLow; 
  data.dwReserved0         = fi.data.dwReserved0;
  data.dwReserved1         = fi.data.dwReserved1;
  int i;
  for(i=0; i<MAX_PATH; i++) 
  {
    data.cFileName[i]      = fi.data.cFileName[i];
    if(fi.data.cFileName[i] == '\0')
      break;
  }
  for(i=0; i<14; i++)
    data.cAlternateFileName[i] = fi.data.cAlternateFileName[i];

  _OrigPath = fi._OrigPath;
  _CurrPath = fi._CurrPath;
  showSeconds_ = fi.showSeconds_;
}
//----< destructor >-------------------------------------------

fileInfo::~fileInfo() { setPath(_OrigPath); }

//----< assignment operator >----------------------------------

fileInfo& fileInfo::operator=(const fileInfo &fi) 
{
  if(this == &fi) return *this;
  data.dwFileAttributes    = fi.data.dwFileAttributes;
  data.ftCreationTime      = fi.data.ftCreationTime;  
  data.ftLastAccessTime    = fi.data.ftLastAccessTime;
  data.ftLastWriteTime     = fi.data.ftLastWriteTime; 
  data.nFileSizeHigh       = fi.data.nFileSizeHigh;
  data.nFileSizeLow        = fi.data.nFileSizeLow; 
  data.dwReserved0         = fi.data.dwReserved0;
  data.dwReserved1         = fi.data.dwReserved1;
  showSize_ = fi.showSize_;
  showSeconds_ = fi.showSeconds_;
  showTime_ = fi.showTime_;
  showDate_ = fi.showDate_;
  showAttrib_ = fi.showAttrib_;
  int i;
  for(i=0; i<MAX_PATH; i++)
    data.cFileName[i]      = fi.data.cFileName[i];
  for(i=0; i<14; i++)
    data.cAlternateFileName[i] = fi.data.cAlternateFileName[i];
  _OrigPath = fi._OrigPath;
  _CurrPath = fi._CurrPath;

  return *this;
}
//
//----< get file size >----------------------------------------

unsigned long int fileInfo::size() const 
{
  DWORDLONG myDWL = (static_cast<DWORDLONG>(data.nFileSizeHigh) << 32);
  myDWL += (data.nFileSizeLow & 0xFFFFFFFF);
  return static_cast<unsigned long int>(myDWL);
}
//----< is my size smaller? >----------------------------------

bool fileInfo::smaller(const fileInfo &fi) const 
{  
  DWORDLONG myDWL = (static_cast<DWORDLONG>(data.nFileSizeHigh) << 32);
  myDWL += data.nFileSizeLow & 0xFFFFFFFF;
  DWORDLONG fiDWL = (static_cast<DWORDLONG>(fi.data.nFileSizeHigh) << 32);
  fiDWL += fi.data.nFileSizeLow & 0xFFFFFFFF;
  return (myDWL < fiDWL);
}
//----< is my size larger? >-----------------------------------

bool fileInfo::larger(const fileInfo &fi) const 
{  
  DWORDLONG myDWL = (static_cast<DWORDLONG>(data.nFileSizeHigh) << 32);
  myDWL += data.nFileSizeLow & 0xFFFFFFFF;
  DWORDLONG fiDWL = (static_cast<DWORDLONG>(fi.data.nFileSizeHigh) << 32);
  fiDWL += fi.data.nFileSizeLow & 0xFFFFFFFF;
  return (myDWL > fiDWL);
}
//----< return FILETIME >--------------------------------------
//
//  typedef struct _FILETIME
//  { DWORD dwLowDateTime;  DWORD dwHighDateTime; } FILETIME;
//
FILETIME fileInfo::getFILETIME()
{
  FILETIME lft;
  FileTimeToLocalFileTime(&data.ftLastWriteTime,&lft);
  return lft;
}
//----< compare file times >-----------------------------------
//
//  returns 1 if my FILETIME is later than ft
//          0 if my FILETIME equals ft
//         -1 if my FILETIME is earlier than ft
//
int fileInfo::compareFileTime(FILETIME& ft)
{
  FILETIME myft = getFILETIME();
  return (int)::CompareFileTime(&myft,&ft);
}
//
//----< private date and time extraction >---------------------

SYSTEMTIME fileInfo::DateAndTime() const 
{
 SYSTEMTIME st;
 FILETIME  lft;
 FileTimeToLocalFileTime(&data.ftLastWriteTime,&lft);
 FileTimeToSystemTime(&lft,&st);
 return st;
}
//----< get file date string >---------------------------------

std::string fileInfo::date() const 
{
  SYSTEMTIME st = DateAndTime();
  std::string date;
  date.resize(0);
  date += '0' + (st.wMonth / 10);
  date += '0' + (st.wMonth % 10);
  date += '/';
  date += '0' + (st.wDay / 10);
  date += '0' + (st.wDay % 10);
  date += '/';
  int tmp = st.wYear;
  date += '0' + (tmp/1000);
  tmp  %= 1000;
  date += '0' + (tmp / 100);
  tmp %= 100;
  date += '0' + (tmp / 10);
  tmp %= 10;
  date += '0' + (tmp);
  return date;
}
//----< get file time string >---------------------------------

std::string fileInfo::time() const 
{
  SYSTEMTIME st = DateAndTime();
  std::string time;
  std::string AMPM = "am";
  if(st.wHour > 12) 
  {
    st.wHour -= 12;
    AMPM = "pm";
  }
  time.erase();
  time += '0' + (st.wHour   / 10);
  time += '0' + (st.wHour   % 10);
  time += ':';
  time += '0' + (st.wMinute / 10);
  time += '0' + (st.wMinute % 10);
  if(showSeconds_)
  {
    time += ':';
    time += '0' + (st.wSecond / 10);
    time += '0' + (st.wSecond % 10);
  }
  time += " ";
  time += AMPM;
  return time;
}
//
//----< make attributes string >-------------------------------

std::string fileInfo::attributes() const 
{
  std::string temp;
  if(isArchive()   ) temp += 'A';
  if(isCompressed()) temp += 'C';
  if(isDirectory() ) temp += 'D';
  if(isEncrypted() ) temp += 'E';
  if(isHidden()    ) temp += 'H';
  if(isOffLine()   ) temp += 'O';
  if(isReadOnly()  ) temp += 'R';
  if(isSystem()    ) temp += 'S';
  if(isTemporary() ) temp += 'T';
  return temp;
}
//----< pragma needed to disable performance warning >---------
//
//  for some reason casts don't inhibit warning as they should

#pragma warning(disable : 4800)

//----< is this file Archive? >--------------------------------

bool fileInfo::isArchive() const 
{ 
  return (data.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE);
}
//----< is this file Compressed? >-----------------------------

bool fileInfo::isCompressed() const 
{   
  return (data.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED); 
}
//----< is this file Directory? >------------------------------

bool fileInfo::isDirectory() const 
{   
  return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); 
}
//
//----< is this file Encrypted? >------------------------------

bool fileInfo::isEncrypted() const 
{   
  return (data.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED); 
}
//----< is this file Hidden? >---------------------------------

bool fileInfo::isHidden() const 
{   
  return (data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN); 
}
//----< is this file Normal? >---------------------------------

bool fileInfo::isNormal() const 
{   
  return (data.dwFileAttributes & FILE_ATTRIBUTE_NORMAL); 
}
//----< is this file OffLine? >--------------------------------

bool fileInfo::isOffLine() const 
{   
  return (data.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE); 
}
//----< is this file ReadOnly? >-------------------------------

bool fileInfo::isReadOnly() const 
{   
  return (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY); 
}
//----< is this file System? >---------------------------------

bool fileInfo::isSystem() const 
{   
  return (data.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM); 
}
//----< is this file Temporary? >------------------------------

bool fileInfo::isTemporary() const 
{   
  return (data.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY); 
}
//
//----< display line of file data >----------------------------

void fileInfo::showData(std::ostream &out, char ch, int width) const 
{
  long save = out.flags();
  out.setf(std::ios::right, std::ios::adjustfield);
  if(showSize_)
    out << std::setw(10) << size();
  if(showDate_)
    out << "  " << date();
  if(showTime_ && showDate_)
    out << "  " << time();
  if(showAttrib_)
    out << "  " << attributes();
  out.setf(std::ios::left, std::ios::adjustfield);
  out << "  " << std::setw(width) << name();
  out << ch;
  out.flush();
  out.flags(save);
}
//----< get current searchPath >-------------------------------
//
//  fill with current directory path if empty
//
std::string fileInfo::getPath() 
{
  char buffer[256];
  ::GetCurrentDirectory(256,buffer);
  return std::string(buffer);
}
//----< set current directory >--------------------------------

void fileInfo::setPath(const std::string& s) 
{
  if(::SetCurrentDirectory(s.c_str()) == 0)
  {
    std::string temp = s + " - path not found";
    throw std::invalid_argument(temp.c_str());
  }
  _CurrPath = s;
}
//
//----< find first file >--------------------------------------

bool fileInfo::firstFile(const std::string &filePattern) 
{
  closeFile();    // close any previous search
  std::string path = getPath();
  if(path[path.size()-1] != '\\')
    path += '\\';
  path += filePattern;
  _handle = ::FindFirstFile(path.c_str(),&data);
  return (_handle != INVALID_HANDLE_VALUE);
}
//----< find next file >---------------------------------------

bool fileInfo::nextFile() 
{
  if(_handle == INVALID_HANDLE_VALUE)
    return false;
  return (::FindNextFile(_handle,&data) == TRUE);
}
//----< close search for current file >------------------------

void fileInfo::closeFile() {  FindClose(_handle); }

//
//----< test stub >--------------------------------------------

#ifdef TEST_FILEINFO

///////////////////////////////////////////////////////////////
// The classes below are private - only used by this test
// stub, and so are placed here, and not in fileInfo.h
//
//----< function object which detects case insensitive order >-------

class lessNoCase
{
public:
  bool operator()(const fileInfo &fi1, const fileInfo &fi2) {
    std::string name1 = fi1.name(), name2 = fi2.name();
    size_t leastSize = min(name1.size(), name2.size());
    for(size_t i=0; i<leastSize; ++i)
      if(tolower(name1[i]) > tolower(name2[i]))
        return false;
    return name1.size() < name2.size();
  }
};
//----< function object which detects date order >-------------

class earlier 
{
public:
  bool operator()(const fileInfo &fi1, const fileInfo &fi2) {
    return fi1.earlier(fi2);
  }
};
//----< function object which detects size order >-------------

class smaller 
{  
public:
  bool operator()(const fileInfo &fi1, const fileInfo &fi2) {
    return fi1.smaller(fi2);
  }
};
//
//----< test entry point >-------------------------------------

void main(int argc, char *argv[]) 
{
  std::cout << "\n  Testing Fileinfo objects "
            << "\n ==========================\n";

  // file names are unique, so use set

  typedef std::set< fileInfo, std::less<fileInfo>  > setNames;
  
  // lowercase file names, file dates, and file sizes
  // may not be unique, so use multiset

  typedef std::multiset< fileInfo, lessNoCase > setLCNames;
  typedef std::multiset< fileInfo, earlier > setDates;
  typedef std::multiset< fileInfo, smaller > setSizes;

  fileInfo f;
  f.showSeconds(true);
  try
  {
    if(argc > 1)
      f.setPath(argv[1]);
  }
  catch(std::exception& e) 
  { 
    std::cout << "\n\n  " << e.what() << "\n\n";
    f.setPath("..");
  }
  std::cout << "\n  path = " << f.getPath() << std::endl;

  std::cout << "\n  Files in FindNextFile Order\n";
  setNames sn;
  setLCNames sl;
  setDates sd;
  setSizes ss;

  if(!f.firstFile("*.*"))
    return;
  sn.insert(f);
  sl.insert(f);
  sd.insert(f);
  ss.insert(f);
  f.showData(std::cout);
  while(f.nextFile()) {
    sn.insert(f);
    sl.insert(f);
    sd.insert(f);
    ss.insert(f);
    f.showData(std::cout);
  }
  f.closeFile();
//

  std::cout << "\n  Files ordered alphabetically:\n";
  setNames::iterator fnIt;
  for(fnIt = sn.begin(); fnIt != sn.end(); fnIt++) {
    fnIt->showData(std::cout);
  }
  std::cout << "\n  Files with case insensitive alphabetic order:\n";
  setLCNames::iterator flIt;
  for(flIt = sl.begin(); flIt != sl.end(); flIt++) {
    flIt->showData(std::cout);
  }
  std::cout << "\n  Files ordered by date:\n";
  setDates::iterator fdIt;
  for(fdIt = sd.begin(); fdIt != sd.end(); fdIt++) {
    fdIt->showData(std::cout);
  }
  std::cout << "\n  Files ordered by size:\n";
  setSizes::iterator fsIt;
  for(fsIt = ss.begin(); fsIt != ss.end(); fsIt++) {
    fsIt->showData(std::cout);
  }
  std::cout << "\n\n";

  std::cout << "\n  Comparing file times:\n";
  setDates::iterator first = sd.begin();
  setDates::iterator second = first;
  ++second;
  std::cout << "\n  " << (*first).name() << " has date: "
            << (*first).date() << ", " << (*first).time();
  std::cout << "\n  " << (*second).name() << " has date: "
            << (*second).date() << ", " << (*second).time();
  int retVal = (*first).compareFileTime((*second).getFILETIME());
  if(retVal > 0)
    std::cout << "\n  " << (*first).name() 
              << " is later than " << (*second).name();
  if(retVal == 0)
    std::cout << "\n  " << (*first).name() 
              << " is same time as " << (*second).name();
  if(retVal < 0)
    std::cout << "\n  " << (*first).name() 
              << " is earlier than " << (*second).name();

  retVal = (*second).compareFileTime((*first).getFILETIME());
  if(retVal > 0)
    std::cout << "\n  " << (*second).name() 
              << " is later than " << (*first).name();
  if(retVal == 0)
    std::cout << "\n  " << (*second).name() 
              << " is same time as " << (*first).name();
  if(retVal < 0)
    std::cout << "\n  " << (*second).name() 
              << " is earlier than " << (*first).name();
//
  retVal = (*first).compareFileTime((*first).getFILETIME());
  if(retVal > 0)
    std::cout << "\n  " << (*first).name() 
              << " is later than " << (*first).name();
  if(retVal == 0)
    std::cout << "\n  " << (*first).name() 
              << " is same time as " << (*first).name();
  if(retVal < 0)
    std::cout << "\n  " << (*first).name() 
              << " is earlier than " << (*first).name();


  std::cout << "\n\n  Last search path = " << f.lastSetPath();
  std::cout << "\n\n";
}
#endif

  Testing Fileinfo objects 
 ==========================

  path = C:\SU\CSE687\Code\fileInfo

  Files in FindNextFile Order
         0  03/29/2006  05:26:57 am  D  .                   
         0  03/29/2006  05:26:57 am  D  ..                  
      2659  02/05/2006  10:50:18 am  A  analFI.dat          
      1355  02/05/2006  10:50:34 am  A  analNV.dat          
      1934  02/06/2006  08:16:41 am  A  analWT.dat          
       235  02/05/2006  11:19:30 am  A  bats.prn            
       153  02/05/2006  10:40:51 am  A  compile.bat         
     25088  02/02/2006  08:46:27 am  A  cover.doc           
         0  03/13/2006  08:32:47 pm  D  Debug               
         0  01/19/2006  02:57:41 pm  D  FileInfo            
     15696  02/10/2006  07:34:00 pm  A  FILEINFO.CPP        
         0  03/29/2006  05:27:32 am  A  fileinfo.dat        
    184320  03/29/2006  05:26:57 am  A  fileinfo.exe        
     10473  02/10/2006  07:34:00 pm  A  FILEINFO.H          
    333107  03/29/2006  05:26:57 am  A  fileinfo.obj        
      1814  02/05/2006  07:04:53 am  A  FILEINFO.sln        
     58368  02/28/2006  09:21:04 am  AH  FILEINFO.suo        
     25600  02/05/2006  11:10:31 am  A  FileInfoCover.doc   
     77312  02/19/2006  08:09:46 am  A  FileInfoProperties.doc
      5878  01/19/2006  02:35:53 pm  A  NAV.CPP             
     10374  02/05/2006  10:46:01 am  A  nav.dat             
      6089  01/19/2006  02:35:53 pm  A  NAV.H               
     26112  02/05/2006  11:16:46 am  A  NavCover.doc        
         0  01/19/2006  02:58:13 pm  D  Navigate            
        80  02/05/2006  10:43:14 am  A  run.bat             
      1770  01/19/2006  10:18:17 am  A  startup.bat         
      8454  01/19/2006  06:46:06 am  A  UpgradeLog.XML      
         0  02/28/2006  09:14:05 am  D  Win32Tools          
     12392  02/28/2006  09:18:12 am  A  WinTools.cpp        
      1220  02/05/2006  10:43:21 am  A  wintools.dat        
      6072  02/28/2006  09:18:12 am  A  WinTools.h          
     26112  02/06/2006  08:18:03 am  A  WintoolsCover.doc   
    269312  02/06/2006  08:13:27 am  A  WinToolsOutput.doc  
    266240  02/05/2006  08:57:09 am  A  WinToolsProperties.doc
     12850  03/01/2006  09:22:46 am  A  WS_FTP.LOG          

  Files ordered alphabetically:
         0  03/29/2006  05:26:57 am  D  .                   
         0  03/29/2006  05:26:57 am  D  ..                  
         0  03/13/2006  08:32:47 pm  D  Debug               
     15696  02/10/2006  07:34:00 pm  A  FILEINFO.CPP        
     10473  02/10/2006  07:34:00 pm  A  FILEINFO.H          
      1814  02/05/2006  07:04:53 am  A  FILEINFO.sln        
     58368  02/28/2006  09:21:04 am  AH  FILEINFO.suo        
         0  01/19/2006  02:57:41 pm  D  FileInfo            
     25600  02/05/2006  11:10:31 am  A  FileInfoCover.doc   
     77312  02/19/2006  08:09:46 am  A  FileInfoProperties.doc
      5878  01/19/2006  02:35:53 pm  A  NAV.CPP             
      6089  01/19/2006  02:35:53 pm  A  NAV.H               
     26112  02/05/2006  11:16:46 am  A  NavCover.doc        
         0  01/19/2006  02:58:13 pm  D  Navigate            
      8454  01/19/2006  06:46:06 am  A  UpgradeLog.XML      
     12850  03/01/2006  09:22:46 am  A  WS_FTP.LOG          
         0  02/28/2006  09:14:05 am  D  Win32Tools          
     12392  02/28/2006  09:18:12 am  A  WinTools.cpp        
      6072  02/28/2006  09:18:12 am  A  WinTools.h          
    269312  02/06/2006  08:13:27 am  A  WinToolsOutput.doc  
    266240  02/05/2006  08:57:09 am  A  WinToolsProperties.doc
     26112  02/06/2006  08:18:03 am  A  WintoolsCover.doc   
      2659  02/05/2006  10:50:18 am  A  analFI.dat          
      1355  02/05/2006  10:50:34 am  A  analNV.dat          
      1934  02/06/2006  08:16:41 am  A  analWT.dat          
       235  02/05/2006  11:19:30 am  A  bats.prn            
       153  02/05/2006  10:40:51 am  A  compile.bat         
     25088  02/02/2006  08:46:27 am  A  cover.doc           
         0  03/29/2006  05:27:32 am  A  fileinfo.dat        
    184320  03/29/2006  05:26:57 am  A  fileinfo.exe        
    333107  03/29/2006  05:26:57 am  A  fileinfo.obj        
     10374  02/05/2006  10:46:01 am  A  nav.dat             
        80  02/05/2006  10:43:14 am  A  run.bat             
      1770  01/19/2006  10:18:17 am  A  startup.bat         
      1220  02/05/2006  10:43:21 am  A  wintools.dat        

  Files with case insensitive alphabetic order:
         0  03/29/2006  05:26:57 am  D  .                   
         0  03/29/2006  05:26:57 am  D  ..                  
      2659  02/05/2006  10:50:18 am  A  analFI.dat          
      1355  02/05/2006  10:50:34 am  A  analNV.dat          
      1934  02/06/2006  08:16:41 am  A  analWT.dat          
       235  02/05/2006  11:19:30 am  A  bats.prn            
       153  02/05/2006  10:40:51 am  A  compile.bat         
     25088  02/02/2006  08:46:27 am  A  cover.doc           
         0  03/13/2006  08:32:47 pm  D  Debug               
         0  01/19/2006  02:57:41 pm  D  FileInfo            
     15696  02/10/2006  07:34:00 pm  A  FILEINFO.CPP        
         0  03/29/2006  05:27:32 am  A  fileinfo.dat        
    184320  03/29/2006  05:26:57 am  A  fileinfo.exe        
     10473  02/10/2006  07:34:00 pm  A  FILEINFO.H          
    333107  03/29/2006  05:26:57 am  A  fileinfo.obj        
      1814  02/05/2006  07:04:53 am  A  FILEINFO.sln        
     58368  02/28/2006  09:21:04 am  AH  FILEINFO.suo        
     25600  02/05/2006  11:10:31 am  A  FileInfoCover.doc   
     77312  02/19/2006  08:09:46 am  A  FileInfoProperties.doc
      5878  01/19/2006  02:35:53 pm  A  NAV.CPP             
     10374  02/05/2006  10:46:01 am  A  nav.dat             
      6089  01/19/2006  02:35:53 pm  A  NAV.H               
     26112  02/05/2006  11:16:46 am  A  NavCover.doc        
         0  01/19/2006  02:58:13 pm  D  Navigate            
        80  02/05/2006  10:43:14 am  A  run.bat             
      1770  01/19/2006  10:18:17 am  A  startup.bat         
      8454  01/19/2006  06:46:06 am  A  UpgradeLog.XML      
         0  02/28/2006  09:14:05 am  D  Win32Tools          
     12392  02/28/2006  09:18:12 am  A  WinTools.cpp        
      1220  02/05/2006  10:43:21 am  A  wintools.dat        
      6072  02/28/2006  09:18:12 am  A  WinTools.h          
     26112  02/06/2006  08:18:03 am  A  WintoolsCover.doc   
    269312  02/06/2006  08:13:27 am  A  WinToolsOutput.doc  
    266240  02/05/2006  08:57:09 am  A  WinToolsProperties.doc
     12850  03/01/2006  09:22:46 am  A  WS_FTP.LOG          

  Files ordered by date:
      8454  01/19/2006  06:46:06 am  A  UpgradeLog.XML      
      1770  01/19/2006  10:18:17 am  A  startup.bat         
      5878  01/19/2006  02:35:53 pm  A  NAV.CPP             
      6089  01/19/2006  02:35:53 pm  A  NAV.H               
         0  01/19/2006  02:57:41 pm  D  FileInfo            
         0  01/19/2006  02:58:13 pm  D  Navigate            
     25088  02/02/2006  08:46:27 am  A  cover.doc           
      1814  02/05/2006  07:04:53 am  A  FILEINFO.sln        
    266240  02/05/2006  08:57:09 am  A  WinToolsProperties.doc
       153  02/05/2006  10:40:51 am  A  compile.bat         
        80  02/05/2006  10:43:14 am  A  run.bat             
      1220  02/05/2006  10:43:21 am  A  wintools.dat        
     10374  02/05/2006  10:46:01 am  A  nav.dat             
      2659  02/05/2006  10:50:18 am  A  analFI.dat          
      1355  02/05/2006  10:50:34 am  A  analNV.dat          
     25600  02/05/2006  11:10:31 am  A  FileInfoCover.doc   
     26112  02/05/2006  11:16:46 am  A  NavCover.doc        
       235  02/05/2006  11:19:30 am  A  bats.prn            
    269312  02/06/2006  08:13:27 am  A  WinToolsOutput.doc  
      1934  02/06/2006  08:16:41 am  A  analWT.dat          
     26112  02/06/2006  08:18:03 am  A  WintoolsCover.doc   
     15696  02/10/2006  07:34:00 pm  A  FILEINFO.CPP        
     10473  02/10/2006  07:34:00 pm  A  FILEINFO.H          
     77312  02/19/2006  08:09:46 am  A  FileInfoProperties.doc
         0  02/28/2006  09:14:05 am  D  Win32Tools          
      6072  02/28/2006  09:18:12 am  A  WinTools.h          
     12392  02/28/2006  09:18:12 am  A  WinTools.cpp        
     58368  02/28/2006  09:21:04 am  AH  FILEINFO.suo        
     12850  03/01/2006  09:22:46 am  A  WS_FTP.LOG          
         0  03/13/2006  08:32:47 pm  D  Debug               
    333107  03/29/2006  05:26:57 am  A  fileinfo.obj        
         0  03/29/2006  05:26:57 am  D  .                   
         0  03/29/2006  05:26:57 am  D  ..                  
    184320  03/29/2006  05:26:57 am  A  fileinfo.exe        
         0  03/29/2006  05:27:32 am  A  fileinfo.dat        

  Files ordered by size:
         0  03/29/2006  05:26:57 am  D  .                   
         0  03/29/2006  05:26:57 am  D  ..                  
         0  03/13/2006  08:32:47 pm  D  Debug               
         0  01/19/2006  02:57:41 pm  D  FileInfo            
         0  03/29/2006  05:27:32 am  A  fileinfo.dat        
         0  01/19/2006  02:58:13 pm  D  Navigate            
         0  02/28/2006  09:14:05 am  D  Win32Tools          
        80  02/05/2006  10:43:14 am  A  run.bat             
       153  02/05/2006  10:40:51 am  A  compile.bat         
       235  02/05/2006  11:19:30 am  A  bats.prn            
      1220  02/05/2006  10:43:21 am  A  wintools.dat        
      1355  02/05/2006  10:50:34 am  A  analNV.dat          
      1770  01/19/2006  10:18:17 am  A  startup.bat         
      1814  02/05/2006  07:04:53 am  A  FILEINFO.sln        
      1934  02/06/2006  08:16:41 am  A  analWT.dat          
      2659  02/05/2006  10:50:18 am  A  analFI.dat          
      5878  01/19/2006  02:35:53 pm  A  NAV.CPP             
      6072  02/28/2006  09:18:12 am  A  WinTools.h          
      6089  01/19/2006  02:35:53 pm  A  NAV.H               
      8454  01/19/2006  06:46:06 am  A  UpgradeLog.XML      
     10374  02/05/2006  10:46:01 am  A  nav.dat             
     10473  02/10/2006  07:34:00 pm  A  FILEINFO.H          
     12392  02/28/2006  09:18:12 am  A  WinTools.cpp        
     12850  03/01/2006  09:22:46 am  A  WS_FTP.LOG          
     15696  02/10/2006  07:34:00 pm  A  FILEINFO.CPP        
     25088  02/02/2006  08:46:27 am  A  cover.doc           
     25600  02/05/2006  11:10:31 am  A  FileInfoCover.doc   
     26112  02/05/2006  11:16:46 am  A  NavCover.doc        
     26112  02/06/2006  08:18:03 am  A  WintoolsCover.doc   
     58368  02/28/2006  09:21:04 am  AH  FILEINFO.suo        
     77312  02/19/2006  08:09:46 am  A  FileInfoProperties.doc
    184320  03/29/2006  05:26:57 am  A  fileinfo.exe        
    266240  02/05/2006  08:57:09 am  A  WinToolsProperties.doc
    269312  02/06/2006  08:13:27 am  A  WinToolsOutput.doc  
    333107  03/29/2006  05:26:57 am  A  fileinfo.obj        



  Comparing file times:

  UpgradeLog.XML has date: 01/19/2006, 06:46:06 am
  startup.bat has date: 01/19/2006, 10:18:17 am
  UpgradeLog.XML is earlier than startup.bat
  startup.bat is later than UpgradeLog.XML
  UpgradeLog.XML is same time as UpgradeLog.XML

  Last search path = .

