
/**
 * @filename:  class.countDown.js
 *
 * @description:  Javascript class that implements a count down to a specified event.
 * 				  The specified event is specified in the addEvent method, when the event
 *				  expires or the time has elapsed the event is fired.
 *
 * @access public
 * @param objName = name of the object
 * @see
 */
function countDown( objName )
{
	this.events = new Array();
    this.objName = objName;
    this.intervalID = -1;
    this.index = -1;
    this.debug = false;

	/*
	 * 	addEvent( id, targetDate, onTimeElapsed )
	 *
	 *  Adds an event to the event array
	 *
	 *  id 			 : is the tag element id value
	 *  targetDate	 : is the date & time ("04/15/2008 15:30") in which the event should fire
	 *  targetOffsetTZ : the offset of the target date time zone (-4, -5, etc)
	 *  onTimeElapsed: this is the event that will be fired when the time has elapsed.  there
	 *				 : are one parameter that is passed to this user defined function which is
	 *				 : the id of the tag element
     * passCargo     : this can be any value that is associated with each and is unique to each
     *               : event, it is passed on to the event handler when the timer expires
	 */
	this.addEvent = function( id, targetDate, targetOffsetTZ, outputExpression, onTimeElapsed, passCargo )
	{
		var newEvent = new Array();
		newEvent[ "id" ] = id;
		newEvent[ "targetDate" ] = targetDate;
		newEvent[ "targetOffsetTZ" ] = targetOffsetTZ;
		newEvent[ "onTimeElapsed" ] = onTimeElapsed;
		newEvent[ "outputExpression" ] = outputExpression;
        newEvent[ "passCargo" ] = passCargo;
		this.events.push( newEvent );
	}

	/*
	 * 	start()
	 *
	 *	Starts the event clock
	 */
	this.start = function()
	{
        if ( this.events.length > 0 )
        {
    		this.intervalID = setInterval( this.objName + "._countDown(); ", 990 );
        }
	}

	/*
	 * 	stop()
	 *
	 *	Stops the event clock
	 */
	this.stop = function()
	{
		if ( this.intervalID != -1 )
		{
			clearInterval( this.intervalID );
            this.intervalID = -1;
		}
	}

    this._calcDateUTC = function( targetOffsetTZ )
    {  
        try
        {
			var offset = targetOffsetTZ / 3600;
            var d = new Date();
            var utc = d.getTime() + ( d.getTimezoneOffset() * 60000 );
            var nd = new Date( utc + ( 3600000 * offset ) );     
            return ( nd );
        }
        catch( e )
        {
            if ( this.debug )
            {
                alert( e );
            }
        }
    }
    
	/*
	 * 	_countDown()
	 *
	 *	For internal use only; this is the function that gets fired through the setInterval() function
	 *
	 */
	this._countDown = function()
	{
	    this.stop();

		for ( this.index = 0; this.index < this.events.length; this.index++ )
		{
		    if ( this.events[ this.index ] != null )
            {
    			try
                {
        			today = this._calcDateUTC( this.events[ this.index ][ "targetOffsetTZ" ] );
        			eventTime = new Date( this.events[ this.index ][ "targetDate" ] );
        			ddiff = new Date( eventTime - today );
        			gsecs = Math.floor( ddiff.valueOf() / 1000 );

        			if ( gsecs <= 0 )
        			{
        				if ( this.events[ this.index ][ "onTimeElapsed" ] != null )
        				{
        				    try
                            {
            					this.events[ this.index ][ "onTimeElapsed" ](this.events[ this.index ][ "id" ], this.events[ this.index ][ "passCargo" ] );
                            }
                            catch( e )
                            {
                                if ( this.debug )
                                {
                                    alert( e );
                                }
                            }
                        }

                        this.events[ this.index ][ "id" ] = null;
                        this.events[ this.index ][ "onTimeElapsed" ] = null;
                        this.events[ this.index ][ "passCargo" ] = null;
                        this.events[ this.index ] = null;
        				this.events.splice( this.index, 1 );

                        if ( this.events.length == 0 )
                        {
                           break;
                        }
        			}
        			else
        			{
             		    document.getElementById( this.events[ this.index ][ "id" ] ).innerHTML = this._formatTimeLeft( gsecs );
        			}
                }
                catch ( e )
                {
                    if ( this.debug )
                    {
                        alert( e );
                    }
                }
            }
		}

        this.start();
	}

	/*
	 * 	_countBack()
	 *
	 *	For internal use only; this function calls _calcAge and then formats the output
	 *
	 */
	this._formatTimeLeft = function( secs )
	{
    	var retval = this.events[ this.index ][ "outputExpression" ];
		var prefix = false;


		var days = this._calcAge( secs, 86400, 100000 );
		if ( days > 0 )
		{
			retval = retval.replace( /%D%/g, days );
			prefix = true;
		}
		else
			retval = retval.replace( /%D%d/g, "" );


		var hours = this._calcAge( secs, 3600, 24 );
		if ( hours > 0 || prefix )
		{
			retval = retval.replace( /%H%/g, hours );
			prefix = true;
		}
		else
			retval = retval.replace( /%H%h/g, "" );


		var minutes = this._calcAge( secs, 60, 60 );
		if ( minutes > 0 || prefix )
		{
			retval = retval.replace( /%M%/g, minutes );
			prefix = true;
		}
		else
			retval = retval.replace( /%M%m/g, "" );


		var seconds = this._calcAge( secs, 1, 60 );
		if ( seconds > 0 || prefix )
		{
			prefix = true;
			retval = retval.replace( /%S%/g, seconds );
		}
		else
			retval = retval.replace( /%S%s/g, "" );


		return ( retval );
	}

	/*
	 * 	_calcAge()
	 *
	 *	For internal use only; this function calculates the age of the event depending up on the passed num# parameters
	 *
	 */
	this._calcAge = function ( secs, num1, num2 )
	{
		s = ( ( Math.floor( secs / num1 ) ) % num2 ).toString();

		if ( s.length < 2 )
		{
			s = "0" + s;
		}

		return ( s );
	}

}


