var gVersion = "3.0.0.3";

// the following line is for jslint
/*global window, CrossPost, debug, alert, getUniqueId*/


//*************************************
// stockage d'un tableau dans un champ
//*************************************
function FieldArray(field) {
	this.field = field;
}

FieldArray.escapeValue = function(val) {
	val = val.replace(/\$/g,"$dollar");
	return val.replace(/;/g,"$pointvirgule");
};

FieldArray.unescapeValue = function(val) {
	val = val.replace(/\$pointvirgule/g,";");
	return val.replace(/\$dollar/g,"$");
};

/*FieldArray.prototype.add = FieldArray.prototype.push = function (val){
	debug.out("Add in FieldArray " + this.field.name + " : " + val);
	var vals = this.field.value;
	if (vals !== "") {
		vals = vals + ";";
	}
	vals = vals + val;
	this.field.value = vals;
};

FieldArray.prototype.getFieldValue = function (valToAdd){
	return this.field.value;
};

FieldArray.prototype.getPushedFieldValue = function (val){
	var vals = this.field.value;
	vals.split(";").push(val);
	return vals.join(";");
};

FieldArray.prototype.getPoppedFieldValue = function (){
	var vals = this.field.value;
	if (vals !== "") {
		vals.split(";").pop();
		return vals.join(";");
	}
};*/

FieldArray.getJoinedFieldValue = function(array) {
	for (var i = 0; i < array.length; i++) {
		array[i] = FieldArray.escapeValue(array[i]);
	}
	return array.join(";");
};


/*FieldArray.prototype.remove = function (val) {
	debug.out("Remove from FieldArray " + this.field.name + " : " + val);
	var oldvals = this.field.value;
	if (oldvals !== "")
	{
		var newvals = "";
		var oldvalsArray = oldvals.split(";");
		for (var i = 0; i < oldvalsArray.length; i++) {
			if (oldvalsArray[i] != val) {
				if (newvals !== "") {
					newvals = newvals + ";";
				}
				newvals = newvals + oldvalsArray[i];
			}
		}
		this.field.value = newvals;
	}
};*/

FieldArray.prototype.pop = function() {
	var vals = this.field.value;
	if (vals !== "") {
		poppedVal = vals.split(";").pop();
		this.field.value = vals.join(";");
		return FieldArray.unescapeValue(poppedVal);
	}
};

FieldArray.prototype.getArray = function() {
	var vals = this.field.value;
	if (vals !== "") {
		var valArray = vals.split(";");
		for (var i = 0; i < valArray.length; i++) {
			valArray[i] = FieldArray.unescapeValue(valArray[i]);
		}
		return valArray;
	}
	else {
		return new Array();
	}
};

//-----------------------------------------
// fin stockage d'un tableau dans un champ
//-----------------------------------------


//********************
// commande cliente
//********************
function clientCommand(func, sender, retriesMax) {
	this.func = func;
	this.sender = sender;
	this.retriesMax = retriesMax;
}
clientCommand.prototype.execute = function() {
	return this.func();
};
//------------------------
// fin commande cliente
//------------------------


//********
// cibles
//********
function H_Target(hostUid) {
	this.hostUid = hostUid;
	this.sessionHostUid = getSessionHostUid(hostUid);
}
H_Target.prototype.toString = function() {
	return "H (hostUid="  + this.hostUid + ")";
};

function Nx_Target(controllerName, controllerUrl) {
	this.controllerName = controllerName;
	this.controllerUrl = controllerUrl;
}
Nx_Target.prototype.toString = function() {
	return "Nx (controllerName="  + this.controllerName + ", controllerUrl=" + this.controllerUrl + ")";
};

function NxH_Target(controllerName, controllerUrl, hostUid) {
	this.controllerName = controllerName;
	this.controllerUrl = controllerUrl;
	this.hostUid = hostUid;
	this.sessionHostUid = getSessionHostUid(hostUid);
}
NxH_Target.prototype.toString = function() {
	return "NxH (hostUid="  + this.hostUid + ", controllerName="  + this.controllerName + ", controllerUrl=" + this.controllerUrl + ")";
};

