﻿

////////////////////////////////////////////////////////////////////////////////////////////////////
// TimerManager
////////////////////////////////////////////////////////////////////////////////////////////////////
function TimerManager()
{
    var This = this;
    
    // Data members
    This.Handles = {};
    This.TimerId = 0;
    
    // Methods
    This.NextId = function()
    {
        var id = This.TimerId;
        This.TimerId++;
        return id;
    }

    This.Start = function(iTimeout, iDelay, iRepeat)
    {
        var timerHandle = {};
        
        timerHandle.Id = This.NextId();
        timerHandle.Timeout = iTimeout;
        timerHandle.Repeat = iRepeat;

        This.Handles[timerHandle.Id] = timerHandle;
        
        if (iRepeat)
            timerHandle.Handle = setInterval('Timers.Timeout(' + timerHandle.Id + ')', iDelay);
        else
            timerHandle.Handle = setTimeout('Timers.Timeout(' + timerHandle.Id + ')', iDelay);
    
        return timerHandle;
    }

    This.Stop = function(iTimerHandle)
    {
        if (iTimerHandle.Handle)
        {
            if (iTimerHandle.Repeat)
                clearInterval(iTimerHandle.Handle);
            else
                clearTimeout(iTimerHandle.Handle);
            iTimerHandle.Handle = null;
        }

        delete This.Handles[iTimerHandle.Id];
    }

    This.Timeout = function(iTimerId)
    {
        var handle = This.Handles[iTimerId];

        if (handle && handle.Timeout)
            handle.Timeout();
    }
};


////////////////////////////////////////////////////////////////////////////////////////////////////
// Timers
////////////////////////////////////////////////////////////////////////////////////////////////////
var Timers = new TimerManager();


////////////////////////////////////////////////////////////////////////////////////////////////////
// Timer
////////////////////////////////////////////////////////////////////////////////////////////////////
function Timer(iDelay, iTimeoutHandler, iRepeat)
{
    var This = this;

    // Data members
    This.Handle = null;
    This.StartTime = null;
    This.Delay = null;
    This.Repeat = false;

    // Events
    This.OnTimeout = new EventHandler();

    // Methods
    This.Start = function()
    {
        if (!This.Handle)
        {
            This.StartTime = Date.now();
            This.Handle = Timers.Start(This.Timeout, This.Delay, This.Repeat);
        }
    }

    This.Stop = function()
    {
        if (This.Handle)
        {
            var time = Date.now() - This.StartTime;
            Timers.Stop(This.Handle);
            This.StartTime = null;
            return time;
        }
    }

    This.GetTime = function()
    { return Date.now() - This.StartTime; }

    This.Timeout = function()
    { This.OnTimeout.Invoke(Date.now() - This.StartTime); }
    
    // Initialize
    {
        This.Delay = iDelay;
        if (iTimeoutHandler)
            This.OnTimeout.Add(iTimeoutHandler);
        This.Repeat = (iRepeat) ? iRepeat : false;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
