// 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.Reflection;
using System.Timers;


namespace Hiperscan.Unix
{

    public static class Timeout
    {
        
        public delegate bool TimeoutHandler();
        public volatile static bool UseGLib = Timeout.CheckMonoAssembly();

        private static bool CheckMonoAssembly()
        {
            try
            {
                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 timer_handler)
        {
            if (UseGLib)
            {
                // use GLib.Mainloop or GLib.Timeout respectively
                try
                {
                    Timeout.AddHelper(interval, timer_handler);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
            else
            {
                if (interval == 0)
                    interval = 1;
                // GLib is not available, use System.Timers.Timer
                Timer timer = new Timer
                {
                    Interval = interval,
                    Enabled = true,
                    AutoReset = false,
                };

                timer.Elapsed += (o, e) =>
                {
                    timer.Enabled = false;
                    timer.Stop();
                    timer.Dispose();

                    bool restart = timer_handler();

                    if (restart)
                        Unix.Timeout.Add(interval, timer_handler);
                };

                timer.Start();
            }
        }

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