function NxNH_Target(controllerName, controllerUrl, hostUid, features, modal, title) {
	this.controllerName = controllerName;
	this.controllerUrl = controllerUrl;
	this.hostUid = hostUid;
	this.sessionHostUid = getSessionHostUid(hostUid);
	this.features = features;
	this.modal = modal;
	this.title = title;
}
NxNH_Target.prototype.toString = function() {
	return "NxNH (hostUid="  + this.hostUid + ", controllerName="  + this.controllerName + ", controllerUrl=" + this.controllerUrl + ", modal=" + this.modal + ")";
};

function caller_Target() {
}
caller_Target.getCallerInfo = function(strCaller) {
	var strCallerArray = strCaller.split("|");
	
	var unescapedControllerUrl = strCallerArray[3].replace(/\$pipe/g,"|");
	unescapedControllerUrl = unescapedControllerUrl.replace(/\$dollar/g,"$");

	if (strCallerArray[0] == "HostController") {
		debug.out("L'appelant est de type PCMVC2 : " + strCallerArray[1] + " - " + strCallerArray[2] + " - " + unescapedControllerUrl + " - " + strCallerArray[4]);
		return new CallerInfo(strCallerArray[1], strCallerArray[2], unescapedControllerUrl, strCallerArray[4] == "true");
	}
	else {
		debug.err("L'appelant est de type inconnu : " + strCallerArray[0]);
		return null;
	}
};
caller_Target.prototype.toString = function() {
	return "caller";
};

function callback_Target() {
}
callback_Target.getCallerInfo = caller_Target.getCallerInfo;
callback_Target.prototype.toString = function() {
	return "callback";
};

function callbackH_Target(hostUid) {
	this.hostUid = hostUid;
	this.sessionHostUid = getSessionHostUid(hostUid);
}
callbackH_Target.getCallerInfo = caller_Target.getCallerInfo;
callbackH_Target.prototype.toString = function() {
	return "callbackH (hostUid="  + this.hostUid + ")";
};

function callbackNH_Target(hostUid, features, modal, title) {
	this.hostUid = hostUid;
	this.sessionHostUid = getSessionHostUid(hostUid);
	this.features = features;
	this.modal = modal;
	this.title = title;
}
callbackNH_Target.getCallerInfo = caller_Target.getCallerInfo;
callbackNH_Target.prototype.toString = function() {
	return "callbackNH (hostUid="  + this.hostUid + ", modal=" + this.modal + ")";
};

function CallerInfo(sessionHostUid, controllerName, controllerUrl, modalCall) {
	if (sessionHostUid == "fwk_client") { // valeur spéciale
		this.sessionHostUid = g_sessionHostUid;
	}
	else {
		this.sessionHostUid = sessionHostUid;
	}
	this.controllerName = controllerName;
	this.controllerUrl = controllerUrl;
	this.modalCall = modalCall;
}
CallerInfo.prototype.toString = function() {
	var escapedControllerUrl = this.controllerUrl.replace(/\$/g,"$dollar");
	escapedControllerUrl = escapedControllerUrl.replace(/\|/g,"$pipe");
	return "HostController|"  + this.sessionHostUid + "|" + this.controllerName + "|" + escapedControllerUrl + "|" + this.modalCall;
};

//------------
// fin cibles
//------------



//*************************************************************
// Fonctions globales (Initilialisation d'hôte)
//*************************************************************
var g_sessionHostUid;
var g_applicationUid;
var g_controllerName;
var g_callersField;
var g_clientCommands = new Array();
var g_retries;
var g_ready;
var g_frozen;
var g_redirectFrame;
var g_title;


