/* The original version of this program can be found at http://damb.dk */
#include <windows.h>
#include <stdlib.h>
#include <iostream>
#include <map>
#include <string>
#include <direct.h>

void RefreshDirectory(const char *aDirName);

void WatchDirectory(const char *aDirName)
{
   RefreshDirectory(aDirName); // First list all files in the dir
   HANDLE ChangeHandle;

   ChangeHandle = FindFirstChangeNotification(aDirName, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);

   if(ChangeHandle == INVALID_HANDLE_VALUE)
      ExitProcess(GetLastError());

   while(1)
   {
      switch(WaitForSingleObject(ChangeHandle, INFINITE))
      {
      case WAIT_OBJECT_0:
         RefreshDirectory(aDirName);
         if(!FindNextChangeNotification(ChangeHandle))
            ExitProcess(GetLastError());
         break;
      default:
         ExitProcess(GetLastError());
      }
   }
}

std::map<std::string, bool >FileMap;
void RefreshDirectory(const char *aDirName)
{
   std::string SrcPattern = std::string(aDirName) + "*";
   std::map<std::string, bool >::iterator it;

   // First mark all as "not pressent"
   for(it = FileMap.begin(); it != FileMap.end(); ++it)
      it->second = false;

   WIN32_FIND_DATA FindFileData;
   HANDLE FindHandle = FindFirstFile(SrcPattern.c_str(), &FindFileData);

   if(FindHandle == INVALID_HANDLE_VALUE)
   {
     std::cerr << "Invalid File Handle. GetLastError reports: " <<  GetLastError() << std::endl;
     return;
   }
   do
   {
      if(!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
      {
         it = FileMap.find(FindFileData.cFileName);
         if(it != FileMap.end())
         {  // The file did exist
            it->second = true; // Mark as pressent
         }
         else
         {
            std::cout << "New file: " << FindFileData.cFileName << std::endl;
            FileMap.insert(std::make_pair(std::string(FindFileData.cFileName), true));
         }
      }
   }
   while(FindNextFile(FindHandle, &FindFileData));
   FindClose(FindHandle);

   // Find the files which has been removed
   for(it = FileMap.begin(); it != FileMap.end(); )
   {
      if(!it->second)
      {
         std::cout << "Removed: " << it->first << std::endl;
         FileMap.erase(it);
         it = FileMap.begin();
      }
      else
      {
         ++it;
      }
   }
}

int main()
{
   char Dir[256];
   getcwd(Dir, sizeof(Dir) - 1);
   strcat(Dir, "\\");
   WatchDirectory(Dir);
   return 0;
}