// Created with MonoDevelop
//
//    Copyright (C) 2010 Hiperscan GmbH Dresden, Germany
//
//    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 3 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, see <http://www.gnu.org/licenses/>.



using System;
using System.Timers;
using System.Reflection;
using System.Collections.Generic;
using System.ComponentModel;


namespace Hiperscan.Unix
{

	public class Timeout
	{
		
		public delegate bool TimeoutHandler();
		public volatile static ISynchronizeInvoke SynchronizingObject = null;
		public volatile static bool UseGLib = Timeout.CheckMonoAssembly();
		private static Assembly glib_sharp = null;

		private volatile static List<Timer> timers = new List<Timer>();
		
		
		private static bool CheckMonoAssembly()
		{
			try
			{
				Timeout.glib_sharp = Assembly.Load("glib-sharp");
				Console.WriteLine("glib-sharp is available.");
				return true;
			}
			catch
			{
				Console.WriteLine("glib-sharp is not available.");
				return false;
			}
		}

		public static void Add(uint interval, TimeoutHandler hndlr)
		{
			if (UseGLib)
			{
				// use GLib.Mainloop or GLib.Timeout respectively
				try
				{
					Timeout.Add_Helper(interval, hndlr);
				}
				catch (Exception ex)
				{
					Console.WriteLine(ex);
//					Timeout.UseGLib = false;
//					Timeout.Add(interval, hndlr);
				}
			}
			else
			{
				// GLib is not available, use System.Timers.Timer
				Timer timer = new Timer();
				timer.Elapsed += delegate(object o, ElapsedEventArgs e) { hndlr(); };
				timer.Interval = interval;
				if (Timeout.SynchronizingObject != null)
					timer.SynchronizingObject = Timeout.SynchronizingObject;
				
				Timeout.timers.Add(timer);
				
				timer.Start();
			}
		}

		private static void Add_Helper(uint interval, TimeoutHandler hndlr)
		{
			GLib.Timeout.Add(interval, delegate { return hndlr(); });
		}
	}
}