function initialize(applicationUid, forceHostUid, title) {
	g_applicationUid = applicationUid;
	if (forceHostUid != "") {
		window.name = getSessionHostUid(forceHostUid);
	}
	g_sessionHostUid = window.name;
	g_controllerName = window.document.getElementById("FWK_ControllerName").value;
	g_callersField = window.document.getElementById("FWK_Callers");
	g_title = title;
	g_retries = 0;
	window.attachEvent("onload", window_loaded);
	window.attachEvent("onunload", window_unloaded);
	debug.out("L'hôte " + g_sessionHostUid + " est initialisé");
	
	// met à jour le titre
	if (title != "") {
		document.title = g_title;
	}
	
	// création redirectFrame dans les fenêtres modales
	if (window.top.dialogArguments  && (hModalOpener = getModalOpenerRecursive(window.top.dialogArguments.window))) {
		if (hModalOpener.document.createElement && 
			(g_redirectFrame = hModalOpener.document.createElement('iframe'))) { 
			g_redirectFrame.id = g_sessionHostUid;
			//COR-2008-0484 blankPage au lieu de "" pour éviter le message de passage en HTTP lorsque le site est en HTTPS
			g_redirectFrame.src = "PCMVC.ashx?resType=blankPage" 
			g_redirectFrame.width = 0; 
			g_redirectFrame.height = 0; 
			hModalOpener.document.body.appendChild(g_redirectFrame); 
			g_redirectFrame.contentWindow.name=g_sessionHostUid;
			g_redirectFrame.contentWindow.g_redir = this; 
			debug.out("L'hôte " + g_sessionHostUid + " est redirigé");
		}
	}
}

function window_loaded() {
	debug.out("L'hôte " + g_sessionHostUid + " est chargé");
	g_ready = true;
	executeClientCommands();
}

function getModalOpenerRecursive(win) {
	if (win.top.dialogArguments && (hModalOpener = win.top.dialogArguments.window)) {
		return getModalOpenerRecursive(hModalOpener);
	}
	else {
		return win;
	}
}

function window_unloaded() {
	// suppression redirectFrame dans les fenêtres modales
	if (g_redirectFrame) { 
		g_redirectFrame.removeNode(true);
		debug.out("L'hôte " + g_sessionHostUid + " est non redirigé");
	}
		
	debug.out("L'hôte " + g_sessionHostUid + " est déchargé");
}

function addClientCommandsArray(clientCommands) {
	for (var i = 0; i < clientCommands.length; i++) {
		addClientCommand(clientCommands[i]);
	}
}

function addClientCommand(clientCommand) {
	g_clientCommands[g_clientCommands.length] = clientCommand;
}

function executeClientCommands() {
	for (var i = 0; i < g_clientCommands.length; i++) {
		var command = g_clientCommands[i];
		if (command === undefined) {
			continue;
		}
		debug.out("Exécution de la commande configurée " +  command.sender);
		var result = command.execute();
		if (! result) {
			g_retries ++;
			var retriesMax = command.retriesMax;
			if (g_retries > retriesMax) {
				// nombre de reprise maximum atteint pour la commande
				// les commandes suivantes ne seront pas exécutées
				// fin d'exécution des commandes
				debug.err("La commande configurée " +  command.sender + " n'a pas pu être exécutée");
				for (var j = i + 1; j < g_clientCommands.length; j++) {
					var nextCommand = g_clientCommands[j];
					debug.err("La commande configurée suivante " +  nextCommand.sender + " a été ignorée");
				}
				break;
			}
			else {
				// reporte l'exécution des commandes
				if (this.retries == 1) {
					debug.warn("La commande configurée " +  command.sender + " n'a pas été exécutée - " + retriesMax + " nouvelles tentative(s)");
				}
				window.setTimeout(function(){executeClientCommands();}, 1000);
				break;
			}		
		}
		else {
			// supprime la commande des commandes à exécuter
			debug.out("La commande configurée " +  command.sender + " a été exécutée");
			delete g_clientCommands[i];
		}
	}
}

