/////////////////////////////////////////////////////////////////
//	Copyright © 2004-2008 by Symmetrix Software, Inc.
//				Brookfield, Wisconsin
//				ALL RIGHTS RESERVED
  

//////////////////////////////////////////////////////////////////////////////////
//	Little class to handle idle proceses...
//	Should not be instantiated.....   Everything is implemented at the "class" 
//	level 
function PLXIdler() {};

// Add an idle process with the specified process id (pid).  Call the specified 
//	function on idle.  Additional parameters are passed to aFunc.
PLXIdler.addProcess = function( pid, aFunc )
{
	// Insanity?
	if ( !pid )
		throw Error( "Idle process must have a pid..." );
		
	// More insanity?
	if ( !aFunc || !( aFunc instanceof Function ) )
		throw Error( "Idle process must have a function..." );
	
	// Create processes collection if needed.....
	if ( !PLXIdler._processes )
		{
		PLXIdler._processes = new Object;
		PLXIdler._processCount = 0;
		}
	
	// The defined behaviour is that adding a new process ID should REPLACE any
	// previous process with that idea.
	// So... we remove it, but ask that the timer not be stopped....
	PLXIdler.removeProcess( pid, true );
	
	// Set-up new process.  If additional arguments are specified, copy them into
	// an array for us to deliver to aFunc later....
	var newProcess = new Object;
	newProcess._aFunc = aFunc;
	if ( arguments.length > 2 )
		{
		newProcess._args = new Array;
		for ( var idx = 2; idx < arguments.length; idx++ )
			newProcess._args.push( arguments[idx] );
		}
	else
		newProcess._args = null;
		
	// Add the process.....
	PLXIdler._processes[pid] = newProcess;
	PLXIdler._processCount++;
	
	// If the timer's not running, then start it...
	if ( !PLXIdler._timerID )
		PLXIdler._timerID = setInterval( "PLXIdler.onIdle();", 250 );

}

// Remove the specified process.  keepTimerGoing == true keeps the
// timer going even if no processes are left after removal.  Default 
// is to cancel the timer.
PLXIdler.removeProcess = function( pid, keepTimerGoing )
{
	if ( PLXIdler._processes && PLXIdler._processes[pid] )
		{
		delete PLXIdler._processes[pid];
		PLXIdler._processCount--;
		}

	if ( PLXIdler._processCount <= 0 && !keepTimerGoing  )
		{
		clearInterval( PLXIdler._timerID );
		PLXIdler._timerID = null;
		}
}

PLXIdler.hasProcess = function( pid )
{
	return PLXIdler._processes && PLXIdler._processes[pid];
}

PLXIdler.onIdle = function()
{
	if ( !PLXIdler._processes )
		throw Error( "PLXIdler.onIdle() called with no processes." );;
		
	if ( PLXIdler._isBusy )
		return;
		
	PLXIdler._isBusy = true;
	
	// Run each of the "processes" (i.e. functions), passing them
	// the arguments (objects) specified when they were added.
	// Remove any processes that DO NOT need more time.
	// When last process is removed, the interval timer is canceled
	// by removeProcess().
	var completedProcesses = new Array;
	for ( var pid in PLXIdler._processes )
		{
		var currProc = PLXIdler._processes[pid];
		var needsMoreTime = currProc._aFunc.apply( null, currProc._args );
		if ( !needsMoreTime )
			completedProcesses.push( pid );
		}

	for ( var idx = 0; idx < completedProcesses.length; idx++ )
			PLXIdler.removeProcess( completedProcesses[idx] );
			
	PLXIdler._isBusy = false;
	
}

