using System;
namespace Wayne.Lib
{
    /// <summary>
    /// Factory for creating timers
    /// </summary>
    public interface  ITimerFactory
    {
        /// <summary>
        /// Create a timer 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="parentEntity"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        ITimer Create(int id, IIdentifiableEntity parentEntity, string name);

        /// <summary>
        /// Creates a timer
        /// </summary>
        /// <typeparam name="TState"></typeparam>
        /// <param name="id"></param>
        /// <param name="parentEntity"></param>
        /// <param name="name"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        ITimer<TState> Create<TState>(int id, IIdentifiableEntity parentEntity, string name, TState state);
    }

    /// <summary>
    /// Timer changer
    /// </summary>
    public interface ITimerChanger : IIdentifiableEntity, IDisposable
    {
        /// <summary>
        /// Changes the due time and interval of a timer.
        /// </summary>
        /// <param name="dueTime"></param>
        /// <param name="period"></param>
        /// <returns></returns>
        bool Change(TimeSpan? dueTime, TimeSpan? period);
    }
    
    /// <summary>
    /// Timer interface.
    /// </summary>
    public interface ITimer : ITimerChanger
    {
        /// <summary>
        /// Fired when the timer fires.
        /// </summary>
        event EventHandler OnTimeout;
    }

    /// <summary>
    /// Timer interface for a timer that has an argument.
    /// </summary>
    /// <typeparam name="TState"></typeparam>
    public interface ITimer<TState> : ITimerChanger
    {
        /// <summary>
        /// Fired when timer fires.
        /// </summary>
        event EventHandler<EventArgs<TState>> OnTimeout;
    }
}