// appel de fonction transversal
function doCrossCall(func, args, target) {
	if (target instanceof H_Target) {
		var host = getHost(target.sessionHostUid, true);
		if (!host) {
			return false;
		}
		return __DoCrossHostCall(host, func, args);
	}
	return true;
}

// appel de commande transversal
function doCrossCommand(cmd, args, target, oneway) {
	debug.out("Exécution de la commande transversale " + (oneway ? "monodirectionnelle " : "bidirectionnelle ") + cmd 
	+ "(" + args[0] + (args[1] !== undefined ? "-" + args[1] : "") + (args[2] !== undefined ? "-" + args[2] : "") + ") de cible " + target.toString(), "yellow");
	
	var targetHost;
	var callersFieldArray = new FieldArray(g_callersField);
	
	// calcul de l'appelant à transmettre
	var newCaller;
	var sentCallersArray = callersFieldArray.getArray();
	
		
	if (target instanceof caller_Target) {
		sentCallersArray.pop();
	}
	if (! oneway) {
		// bi-directionnel
		if (target instanceof NxNH_Target && target.modal) {
			newCaller = new CallerInfo(g_sessionHostUid, g_controllerName, window.location.href, true);
		}
		else {
			// y-compris caller_Target (retour de fenêtre modale n'utilise pas oneway et est forcément mono-directionnel)
			newCaller = new CallerInfo(g_sessionHostUid, g_controllerName, window.location.href, false);
		}
		sentCallersArray.push(newCaller.toString()); 
	}
	var sentCallers = FieldArray.getJoinedFieldValue(sentCallersArray);
	
	
	if (target instanceof H_Target) {
		targetHost = getHost(target.sessionHostUid, false); // valable pour les deux cibles
			
		if (!targetHost) {
			debug.warn("R1.H : La commande " + cmd + " sur l'hôte (" + target.toString() + ") ne peut aboutir car l'hôte est introuvable ou partiel");
			return false;
		}
		/*else if (host.isPartial) {
			debug.warn("R2.2 : La commande " + cmd + " sur l'hôte (" + target.toString() + ") ne peut aboutir car l'hôte est partiel");
			return false;
		}*/
		if (targetHost.frozen) {
			debug.warn("R4.H : La cible Host (" + target.toString() + ") est interdite car un appel modal est en cours");
			return false;
		}
		if (!__DoCrossPost(targetHost, sentCallers, cmd, args[0], args[1], args[2], targetHost.g_title)) {
			return false;
		}
	}
	else if (target instanceof Nx_Target || target instanceof callback_Target) {
		var controllerUrl;
		var controllerName;
		if (target instanceof callback_Target) {
			var strCaller = callersFieldArray.getArray().pop();
			if (strCaller === undefined) {
				debug.warn("Il n'y a pas d'appelant - la commande est ignorée");
				return true;
			}
			var caller = callback_Target.getCallerInfo(strCaller);
			controllerUrl = caller.controllerUrl;
			controllerName = caller.controllerName;
		}
		else {
			controllerUrl = target.controllerUrl;
			controllerName = target.controllerName;
		}
		// titre hôte courant conservé
		var title = g_title;
		if (!__CreateFormAndPost(window.document, "_self", cmd, args[0], args[1], args[2], controllerUrl, "", 
			oneway, sentCallers, controllerName, title)) {
			return false;
		}
	}
	else if (target instanceof NxH_Target || target instanceof callbackH_Target) {
		var controllerUrl;
		var controllerName;
		if (target instanceof callbackH_Target) {
			var strCaller = callersFieldArray.getArray().pop();
			if (strCaller === undefined) {
				debug.warn("Il n'y a pas d'appelant - la commande est ignorée");
				return true;
			}
			var caller = callback_Target.getCallerInfo(strCaller);
			controllerUrl = caller.controllerUrl;
			controllerName = caller.controllerName;
		}
		else {
			controllerUrl = target.controllerUrl;
			controllerName = target.controllerName;
		}
		host = getHost(target.sessionHostUid, true);
		if (!host) {
			debug.warn("R1.NxH : La commande " + cmd + " sur l'hôte (" + target.toString() + ") ne peut aboutir car l'hôte est introuvable");
			return false;
		}
		if (host.frozen) {
			debug.warn("R4.NxH : La cible (" + target.toString() + ") est interdite car un appel modal est en cours");
			return false;
		}
		// titre hôte cible conservé
		var title = host.g_title;
		var winName = target.sessionHostUid; // formulaire dynamique sur target HTML
		if (!__CreateFormAndPost(window.document, winName, cmd, args[0], args[1], args[2], controllerUrl, "", 
			oneway, sentCallers, controllerName, title)) {
			return false;
		}
	}
	else if ((target instanceof NxNH_Target || target instanceof callbackNH_Target) && !target.modal) {
		var controllerUrl;
		var controllerName;
		if (target instanceof callbackNH_Target) {
			var strCaller = callersFieldArray.getArray().pop();
			if (strCaller === undefined) {
				debug.warn("Il n'y a pas d'appelant - la commande est ignorée");
				return true;
			}
			var caller = callback_Target.getCallerInfo(strCaller);
			controllerUrl = caller.controllerUrl;
			controllerName = caller.controllerName;
		}
		else {
			controllerUrl = target.controllerUrl;
			controllerName = target.controllerName;
		}
		// nouveau titre
		var title = target.title;
		
		var winName = target.sessionHostUid;
		//COR-2008-0484 blankPage au lieu de "" pour éviter le message de passage en HTTP lorsque le site est en HTTPS
		//COR-2008-0536 pb d'ouverture de fenêtre non modales à partir de fenêtres modales dans le cas de plusieurs IE ouverts (cf. KB831678)
		var openerWin;
		if (window.top.dialogArguments)
			openerWin = getModalOpenerRecursive(window.top.dialogArguments.window);
		else
			openerWin = window;
		var hWin = openerWin.open("PCMVC.ashx?resType=blankPage", winName, target.features);
		//COR-2009-0410 Erreur Javascript sur ouverture pdf
		//cf. http://groups.google.com/group/microsoft.public.inetexplorer.scripting/browse_frm/thread/d480a5c5fa5fe086/72afd65479128a7e?lnk=st&q=%2B"Member+not+found",+%2B"window.open"&rnum=1#72afd65479128a7e 
        try {
            hWin.focus();
        }
        catch(err) {
            if (err.number == -2147352573) { //membre introuvable (80020003)
                // cas de la récupération d'une fenêtre contenant un document non HTML 
	            hWin.close();
	            hWin = openerWin.open("PCMVC.ashx?resType=blankPage", winName, target.features);
            }
            else
	            throw err;
	    }
		//hWin.focus();
		if (!__CreateFormAndPost(window.document, winName, cmd, args[0], args[1], args[2], controllerUrl, "", 
			oneway, sentCallers, controllerName, title)) {
			return false;
		}
	}
	else if ((target instanceof NxNH_Target || target instanceof callbackNH_Target) && target.modal) {
		var controllerUrl;
		var controllerName;
		if (target instanceof callbackNH_Target) {
			var strCaller = callersFieldArray.getArray().pop();
			if (strCaller === undefined) {
				debug.warn("Il n'y a pas d'appelant - la commande est ignorée");
				return true;
			}
			var caller = callback_Target.getCallerInfo(strCaller);
			controllerUrl = caller.controllerUrl;
			controllerName = caller.controllerName;
		}
		else {
			controllerUrl = target.controllerUrl;
			controllerName = target.controllerName;
		}
		var params = new Object();
		params.window = window.self;
		params.args = args;
		this.frozen = true;
		var retVal = window.showModalDialog("PCMVC.ashx?resType=dynamicPage&hostUid=" + encodeURIComponent(target.hostUid)
						+ "&targetUrl=" + encodeURIComponent(controllerUrl) + "&controllerName=" + encodeURIComponent(controllerName)
						+ "&cmd=" + cmd + "&oneway=" + oneway + "&callers=" + encodeURIComponent(sentCallers) + "&title=" + encodeURIComponent(target.title), params, target.features);
		this.frozen = false;
		if (retVal!== undefined) {
			if (!__DoMVCPost(retVal.cmd, retVal.arg1, retVal.arg2, retVal.arg3)) {
				return false;
			}
		}
	}
	else if (target instanceof caller_Target) {
		var strCaller = callersFieldArray.getArray().pop();
		if (strCaller === undefined) {
			debug.warn("Il n'y a pas d'appelant - la commande est ignorée");
			return true;
		}
		var caller = caller_Target.getCallerInfo(strCaller);
		
		if (caller.modalCall) {
			calledHost = getHost(caller.sessionHostUid, false);
			if (!calledHost) {
				debug.warn("R1.Caller : La commande " + cmd + " sur l'hôte (" + target.toString() + ") ne peut aboutir car l'hôte est introuvable");
				return false;
			}
			if (this.dialogArguments == undefined || this.dialogArguments.window != calledHost) {
				debug.warn("R5.Caller : La cible caller (" + target.toString() + ") n'est autorisée que depuis la même fenêtre que l'hôte cible de l'appel modal en cours");
				return false;
			}
			var retValue = new Object();
			retValue.cmd=cmd;
			retValue.arg1=args[0];
			retValue.arg2=args[1];
			retValue.arg3=args[2];
			window.top.returnValue = retValue;
			window.top.close();
		}
		else { // appelant en appel non modal
			// l'hôte courant est-il l'hôte appelant
			if (g_sessionHostUid == caller.sessionHostUid) {
				// on est déjà dans l'hôte appelant
				// le contrôleur courant est-il le contrôleur appelant
				if (g_controllerName == caller.controllerName) {
					// même hôte, même contrôleur donc commande locale
					if (!__DoCrossPost(this, sentCallers, cmd, args[0], args[1], args[2], g_title)) {
						return false;
					}
				}
				else {
					// même hôte, contrôleur différent donc changement de contrôleur (Nx)
					if (!__CreateFormAndPost(window.document, "_self", cmd, args[0], args[1], args[2], caller.controllerUrl, "", 
						oneway, sentCallers, caller.controllerName, g_title)) {
						return false;
					}
				}
			}
			else {
				// on est hors de l'hôte appelant
				host = getHost(caller.sessionHostUid, false);
				if (!host) {
					debug.warn("R1.Caller : La commande " + cmd + " sur l'hôte (" + target.toString() + ") ne peut aboutir car l'hôte est introuvable");
					return false;
				}
				if (host.frozen) {
					debug.warn("R4.Caller : La cible caller (" + target.toString() + ") est interdite car un appel modal est en cours");
					return false;
				}
				// le contrôleur de l'hôte appelant est-il le contrôleur appelant
				if (host.g_controllerName == caller.controllerName) {
					// hôte différent, même contrôleur donc crossPost (H)
					if (!__DoCrossPost(host, sentCallers, cmd, args[0], args[1], args[2], host.g_title)) {
						return false;
					}
				}
				else {
					// hôte différent, contrôleur différent donc changement de contrôleur dans hôte (NxH)
					var winName = caller.sessionHostUid; // formulaire dynamique sur target HTML
					if (!__CreateFormAndPost(window.document, winName, cmd, args[0], args[1], args[2], caller.controllerUrl, "", 
						oneway, sentCallers, caller.controllerName, host.g_title)) {
						return false;
					}
				}
			}
		}
		// pas d'action
	}
	
	debug.out("La commande transversale " + (oneway ? "monodirectionnelle " : "bidrectionnelle ") + cmd 
	+ "(" + args[0] + (args[1] !== undefined ? "-" + args[1] : "") + (args[2] !== undefined ? "-" + args[2] : "") + ") de cible " + target.toString() 
	+ " a été exécutée");
	return true;
};

