//
// FileSystemWatcher with Timer for Single Notification of File Changes
// http://noahcoad.com/post/14313643571/filesystemwatcher-with-timer-for-single-notification-of-file-changes
// by Noah Coad, 4/13/2012, licensed http://bit.ly/IsoYkj
//

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Timers;

namespace FileWatcherExample
{
	class Program
	{
		// Keep track of the timers for various files
		private static Dictionary<string, Timer> timers = new Dictionary<string, Timer>();

		static void Main(string[] args)
		{
			// Create the watcher and subscribe to events
			FileSystemWatcher fsw = new FileSystemWatcher(@"c:\temp\watchme");
			fsw.Created += new FileSystemEventHandler(fsw_Trigger);
			fsw.Changed += new FileSystemEventHandler(fsw_Trigger);
			fsw.Deleted += new FileSystemEventHandler(fsw_Trigger);
			fsw.Renamed += new RenamedEventHandler(fsw_Trigger);
			fsw.EnableRaisingEvents = true;

			// Continue listening until [ENTER] is pressed
			Console.WriteLine("Monitoring...");
			Console.ReadLine();
		}

		static void fsw_Trigger(object sender, FileSystemEventArgs e)
		{
			// Let the user know what type of change was triggered
			Console.WriteLine("File {0}: {1}", e.ChangeType, e.Name);

			// If a file was created or changed, start a timer
			if (e.ChangeType == WatcherChangeTypes.Created || e.ChangeType == WatcherChangeTypes.Changed)
			{
				Timer t;

				// Create a new timer if one isn't already assigned to this file
				if (timers.ContainsKey(e.FullPath)) t = timers[e.FullPath];
				else
				{
					// Adjust interval for your needs, 200ms is generally good
					timers.Add(e.FullPath, t = new Timer() { Interval = 200, AutoReset = false });
					t.Elapsed += new ElapsedEventHandler(fileTimer_Elapsed);
				}

				// Reset the timer
				t.Stop(); t.Start();
			}
		}
		
		static void fileTimer_Elapsed(object sender, ElapsedEventArgs e)
		{
			// A timer has elapsed, find out which file it belonged to and inform user
			Timer t = sender as Timer;
			string file = timers.First(a => a.Value == t).Key;
			Console.WriteLine("File done: " + file);

			// Remove the timer so the runtime will dispose of it
			timers.Remove(file);
		}
	}
}
