var DIVIDER = "~";
var REGISTERED = "registered";
var INCOMING_METHOD_NAME = "callIncomingMethod";

/* Page ID used by Flash Local Connection to make difference between the different opened pages*/
var pageId;

/* Initial time stamp used for bandwidth detection*/
var initFlashTimestamp = new Date();

/* List of registered masters ids */
var masters = new Array();

/* List of slaves waiting for its master to be registered*/
var waitingSlaves = new Array();

/* Associative array with the lists of slaves of each master (the index is the master id) */
var slaves = new Object();

/* Associative array with the lists of the messages sent by each master (the index is the master id) */
var masterMessageQueue = new Object();

/*
PUBLIC FUNCTIONS
*/

function getPageId(){
	if (pageId == undefined){
		pageId = Math.round(Math.random()*10000000);
	}
	return pageId;		
}    


function getFlashLoadingTime(){
	var finishFlashTimestamp = new Date();
	var loadTime = finishFlashTimestamp.getTime() - initFlashTimestamp.getTime();
	return loadTime;
}

function setInitialTimestamp(){
	initFlashTimestamp = new Date();
}

function registerMaster (id){
	trace("registerMaster->id: "+id);
	masters.push(id);
	
	//Initilizing its own slaves list
	slaves[id] = new Array();
	
	//Initilizing its own messages queue
	masterMessageQueue[id] = new Array();
	//Always first message will be a registered confirmation message
	pushSlaveMessage(new Array(REGISTERED, id, id), id);
	
	//Checking the list of waiting slaves looking for slaves of this master
	refreshWaitingSlaves();
	return true;
}

function registerSlave(id){	
	trace("registerSlave->slaveId: "+id);
	var masterId = getMasterId(id);
	
	if(masterId!=""){
		trace("registerSlave->addSlave->id: "+id+" masterId: "+masterId);
		addSlave(id, masterId);
	}else{		
		trace("registerSlave->addWaitingSlave->id: "+id+" masterId: "+masterId);
		addWaitingSlave(id);
	}
	return true;
}

function sendMessageTo(id, message, params, from){
	trace("sendMessageTo->id:" + id+" message: "+message+" params: "+ params+" from: "+from+" getFlashMovie: "+getFlashMovie(id));
	getFlashMovie(id)[INCOMING_METHOD_NAME](message, params, from);
	return true;
}

/*
Shortcut to sendMessageTo for Master message
*/
function sendMessageToMaster(message, params, from){
	trace("sendMassageToMaster message: "+message+" params: "+params+" from: "+from);
	var masterId = getMasterId(from);
	sendMessageTo(masterId, message, params, from);	
}

/*
Brodcast messages from the master to all of its slaves. The messages are saved
waiting for new slaves registered.
*/
function broadcastMessageSlaves(message, params, from){
	var mastersSlaves = getSlaves(from);
	trace("broadcastMessageSlaves message: "+message+" params: "+params+" from: "+from);
	
	pushSlaveMessage(new Array(message, params, from), from);
	for (i=0; i<mastersSlaves.length; i++) {
		sendMessageTo(mastersSlaves[i], message, params, from);
	}
}

/*
Returns the list of slaves for a given master id.
*/
function getSlaves(masterId){
	return slaves[masterId];
}


/*
PRIVATE FUNCTIONS
*/
function addSlave(id, masterId){
	var mastersSlaves = getSlaves(masterId);
	
	mastersSlaves.push(id);

	removeWaitingSlave(id);
	sendMessageQueueTo(id, masterId);	
}

function getMasterMessages(masterId){
	return masterMessageQueue[masterId];
}

function addWaitingSlave(id){
	if(!isWaitingSlave(id)){
		waitingSlaves.push(id);
	}
}


function isWaitingSlave(id){
	var i=0; 
	for (i=0; i<waitingSlaves.length; i++) {
		if(id == waitingSlaves[i]){
			return true;
		}
	}
	return false;
}


function pushSlaveMessage(message, masterId){
	var masterMessages = getMasterMessages(masterId)
	masterMessages.push(message);
}

function getFlashMovie(id){
	return document.getElementById(id);
}

function getMasterId(componentId){
	var masterId;
	subComponents = componentId.split(DIVIDER);
	if(subComponents.length == 1){
		if(masters.length>0){
			masterId = masters[0];
		}else{
			masterId = "";
		}
	}else if (subComponents.length == 2){
		if(isMasterReady(subComponents[1])){
			masterId = subComponents[1];
		}else{
			masterId = "";
		}
	}
	return masterId;	
}

function isMasterReady(id){
	var i=0; 
	for (i=0; i<masters.length; i++) {
		if(id == masters[i]){
			return true;
		}
	}
	return false;
}

function sendMessageQueueTo(id, masterId){
	var masterMessages = getMasterMessages(masterId);
	var i=0; 
	trace("sendMessageQueueTo->masterMessages.length: "+masterMessages.length);
	for (i=0; i<masterMessages.length; i++) {
		sendMessageTo(id, masterMessages[i][0], masterMessages[i][1], masterMessages[i][2]);
	}
}

function refreshWaitingSlaves(){
	trace("refreshWaitingSlaves->waitingSlaves.length: "+waitingSlaves.length);
	for (i=0; i<waitingSlaves.length; i++) {
		if(waitingSlaves[i]!=undefined){
			registerSlave(waitingSlaves[i]);
		}
	}
	
	for (i=0; i<waitingSlaves.length; i++) {
		if(waitingSlaves[i]==undefined){
			waitingSlaves.splice(i, 1);
			i--;
		}		
	}
}

function removeWaitingSlave(id){
	for (i=0; i<waitingSlaves.length; i++) {
		if(id == waitingSlaves[i]){
			waitingSlaves[i] = undefined;
			return;
		}
	}
}

function trace(message){
	//console.log(message);
	//document.myform.logger.value += message+"\n";	
	//alert(message);
}