function getHost(sessionHostUid, allowPartial) {
	debug.out("Recherche de l'hôte " + sessionHostUid);
	//COR-2008-0484 NB : si l'hôte n'est pas trouvé le message de passage en HTTP apparaîtra lorsque le site est en HTTPS
	var hWin = window.open("", sessionHostUid);
	if (hWin.g_redir) {
	debug.out("Recherche de l'hôte redirigé " + sessionHostUid);
		//COR-2008-0484 NB : normalement le handle n'est jamais vide donc pas de message de passage en HTTP lorsque le site est en HTTPS
		hWin = hWin.g_redir.open("", sessionHostUid);
	}
	if (hWin.g_sessionHostUid === undefined) {
		if (hWin.parent != hWin) {// hôte partiel
			if (allowPartial) {
				return hWin;
			}
			else {
				debug.warn("L'hôte " + sessionHostUid + " est partiel");
				return null;
			}
		}
		else {
			debug.warn("L'hôte " + sessionHostUid + " est introuvable");
			hWin.document.write("<B>PCMVC DesignError : </B> l'hôte " + sessionHostUid + " est introuvable.<BR>");
			return null;
		}
	}
	else {
		return hWin;
	}
}

function getSessionHostUid(hostUid) {
	return "w_" + g_applicationUid + "_" + hostUid;
}


