#ifndef COMPDIR_H
#define COMPDIR_H

//$Id: CompDir.h,v 1.25 2007/03/22 19:24:57 markus Rel $

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include <ctime>

#include <string>

#include <YGP/Check.h>
#include <YGP/PathSrch.h>


namespace YGP {
   struct File;
   class  IDirectorySearch;
}


class CompareDirs {
 public:
   typedef enum { NO_OPTION = 0, OPT_SEARCHSUBDIRS = 1, OPT_NOCHANGED = 2,
		  OPT_CHECKCONTENTS = 4, OPT_NODIRCOMP = 8, OPT_NONEWDEL = 16,
		  OPT_IGNORETIMESTAMP = 32, OPT_EQUAL = 64,
                  OPT_CHECKHIDDEN = 128, OPT_SEARCHEQUALSUBDIRS = 256 } Options;
   // *** DIR_DELETED, DIR_NEW must be the last two entries ***
   typedef enum { DIR_YOUNGER, DIR_OLDER, DIR_DIFFERENT, DIR_EQUAL,
		  DIR_DELETED, DIR_NEW } Status;

   CompareDirs ();
   CompareDirs (YGP::IDirectorySearch& dirOrig, YGP::IDirectorySearch& dirComp,
		const int option = NO_OPTION);
   CompareDirs (const CompareDirs&);
   virtual ~CompareDirs ();

   const CompareDirs& operator= (const CompareDirs&);

   void compare () throw (std::exception);

   // Set further parameters
   bool hasOption    (Options option) { return iOption & option; }
   void addOption    (Options option) { iOption |= option; }
   void removeOption (Options option) { iOption &= ~option; }
   void toggleOption (Options option) {
           iOption & option ? removeOption (option) : addOption (option); }

   void setOriginalDir (YGP::IDirectorySearch& dir);
   void setCompareDir  (YGP::IDirectorySearch& dir);

   void setBeginTime (time_t time) { datBegin = time; }
   void setEndTime   (time_t time) { datEnd = time; }
   int  setBeginTime (const char* pTime) { return setTime (pTime, datBegin); }
   int  setEndTime   (const char* pTime) { return setTime (pTime, datEnd); }

   void addIncludeFiles (const std::string& incl) { addNode (files, 'i', incl); }
   void addExcludeFiles (const std::string& excl) { addNode (files, 'x', excl); }
   void addIncludeDirs (const std::string& incl) {
     addNode (dirs, 'I', incl);
     iOption |= OPT_SEARCHSUBDIRS;
   }
   void addExcludeDirs (const std::string& excl) {
     addNode (dirs, 'X', excl);
     iOption |= OPT_SEARCHSUBDIRS;
   }
   void clearFiles () { files = ""; }
   void clearDirectories () { dirs = ""; }

   const YGP::IDirectorySearch* getOrigObject () const { return dirOrig; }
   const YGP::IDirectorySearch* getCompObject () const { return dirComp; }
   int checkIntegrity () const;

   static YGP::IDirectorySearch* makeSearchobject (const char* search, unsigned int port)
      throw (std::invalid_argument);

 protected:
   int         getOption () const { return iOption; }
   std::string getDirOrig () const { Check2 (dirOrig); return dirOrig->getDirectory (); }
   std::string getDirComp () const { Check2 (dirComp); return dirComp->getDirectory (); }
   std::string getDirStartComp () const { Check2 (dirOrig);
      return dirOrig->getDirectory ().replace (0, cOrigLen, 0, '\0'); }


   virtual void showFile (const Status diff, const YGP::File* pFileOrig,
			  const YGP::File* pFileComp = NULL) = 0;
   virtual void enterDirectory (const std::string& path) { }

 private:
   int          iOption;
   unsigned int cOrigLen;
   std::string  files;
   std::string  dirs;
   time_t       datBegin;
   time_t       datEnd;

   YGP::IDirectorySearch* dirOrig;
   YGP::IDirectorySearch* dirComp;

   int setTime (const char* pTime, time_t& time);

   bool checkDirectory (const char* pFile) const;
   bool checkDirname (const char* pszFile, const std::string& regexp) const;

   bool compareFiles (const YGP::File& fileOrig, const YGP::File& fileComp,
                      long& cmp) const;

   bool checkDate (time_t lTime) const
      { return ((lTime >= datBegin) && (lTime <= datEnd)); }

   static void addNode (std::string& list, char prefix, const std::string& node);

};

#endif


syntax highlighted by Code2HTML, v. 0.9.1