//****************************************************************************
// Copyright (C) thePlatform for Media, Inc. All Rights Reserved.
//****************************************************************************

// dynamically resize an element, for example, the category list
function tpResize(divID, height, width)
{
	var element = document.getElementById(divID);
	element.style.height = height + "px";
	element.style.width = width + "px";
}

// open a new pop-up window
function tpOpenNewWindow(URLtoOpen, windowName, windowFeatures)
{
	var newWindow=window.open(URLtoOpen, windowName, windowFeatures); 
}

// implementation of a message queue
function tpMessageQueue()
{
	// used to maintain the list of registered components
	var _componentMap = {};

	// handle component registration
	this.register = function(id)
	{
		_log("REGISTER: '" + id + "'");
		_componentMap[id] = 'registered';
	}

	// check if a component is registered
	function _isRegistered(id)
	{
		return _componentMap[id];
	}

	// used to maintain a message queue
	var _messageMap = {};

	// keep track of the message timer
	var _timerID = null;
	
	// unregister everything; used if you're changing controls in place on the page
	this.unregisterAll = function()
	{
		if (_timerID != null)
		{
			clearTimeout(_timerID);
			_timerID = null;
		}
		_componentMap = {};
		_messageMap = {};
		_log("UNREGISTERALL: unregistered all components");
	}

	// start up the messaging service
	function _startMessaging()
	{
		if (_timerID == null)
		{
			_timerID = setTimeout(_processQueue, 50);
		}
	}

	// send a message
	function _makeCall(message, attempt)
	{
		var params = "";
		for (var i = 0; i < message.parameters.length; i++)
		{
			if (params.length > 0)
			{
				params += ", ";	
			}
			params += "message.parameters[" + i + "]";	
		}

		// build the call
		var call = "document.getElementById('" + message.recipient + "')." + message.method + "(" + params + ");"
		_log("MAKECALL_" + attempt + ": " + call);
		try
		{
			eval(call);
		}
		catch (e)
		{
			// some unexpected error... reschedule the call
			_log("MAKECALL_" + attempt + ": error on \"" + call + "\": " + e.message);
			if (attempt < 10)
			{
				setTimeout(function() {_makeCall(message, attempt + 1)}, 50);
			}
			else
			{
				_log("MAKECALL: reached maximum attempts to send, discarding message");
			}
		}			
	}

	// run through the message queue, and send messages to whatever's registered
	function _processQueue()
	{
		_log("PROCESSQUEUE: checking for pending messages");
		_timerID = null;
		var pendingMessages = false;
		for (var componentID in _messageMap)
		{
			var messages = _messageMap[componentID];
			if (messages.length > 0)
			{
				if (_isRegistered(componentID))
				{
					// component is registered now, send messages
					_log("PROCESSQUEUE: '" + componentID + "' has " + messages.length + " pending message(s)");
					while (messages.length > 0)
					{
						// get the message
						var message = messages.shift();
						
						// make the call
						_makeCall(message, 1);
					}
				}
				else
				{
					// component is not registered yet, need to try again later
					_log("PROCESSQUEUE: '" + componentID + "' not registered yet, try again later");
					pendingMessages = true;
				}
			}
			else
			{
				_log("PROCESSQUEUE: '" + componentID + "' has no pending messages");
			}
		}
		if (pendingMessages)
		{
			_startMessaging();
		}
	}

	// handle messaging between components
	this.sendMessage = function(recipient, method, parameters)
	{
		// build the message
		_log("SENDMESSAGE: called with (recipient=" + recipient + ", method=" + method + ", parameters=" + parameters + ")");
		var message =
		{
			recipient: recipient,
			method: method,
			parameters: parameters
		};
		
		// if the component is already registered, skip the timer; just do a call-back
		// but on a separate thread, to avoid Flash blocking on overlapping synchronous
		// call
		if (_isRegistered(recipient))
		{
			setTimeout(function() {_makeCall(message, 1)}, 0);		
		}
		else
		{
			_log("SENDMESSAGE: '" + recipient + "' is not registered, enqueue");
			_addMessage(recipient, message);
			_startMessaging();
		}
	}

	// add a message to the queue
	function _addMessage(recipient, message)
	{
		if (!_messageMap[recipient])
		{
			_messageMap[recipient] = new Array();
		}
		_messageMap[recipient].push(message);
	}
	
	// whether or not logging is enabled by default
	var _isDebug = false;
	
	// change the logging state
	this.setDebug = function(isDebug)
	{
		_isDebug = isDebug;
	}
	
	// logging
	this.log = _log;
	
	function _log(message)
	{
		if (_isDebug && typeof console != "undefined")
		{
			console.log("tpDebug: " + ((new Date()).getTime() / 1000) + ": " + message);
		} 
	}
}

// queue instance
var queue = new tpMessageQueue();

// register a new component
function tpRegister(id)
{
	queue.register(id);
}

// unregister all components
function tpUnregisterAll()
{
	queue.unregisterAll();
}

// send a message from one component to another
function tpSendMessage(recipient, method, parameters)
{
	queue.sendMessage(recipient, method, parameters);
}

// turn debug output on or off
function tpSetDebug(isDebug)
{
	queue.setDebug(isDebug);
}

// log a message; it will only get logged if debug is turned on
function tpLog(message)
{
	queue.log(message);
}

// handle player transitions for Windows Media, to track when playback ends
function tpWMPStateChanged(playerState)
{
	if (playerState == 8)
	{
		WMPlayer.TCallLabel("/", "wmPlayerLabel");
	}
	else if (playerState == 10)
	{
		playTO = setTimeout("timedPlay()", 100);
	}
	else if (playerState == 3 || playerState == 6)
	{
		clearTimeout(playTO);
	}
	
}
var backupUrl;
var playTO;

function timedPlay()
{
	if (MediaPlayer.status != 3 || MediaPlayer.status != 6)
	{
		MediaPlayer.URL = backupUrl;
	}
}

function stateCode(ps)
{
	switch(ps)
	{
		case 0:
			return "undefined";
			break;
		case 1:
			return "Stopped";
			break;
		case 2:
			return "Paused";
			break;
		case 3:
			return "Playing";
			break;
		case 4:
			return "ScanForward";
			break;
		case 5:
			return "ScanReverse";
			break;
		case 6:
			return "Buffering";
			break;
		case 7:
			return "Waiting";
			break;
		case 8:
			return "MediaEnabled";
			break;
		case 9:
			return "Transitioning";
			break;
		case 10:
			return "Ready";
			break;
		case 11:
			return "Reconnecting";
			break;
		default:
			return "invalid" + ps;
	}
}

// handle setting the URL in Windows Media Player
function tpWMPPlayURL(url)
{
	backupUrl = url;
	MediaPlayer.URL = url;
}