//-----------------------------------------------------------------
// fin Fonctions globales (Initilialisation d'hôte et de conteneur)
//-----------------------------------------------------------------


//*******************************************
// Fonctions globales de bas niveau (Interne)
//*******************************************

function __DoMVCPost(cmd, arg1, arg2, arg3)
{
	debug.out("Exécution de la commande " + cmd 
	+ "(" + arg1 + (arg2 !== undefined ? "-" + arg2 : "") + (arg3 !== undefined ? "-" + arg3 : "") + ")" , "yellow");
	if (!g_ready) { //la page n'est pas chargée
		debug.warn("La commande " + cmd 
		+ "(" + arg1 + (arg2 !== undefined ? "-" + arg2 : "") + (arg3 !== undefined ? "-" + arg3 : "") + ") ne peut être exécutée actuellement (DMP)");
		return false;
	}
	window.document.getElementById("FWK_cross_cmd").value = cmd;
	window.document.getElementById("FWK_cross_arg1").value= arg1;
	window.document.getElementById("FWK_cross_arg2").value= arg2;
	window.document.getElementById("FWK_cross_arg3").value= arg3;
	CrossPost();
	return true;
}

function __DoCrossPost(host, callers, cmd, arg1, arg2, arg3, title)
{
	if (!host.g_ready) { //la page n'est pas chargée
		debug.warn("La commande " + cmd 
		+ "(" + arg1 + (arg2 !== undefined ? "-" + arg2 : "") + (arg3 !== undefined ? "-" + arg3 : "") + ") ne peut être exécutée actuellement (DCP)");
		return false;
	}
	host.document.getElementById("FWK_callers").value = callers;
	host.document.getElementById("FWK_cross_cmd").value = cmd;
	host.document.getElementById("FWK_cross_arg1").value= arg1;
	host.document.getElementById("FWK_cross_arg2").value= arg2;
	host.document.getElementById("FWK_cross_arg3").value= arg3;
	host.document.getElementById("FWK_title").value = title;
	host.CrossPost();
	return true;
}

