/*
	Roku.MySB.Mutex
*/

if(typeof(Roku) == "undefined")
    Roku = { classes : [] };
    
if(typeof(Roku.MySB) == "undefined")
    Roku.MySB = { };

Roku.MySB.Mutex =
{
	list					: new Object(),
	nextId					: 1
};

Roku.MySB.Mutex.execute = function(handler, custom_data)
{
	new MutexData(this.nextId++, handler, custom_data);
}


Roku.MySB.Mutex.add = function(key, data)
{ 
	this.list[key] = data;    
} 

Roku.MySB.Mutex.remove = function( key )
{ 
	delete this.list[key]; 
} 

Roku.MySB.Mutex.get = function( key )
{ 
	return key==null ? null : this.list[key]; 
} 

Roku.MySB.Mutex.first = function()
{ 
	return this.get(this.nextKey()); 
}

Roku.MySB.Mutex.next = function( key )
{ 
	return this.get( this.nextKey(key) ); 
} 

Roku.MySB.Mutex.nextKey = function( key )
{ 
	for (entry in this.list) 
	{ 
	    if (!key) 
			return entry; 
			
		if (key==entry) 
			key=null; /*tricky*/ 
    } 
    
    return null; 
} 

Roku.MySB.Mutex.SLICE = function( cmdID, startID )
{
	//Roku.Util.Trace("debug_out", "In SLICE: " + cmdID, true);
	this.get(cmdID).attempt( this.get(startID) ); 
}


function MutexData( cmdID, handler, custom_data )
{ 
	this.attempt = function( start ) 
	{ 
		for (var entry=start; entry; entry=Roku.MySB.Mutex.next(entry.id)) 
		{ 
			if (entry.stamp && 
					(entry.stamp < this.stamp || 
						(entry.stamp == this.stamp && entry.id < this.id) ) ) 
				return setTimeout("Roku.MySB.Mutex.SLICE("+this.id+","+entry.id+")", 5); 
		} 
		this.handler(this.custom_data); // Run
		this.stamp = 0;           //release
		Roku.MySB.Mutex.remove( this.id ); 
	} 
  
	// constructor logic 
	this.id       = cmdID; 
	this.handler = handler; 
	this.custom_data = custom_data; 
	Roku.MySB.Mutex.add( this.id, this ); // stamp is “false” 
	this.stamp   = (new Date()).getTime(); 
	var entry = Roku.MySB.Mutex.first();
	this.attempt( Roku.MySB.Mutex.first() ); 
} 
    
