/**
 * @class Constructor of the Environment object<br>
 * This one is used to manage windows<br>
 *
 * @return window manager
 * @constructor
 * @author Laurent Vergnaud
 */
function GraphicalEnvironment() {

	/**
	 * Windows ({@link GraphicalWindow} collection) opened on the current document
	 * @type Hashtable
	 */
	this.graphicalWindows = new Hashtable();

	/**
	 * Top level GraphicalWindow
	 * @type GraphicalWindow
	 */
	this.lastGraphicalWindow = null;

	/**
	 * Actual zindex for next GraphicalWindow (used to put the next opened GraphicalWindow above the top level GraphicalWindow)
	 * @type Int
	 */
	this.zindex = 2000;

	/**
	 * Add a window in the environment
	 *
	 * @param {GraphicalWindow} graphicalWindow This is a GraphicalWindow yet created
	 * @param {String} divName Name of the GraphicalWindow
	 * @return {String} Id of the added GraphicalWindow
	 */
	this.addGraphicalWindow = function(graphicalWindow) {
		if (this.graphicalWindows.containsKey(graphicalWindow.id)) {
			return false;
		}
		// Show mask
		setAllComboboxVisible(false);
		$("mask").fade('hide');
		document.getElementById("mask").style.display = 'block';
		document.getElementById("mask").style.height = Window.getScrollSize().y + "px";
		document.getElementById("mask").style.zIndex = this.zindex;
		$("mask").fade(0.6);
		this.zindex = this.zindex + 1;
		// Add the window
		this.graphicalWindows.put(graphicalWindow.id,graphicalWindow);
		graphicalWindow.zindex = this.zindex;
		this.zindex = this.zindex + 1;
		graphicalWindow.build();
		var divInner= document.createElement("DIV");
		graphicalWindow.HTMLObject = divInner;
		divInner.innerHTML = graphicalWindow.innerHTML;
		document.getElementById("graphicalEnvironment").appendChild(divInner);
		$(graphicalWindow.id).fade('hide');
		graphicalWindow.refresh();
		$(graphicalWindow.id).fade('in');
		this.lastGraphicalWindow = graphicalWindow.id;
		return graphicalWindow.id;
	}



	/**
	 * Show a dialog window
	 *
	 * @param {String} title Title of the dialog
	 * @param {String} content Content of the dialog
	 * @param {String[]} buttonNames Button names of the dialog
	 * @param {String[]} buttonActions Button actions of the dialog
	 * @param {Int} width Width of the dialog
	 * @param {Int} height Height of the dialog
	 * @param {String} divName Name of the dialog (optional)
	 * @return {String} Id of the added dialog
	 */
	this.showDialog = function(title,content,buttonNames,buttonActions,width,height,divName) {
		if (!(divName))
			divName = "Dialog" + this.graphicalWindows.size();
		var varHTML = "<div class='graphicalWindowContent'>";
		varHTML += content;
		varHTML += "</div>";
		if (!((buttonNames) && (buttonNames != null) && (buttonNames.length == 1) && (buttonNames[0] == "none"))) {
			varHTML += "<div class='submit'>";
			if ((buttonNames) && (buttonNames != null) && (buttonNames.length > 0)) {
				for (var cptDialog = 0 ; cptDialog < buttonNames.length ; cptDialog++) {
					varHTML += "&nbsp;<input type='button' onclick='" + (buttonActions[cptDialog]) + "' value='" + (buttonNames[cptDialog]).toUpperCase() + "' />";
				}
			}
			else
				varHTML += "&nbsp;<input type='button' onclick='graphicalEnvironment.closeTopLevelGraphicalWindow();' value='OK' />";
			varHTML += "</div>";
		}
		var id = this.addGraphicalWindow(new GraphicalWindow(title,varHTML,(width)?width:500,(height)?height:200,divName));
		return id;
	}



	/**
	 * Show a confirmation message
	 *
	 * @param {String} message Message of confirmation message
	 * @param {String} code Return code to listener if confirmation is accepted
	 * @param {String} divName Name of the caller of confirmation message (equals to "" if caller is a main frame)
	 * @param {String} codeNo Return code to listener if confirmation is refused (optional)
	 */
	this.showConfirmationMessage = function(message,code,divName,codeNo) {
		var buttons = ["Oui","Non"];
		var actions = ["" + ((divName != "")?"document.Frame_" + divName + ".":"") + "confirmation_message_listener(\"" + code + "\");",(codeNo)?("" + ((divName != "")?"document.Frame_" + divName + ".":"") + "confirmation_message_listener(\"" + codeNo + "\");"):"graphicalEnvironment.closeTopLevelGraphicalWindow();"];
		this.showDialog("ATTENTION", "<table width=100% height=100%><tr><td class='messageText'>" + message + "</td></tr></table>", buttons, actions, 400, 250, "FConfMess_" + divName);
	}



	/**
	 * Show an error message
	 *
	 * @param {String} message Error message to show
	 */
	this.showErrorMessage = function(message) {
		this.showDialog("ERREUR", "<table width=100% height=100%><tr><td class='messageText'>" + message + "</td></tr></table>");
	}



	/**
	 * Show a simple message
	 *
	 * @param {String} message Message to show
	 */
	this.showMessage = function(title, message) {
		this.showDialog((title)?title:"INFORMATIONS", "<table width=100% height=100%><tr><td class='messageText'>" + message + "</td></tr></table>");
	}
	
	/**
	 * Show wait message
	 *
	 * @param {String} message Message to show
	 */
	this.showWaitMessage = function() {
		var varHTML = "<div class='graphicalWindowContent'>";
		varHTML += "<table width=100% height=100%><tr><td style='padding: 30px;'><img src='images/interface/loading.gif' /></td><td class='messageText'>Veuillez patienter...</td></tr></table>";
		varHTML += "</div>";
		this.addGraphicalWindow(new GraphicalWindow("",varHTML,300,180,"WAIT_FORM",true));
	}
	
	/**
	 * Show a simple assistant (assistant based on a HTML form)
	 *
	 * @param {String} title Title of the assistant
	 * @param {String} url Url of the assistant
	 * @param {String} code Return code to listener (NOT USED here)
	 * @param {String} divName Name of the assistant
	 * @param {Int} width Width of the assistant
	 * @param {Int} height Height of the assistant
	 */
	this.showSimpleUrl = function(title, url, width, height) {
		var innerHTML = getIFrame(url, "IFrame1");
		this.showDialog(title, innerHTML, ["none"], [], (width)?width:500, (height)?height:350, "IFrame1");
	}


	/**
	 * Remove a graphicalWindow
	 *
	 * @param {String} id Name of the graphicalWindow
	 */
	this.removeGraphicalWindow = function(id) {
		window.parent.eval("window.parent.graphicalEnvironment.removeGraphicalWindowWithTimeOut('" + id + "');",1);
	}



	/**
	 * PRIVATE - DO NOT USE THIS FUNCTION
	 * This one is automatically called by removeGraphicalWindow to avoid a IE bug, forces the parent window to do the action
	 *
	 * @param {String} id Name of the graphicalWindow
	 */
	this.removeGraphicalWindowWithTimeOut = function(id) {
		// Remove IE bug by forcing the focus on the main page
		tmpInput = window.parent.document.getElementById("inputForNoBugRemoveForm");
		tmpInput.style.display = "inline";
		tmpInput.focus();
		tmpInput.style.display = "none";
		if ($(id)) {
			$(id).fade('out');
			document.getElementById("graphicalEnvironment").removeChild(this.graphicalWindows.get(id).HTMLObject);
			this.zindex = this.zindex - 1;
			this.graphicalWindows.remove(id);
			setAllComboboxVisible(true);
			$("mask").fade('out');
			window.setTimeout("document.getElementById('mask').style.display = 'none'",1000);
			this.zindex = 2000;
		}
	}



	/**
	 * Close top level GraphicalWindow
	 */
	this.closeTopLevelGraphicalWindow = function() {
		if (!this.graphicalWindows.isEmpty())
			this.removeGraphicalWindow(this.lastGraphicalWindow);
	}

	/**
	 * Change top level GraphicalWindow title
	 */
	this.changeTitleTopLevelGraphicalWindow = function(title) {
		if (!this.graphicalWindows.isEmpty())
			this.graphicalWindows.get(this.lastGraphicalWindow).setTitle(title);
	}

	/**
	 * Change top level GraphicalWindow size
	 */
	this.changeSizeTopLevelGraphicalWindow = function(width, height) {
		if (!this.graphicalWindows.isEmpty())
			this.graphicalWindows.get(this.lastGraphicalWindow).setSize(width, height);
	}
}



/**
 * This allows escape windows by clicking on ESC key
 */
document.onkeydown = function(event) {
    var key = (event)?event.keyCode:window.event.keyCode;
    if (key == 27) {
    	window.parent.graphicalEnvironment.closeTopLevelGraphicalWindow();
    }
}

/**
 * Get new IFrame HTML code
 *
 * @param {String} url Url for the iframe content
 * @param {String} divName Name of the iframe
 * @return {String} HTML code for the iframe
 */
function getIFrame(url, divName) {
	return "<iframe  src='" + url + "' name='" + divName + "' style='width:100%;height:100%' scrolling='no' frameborder='no'></iframe>";
}