function __CreateFormAndPost(doc, window_target, cmd, arg1, arg2, arg3,
	 target_url, target_hostUid,
	 oneWay, callers, controllerName, title)
{
	if (!g_ready) { // body pas encore chargé
		debug.warn("La commande " + cmd 
		+ "(" + arg1 + (arg2 !== undefined ? "-" + arg2 : "") + (arg3 !== undefined ? "-" + arg3 : "") + ") ne peut être exécutée actuellement (CFP)");
		return false;
	}
	var oForm = doc.createElement("FORM");
	oForm.setAttribute("action", target_url);
	oForm.setAttribute("target", window_target);
	oForm.setAttribute("method", "POST");
	oForm.setAttribute("id", "crossForm");
	
	var strHtml = '<INPUT TYPE="hidden" NAME="FWK_cmd" VALUE="' + cmd + '"/>';
	strHtml += '<INPUT TYPE="hidden" NAME="FWK_arg1" VALUE="' + arg1 + '"/>';
	strHtml += '<INPUT TYPE="hidden" NAME="FWK_arg2" VALUE="' + arg2 + '"/>';
	strHtml += '<INPUT TYPE="hidden" NAME="FWK_arg3" VALUE="' + arg3 + '"/>';
	strHtml += '<INPUT TYPE="hidden" NAME="FWK_callers" VALUE="' + callers + '"/>';
	strHtml += '<INPUT TYPE="hidden" NAME="FWK_hostUid" VALUE="' + target_hostUid + '"/>';
	strHtml += '<INPUT TYPE="hidden" NAME="FWK_title" VALUE="' + title + '"/>';
	strHtml += '<INPUT TYPE="hidden" NAME="FWK_controllerName" VALUE="' + controllerName + '"/>';
	
	oForm.innerHTML = strHtml;
	
	appendedForm = doc.body.appendChild(oForm);
	appendedForm.submit();
	if (window_target != "_self") {
		doc.body.removeChild(appendedForm); // suppression du formulaire temporaire
	}
	return true;
}

// Invocation fonctions (Interne)
function __DoCrossHostCall(win, func, args) {
	if (!win.g_ready) { //la page n'est pas chargée
		debug.warn("La fonction " + func 
		+ ") ne peut être exécutée actuellement");
		return false;
	}
	win[func](args);
	return true;
}

//-----------------------------------------------
// fin Fonctions globales de bas niveau (Interne)
//-----------------------------------------------


//*************************************
// Invocation commandes (API end-user)
//*************************************
function DoAction(actionName, actionParams)
{
	__DoMVCPost("DoAction", actionName, actionParams, "");
}
function ShowPresentation(presentationName, presentationParams)
{
	__DoMVCPost("ShowPresentation", presentationName, presentationParams, "");
}
function DoCrossAction(hostUid, oneWay, actionName, actionParams, crossData)
{
	var target = new H_Target(hostUid);
	doCrossCommand("DoAction", [actionName, actionParams, crossData], target, oneWay);
}
function ShowCrossPresentation(hostUid, oneWay, presentationName, presentationParams)
{
	var target = new H_Target(hostUid);
	doCrossCommand("ShowPresentation", [presentationName, presentationParams], target, oneWay);
}

// sérialisation CrossData
function SerializeCrossData(crossDataDico)
{
	var crossData = "";
	if (typeof(crossDataDico) == "string") {
		crossData = crossDataDico;
	}
	else if (crossDataDico !== undefined)
	{
		var crossDataKey;
		for (crossDataKey in crossDataDico)
		{
			if (crossData !== "") {
				crossData = crossData + "@";
			}
			crossData = crossData + EncodeCrossData(crossDataKey) + "#" + EncodeCrossData(crossDataDico[crossDataKey]);
		}
	}
	return crossData;
}
function EncodeCrossData(s)
{
	var str = new String(s);
	str = str.replace(/\$/g,"$dollar"); // échappe $
	str = str.replace(/@/g,"$arobase"); // échappe @
	str = str.replace(/#/g,"$diese"); // échappe #
	return str.toString();
}

//----------------------------------------
// fin Invocation commandes (API end-user)
//----------------------------------------

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   