/*
 * @file : utils.js 
 * /!\ use jQuery
 * @author 2008-10-15: Jérôme CHAUVIN for A&A Partners / WebMuseo
 * aim: several use-(full? less?) functions. ;)
 * Library of several functions used for graphical effects or others things, mainly with jQuery framework but not only.
 * Thus, it initializes jQuery in order to allowing it to work with other Ajax frameworks.
 */

// /!\ : important !
//------------------
// (good) initialization of jQuery framework:
var $j;
function jQueryInit() {
	// to avoid conflicts with other libraries / frameworks:
	$j = jQuery.noConflict();
	// to avoid encoding problems when sending / receiving informations in Ajax
	$j.ajaxSetup({ contentType: "application/x-www-form-urlencoded; charset=utf-8" });
	
	//$j.ajaxSetup({ contentType: "application/x-www-form-urlencoded; charset=utf-8", async: false });
}

jQueryInit(); // initialization.

/* --- other functions: --- */



// To avoid suggestions from the Form History of the web browser:
function clearBrowserTextInputHistory() {
	$j(document).ready(function(){
	    var inputs = document.getElementsByTagName('input');
	    for(var i = 0; i < inputs.length; i++) {
	         if(inputs[i].type == 'text') {
	              inputs[i].setAttribute('autocomplete', 'off');
	         };
	    };
	});
}


function isIE() {
	var navigatorName = navigator.appName;

	return (navigatorName == 'Microsoft Internet Explorer') ? 1 : 0;
}

function showOrHide(objectID, speed) {
	var isHiddenOrUnvisible = false;
	var myObject = $j(objectID);
	
	if(objectID.indexOf("#") == -1)
		myObject = $j("#"+objectID);
	
	if(myObject.is(":hidden") && !myObject.is(":visible")) {
		myObject.fadeIn(speed != undefined ? speed : 'slow');
		isHiddenOrUnvisible = false;
	} else {
		myObject.fadeOut(speed != undefined ? speed : 'slow');
		isHiddenOrUnvisible = true;
	}
	
	return isHiddenOrUnvisible;
}


function showThenHide(objectID, intervalInSecBeforeEnd, howMuchTime) {
	var iFrameWide = $j("#iFrameTag");
	var iFrameWideDisplayValue = $j(iFrameWide).css("display");
	
	// If not defined, the Boolean function generate a "false" value so we're
	// not in a iframe for modification (cf. recordModify.jsp)
	// and we can show the element using jQuery Timer plugin (and then, jQuery
	// ThickBox plugin).
	// By default, the #disallowTagForShowThenHide DOM element in HTML code as a
	// CSS display value set to "none"
	// (see file.js in "writeIframeDoc" function).
	if ( Boolean(iFrameWideDisplayValue) == false ) {
		var myObject = $j(objectID);
	
		if(objectID.indexOf("#") == -1)
			myObject = $j("#"+objectID);
		
	    $j(myObject).fadeIn("fast", function(){ 
	        $j(this).css("visibility", "visible");
	        // below: "$.timer" is from "dev.jquery.timer.js", a jQuery plugin
	        $j.timer({	name: objectID + "_timer", 
	        			interval: intervalInSecBeforeEnd, 
	        			end: howMuchTime
	        		},
	                function() {
	        			$j(myObject).fadeOut("fast", function(){ 
	        				$j(this).css("visibility", "visible");
	        			});
	            	});
	    });
	}
}


function hideOrShowFileWidgetActionsIcons(objectID, action) {
	var iFrameWide = $j("#iFrameTag");
	var iFrameWideDisplayValue = $j(iFrameWide).css("display");
	
	if(objectID.indexOf("#") == -1)
		myObject = $j("#"+objectID);
	
	// If not defined, the Boolean function generate a "false" value so we're
	// not in a iFrame for modification (cf. recordModify.jsp)
	// and we can show the element using jQuery Timer plugin (and then, jQuery
	// ThickBox plugin).
	// By default, the #disallowTagForShowThenHide DOM element in HTML code as a
	// CSS display value set to "none"
	// (see file.js in "writeIframeDoc" function).
	if ( Boolean(iFrameWideDisplayValue) != false ) {
		// in the iFrame
		if (Boolean(action) != false && action == 'show') {
			$j(document).ready(function(){
				$j(myObject).css("visibility", "visible");
			});
		} else {
			$j(document).ready(function(){
				$j(myObject).css("visibility", "hidden");
			});
		}
	} else {
		// not in the iFrame
		
		if (Boolean(action) != false && action == 'hide') {
			$j(document).ready(function(){
				$j(myObject).css("visibility", "hidden");
			});
		} else {
			$j(document).ready(function(){
				$j(myObject).css("visibility", "visible");
			});
		}
	}
}

function reInitThickBox() {
	// on page load call tb_init
	$j(document).ready(function(){
		// Only for Firebug, a FireFox plugin:
		tb_remove(); // a little cleaning
		
		// re-initialization:
		tb_init('a.thickbox, area.thickbox, input.thickbox');// pass where to
																// apply
																// thickbox
		imgLoader = new Image();// preload image
		imgLoader.src = tb_pathToImage;
	});	
}


function initTreeView(whichOne) {
	var isCollapsed = (whichOne.indexOf("root") != -1 ? false : true);
	
	$j(whichOne).treeview({
		animated: "fast"
		, collapsed: isCollapsed
		, unique: true
		// , persist: "cookie"
		// , toggle: function() {
		// window.console && console.log("%o was toggled", this);
		// }
	});
}


/**
 * Initialization of an interface with tabs.with a call-back function when a
 * content tab is showed:
 * 
 * @author Jerome Chauvin
 * @param whichOne:
 *            specifies the DOM element's id which need such an interface.
 * @param selectedTab:
 *            specify the tab number (starts by 0) to open on the
 *            initialization.
 * @param tab_show_function:
 *            the function to call when a tab is showed (can be unspecified)
 */
function initTabsUI(whichOne, selectedTab, tab_show_function) {
	$j(whichOne).tabs({
		selected: selectedTab ? selectedTab : ''
		, show: tab_show_function ? tab_show_function : ''
		, fx: { opacity: 'toggle' }
		// , fx: {fxShow: { height: 'show', opacity: 'show' }}
	});
}

// return a radio button value from its name
function getRadioButtonValue(name) {
  var array = document.getElementsByName(name);
  for (var i=0; i < array.length; ++i) {
    var element = array[i];
    if (element.checked) {
      return element.value;
    }
  }
  return null;
}

function correctUnwantedTags(str) {
	if (str.length > 0) {
		if (str.indexOf(">") != -1)
			str = str.replace(">", "&gt;");
		if (str.indexOf("<") != -1)
			str = str.replace("<", "&lt;");
		
		return str;
	} else
		return "";
}

function correctLink(link) {
	websiteUrl = link.getAttribute('href');
	
	var hostname = window.location.hostname;
	
	var correctedUrl = "http://" + hostname + websiteUrl;

	link.setAttribute('href', correctedUrl);
}

function addToBookmarks(link) {
	websiteName = link.getAttribute('title');
	websiteUrl = link.getAttribute('href');
	
	if(window.sidebar) window.sidebar.addPanel(websiteName, websiteUrl, ""); // Mozilla,
																				// FireFox,...
	else if (window.external) window.external.AddFavorite(websiteUrl, websiteName); // Internet
																					// explorer
																					// Windows
	else if (document.all && (navigator.userAgent.indexOf('Win') < 0)) alert ("Utilisez POMME + D \n pour ajouter " + websiteName + " dans vos favoris !"); // Internet
																																							// explorer
																																							// MAC
	else if (window.opera && window.print) alert ("Utilisez CTRL + T \n pour ajouter " + websiteName + " dans vos favoris !"); // Opera
	else alert ("Cette fonction n'est pas disponible pour votre navigateur.");
}

/* --- some managing cookies functions: --- */
function writeCookie(name, value) {
	var argv=writeCookie.arguments;
	
// var listArgs = "";
// for (var i= 0; i < writeCookie.arguments.length; i++) {
// listArgs += "cookie args["+i+"] : "+writeCookie.arguments[i] + " | ";
// }
// console.log("cookie name : "+name+" and value : "+value+ " and listArgs :
// "+listArgs);
	
	var argc=writeCookie.arguments.length;
	var expires = (argc > 2) ? argv[2] : null;
	var path = (argc > 3) ? argv[3] : null;
	var domain = (argc > 4) ? argv[4] : null;
	var secure = (argc > 5) ? argv[5] : false;
	document.cookie = name + "=" + escape(value)+
	((expires == null) ? "" : ("; expires="+expires.toGMTString()))+
	((path == null) ? "" : ("; path="+path))+
	((domain == null) ? "" : ("; domain="+domain))+
	((secure == true) ? "; secure" : "");
}

function getCookieVal(offset) {
	var endstr=document.cookie.indexOf (";", offset);
	if (endstr==-1) endstr=document.cookie.length;
	return unescape(document.cookie.substring(offset, endstr));
}

function readCookie(name) {
	var arg=name+"=";
	var alen=arg.length;
	var clen=document.cookie.length;
	var i=0;
	while (i<clen) {
		var j=i+alen;
		if (document.cookie.substring(i, j)==arg)
			return getCookieVal(j);
		
		i=document.cookie.indexOf(" ",i)+1;
		
		if (i==0)
			break;
	}
	return null;
}

function deleteCookie(name) {
	date=new Date;
	date.setFullYear(date.getFullYear()-1);
	writeCookie(name, null, date);
}
/* --- end of some managing cookies functions: --- */

// Old name:
// function savePopUpSizeInACookieAndCenterIt(popupShortName, forceCentering) {
function savePopUpSizeInACookie(popupShortName) {
	// console.log("popupShortName : "+popupShortName);
	// works too:
	// var popupShortName = $j(this).attr("name");
	// var popupShortName = name;
	
	// GetPageSize for this pop-up ...
	var arrayPageSize = getPageSize();
	var daGoodWidth = arrayPageSize[2];
	var daGoodHeight = arrayPageSize[3];
	// console.log("popupShortName's h : "+arrayPageSize[2]+" and w :
	// "+arrayPageSize[3])
	// ... and put it in a cookie:
	// We delete old values:
	deleteCookie(new String("wSize_for_" + popupShortName));
	deleteCookie(new String("hSize_for_" + popupShortName));
	var date = new Date();
	date.setFullYear(date.getFullYear()+1);
	// and add the new ones:
	writeCookie(new String("wSize_for_" + popupShortName), new String(daGoodWidth), date, "/");
	writeCookie(new String("hSize_for_" + popupShortName), new String(daGoodHeight), date, "/");
	
	// -----------------------------------------------
	// Not really smooth visually (especially for IE):
	// Re-Centering is now disabled.
	// -----------------------------------------------
	/*
	 * //New values for the pop-up size, so it has to be screen centered based
	 * on its new size: if ( !$j.browser.msie ) { $j(document).ready(function(){
	 * //console.log("dans savePopUpSizeInACookieAndCenterIt et centrage du
	 * popup"); window.moveTo(screen.width/2 - daGoodWidth/2, screen.height/2 -
	 * daGoodHeight/2); });
	 * 
	 * if ( (forceCentering != undefined && forceCentering))
	 * window.moveTo(screen.width/2 - daGoodWidth/2, screen.height/2 -
	 * daGoodHeight/2); }
	 */
	/*
	 * //if ($j.browser.msie) { $j(document).ready(function(){ if (
	 * (forceCentering != undefined && forceCentering))
	 * window.moveTo(screen.width/2 - daGoodWidth/2, screen.height/2 -
	 * daGoodHeight/2);
	 * 
	 * Popup.recenter(); }); //}
	 */
}

//
// getPageSize()
// Returns array with page width, height and window width, height
// Core code from - quirksmode.org
// Edit for Firefox by pHaez
//
function getPageSize(){
	
	var xScroll, yScroll;
	
	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = document.body.scrollWidth;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all
																			// but
																			// Explorer
																			// Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla
				// and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var windowWidth, windowHeight;
	if (self.innerHeight) {	// all except Explorer
		windowWidth = self.innerWidth;
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer
																					// 6
																					// Strict
																					// Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}	
	
	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}

	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){	
		pageWidth = windowWidth;
	} else {
		pageWidth = xScroll;
	}


	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
	return arrayPageSize;
}


// ( /!\ : no more used) - for Notice page and webbrowser windows size
// modification while using jQuery Thickbox plugin
function checkTB() {
  // alert('Browser window size has been changed!');
	
  if ( Boolean(bDoNotResizing) && Boolean($j("#TB_window").css("display")) && !$j.browser.msie) {
	// alert("Thickbox is used and has to be re-initialized!");
	
	// ... no.
    // tb_remove();
    // $j("#mainLink").click();
    
    $j("#TB_window").css({display:"none"}); 
    $j("#TB_ImageOff").remove();
    $j("#TB_caption").remove();
    $j("#TB_closeWindow").remove();
    
    $j(document).ready(function(){
    	// alert("CUR_IM_INDEX : "+CUR_IM_INDEX);
        // $j("#thumbnail_"+CUR_IM_INDEX+"_input").click();
        $j("#mainLink").click();
        // $j("#TB_window").css({display:"block"});
    });

  } else if ( Boolean(bDoNotResizing) && Boolean($j("#TB_window").css("display")) == false ) {
    // alert("Thickbox is not in use!");
  }
  
}

/*
 * @author: Jérôme CHAUVIN creation date: 2009-10-06
 * 
 */
function setDisplayTypeIfAnotherObjectValueIsNotEmpty(objectWhichValHasToBeChecked, objectToDisplay, typeOfDisplay) {
	if ($j(objectWhichValHasToBeChecked).val() != '')
		$j(objectToDisplay).css("display", typeOfDisplay);
	else
		$j(objectToDisplay).css("display", "none");
}


/*
 * @author: Jérôme CHAUVIN creation date: 2009-09-25
 * 
 */
function makeItBlinkSoftly(objectID, speed, howMuchTime) {
	var monObjet = $j(objectID);
	var blinkSpeed = speed != undefined ? speed : 2000;
	var blinkTime = howMuchTime != undefined ? howMuchTime : 5; 
		
	if(objectID.indexOf("#") == -1)
		monObjet = $j("#"+objectID);
	
	for (var i = 0; i < blinkTime; i++) {
		monObjet.fadeOut(blinkSpeed).fadeIn(blinkSpeed);
	}

}


function makeItBlinkSoftlyByClass(objectType, objectsClass, speed, howMuchTime) {
	var blinkSpeed = speed != undefined ? speed : "slow";
	var blinkTime = howMuchTime != undefined ? howMuchTime : 5; 
	if (objectsClass == undefined)
		return;
	
	// var elements = objectType != undefined ? $j(objectType + "[class *= '" +
	// objectsClass + "']") : $j("[class *= '" + objectsClass + "']");
	var elements = $j(objectType + "[class *= '" + objectsClass + "']");
	
	elements.each(function(i){
		for (var i = 0; i < blinkTime; i++) {
			$j(this).fadeOut(blinkSpeed).fadeIn(blinkSpeed);
		}
	});
}

/*
 * @author: Jérôme CHAUVIN creation date: 2009-11-23
 * 
 */
function initAnchorScrollingTo(speed) {
	var scrollSpeed = speed != undefined ? speed : 1000;
	
	$j('a[href*=#]').click(function() {
	   if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
		  var target = $j(this.hash);
		  target = target.length && target || $j('[name=' + this.hash.slice(1) +']');
		  if (target.length) {
			  var targetOffset = target.offset().top;
			  // alert("targetOffset : "+targetOffset);
			  var theHash = $j(this).attr("href");
				
			  // The animation:
			  $j('html,body').animate({scrollTop: targetOffset}, scrollSpeed);
				
			  // if($j.browser.msie)
				// window.location.hash = theHash; //Reset the "hash" in the URL
			  
			  return false;
			}
		}
	});
	
}


/** Cool but resource-intensive due to recursive calls: * */
/*
 * @author: Jérôme CHAUVIN creation date: 2007-11-07
 * 
 */
function makeItBlink(objectID, speed) {
	var monObjet = $j(objectID);
	var blinkSpeed = speed != undefined ? speed : 2000;
	 
	if(objectID.indexOf("#") == -1)
		monObjet = $j("#"+objectID);
	  
	monObjet.fadeOut( blinkSpeed,
						function () { 
					      monObjet.fadeIn( blinkSpeed,
								        	function () { 
									          makeItBlink(objectID, blinkSpeed);
									        });
	    				});
}

function makeItBlinkByClass(objectType, objectsClass, speed) {
	var blinkSpeed = speed != undefined ? speed : "slow";
	if (objectsClass == undefined)
		return;
	
	// var elements = objectType != undefined ? $j(objectType + "[class *= '" +
	// objectsClass + "']") : $j("[class *= '" + objectsClass + "']");
	var elements = $j(objectType + "[class *= '" + objectsClass + "']");
	
	elements.each(function(i){
		$j(this).fadeOut(blinkSpeed,
						 function () { 
							$j(this).fadeIn( blinkSpeed,
											 function () { 
												makeItBlinkByClass(objectType, objectsClass, blinkSpeed);
						        			});
						});
	});
}


// return the current urls.
function getPageUrl() {
  return document.URL;
}

// return the current url, cleaned of its parameters
// example: http://www.webmuseo.com/?param=value becomes http://www.webmuseo.com
function getPageUrlWithoutParameters() {
  var url = getPageUrl();
  return getUrlWithoutParameters(url);
}

// delete the parameters of the given url
// example: http://www.webmuseo.com/?param=value becomes http://www.webmuseo.com
function getUrlWithoutParameters(url) {
  var i = url.indexOf("?");
  if (i != -1) {
  	url = url.substring(0, i);
  }
  return url;
}


// show or hide an element by its ID (reverse its visibility - i.e. "display
// mode")
function showOrHide(id) {
	var element = document.getElementById(id);
	var display = $j("#"+id).css("display");// element.style.display doesn't
											// work great
	if (display == "block") {
		hide(element);
	} else {
		show(element);
	}
}

// force the visibility of an element by its ID
function showById(id) {
	show(document.getElementById(id));
}

// force the visibility of all the elements with the same CSS given class.
function showByClass(cssClass) {
	var elements = $j("." + cssClass);
	for (var i = 0; i < elements.length; i++) {
		var element = elements[i];
		show(element);
	}
}

// force the visibility of an element
function show(element) {
	element.style.display = "block";
}

// hide an element by its ID
function hideById(id) {
	hide(document.getElementById(id));
}

// hide all elements with the same CSS given class
function hideByClass(cssClass) {
	var elements = $j("." + cssClass);
	for (var i = 0; i < elements.length; i++) {
		var element = elements[i];
		hide(element);
	}
}

// hide an element
function hide(element) {
	element.style.display = "none";
}


/*
 * @author : Jérôme CHAUVIN creation date : 2008-03-20
 * 
 * Similar to jQuery "load" but we replace the element instead of its content.
 */
function ajaxReplace(id, url, data, fonction) {
	$j.post(url, data, function (data, textStatus) {
	   $j("#" + id).replaceWith($j(data));
	   if (fonction) {
	     $j(fonction);
	   }
	});
}

/*
 * @author : Jérôme CHAUVIN creation date : 2008-03-20
 * 
 * /!\ : a jQuery Load, over-written, instead of a "ajaxReplace", for IE6/7.
 */
function ajaxLoad(id, url, data, fonction) {
	$j("#" + id).load(url, data, function (data, textStatus) {
	   if (fonction) {
	     $j(fonction);
	   }
	});
}

/*
 * @author: Jérôme CHAUVIN creation date: 2008-04-10
 * 
 * Function to call when we have to add or call a script in an Ajax loaded page,
 * for example with via ThickBox or via richDate.js.
 */
function addScript(scriptURL, fileCharset) {
	var headID = document.getElementsByTagName("head")[0];         
	var newScript = document.createElement('script');
	newScript.type = 'text/javascript';
	newScript.src = scriptURL;
	if (fileCharset) {
		newScript.charset = fileCharset;
	}
	headID.appendChild(newScript);
}

/*
 * @author: Jérôme CHAUVIN creation date: 2008-04-14
 * 
 * Function to call when we want to add a CSS in an Ajax loaded page or normally
 * loaded. This function could help to correct some misbehaviors of some web
 * browser which could behave in a different way as IE. IE can be CSS hacked, by
 * adding special CSS with conditional comments in HTML (in the "head" tag).
 * Conditional comments can also inform that we're using IE and test what is its
 * version or inform that we're not using IE but not we're using another and
 * specific web browser and its version. Javascript (and so jquery) can allow
 * that.
 */
function addCSS(cssFileURL, media) {
	var headID = document.getElementsByTagName("head")[0];         
	var newCss = document.createElement('link');
	newCss.rel = 'stylesheet';
	newCss.type = 'text/css';
	newCss.href = cssFileURL;
	if (media) {
		newCss.media = media;
	} else
		newCss.media = 'all';
	
	headID.appendChild(newCss);
}

// Replace all the occurrence of a searched string ("search",) in a string
// ("str"), by another value ("repl")
function replaceAll(str, search, repl) {
	while (str.indexOf(search) != -1)
		str = str.replace(search, repl);
	return str;
}

// return true if "text" contains "chars"
function contains(text, chars) {
	return text.indexOf(chars) != -1;
}

// return true if "text" contains at least one figure
function containsAtLeastOneFigure(text) {
  for (var i = 0 ; i < 10 ; i++) {
    if (contains(text, String.fromCharCode(48 + i))) {
      return true;
    } 
  }
  return false;
}

// return true if "value" contains only figures
function containsOnlyFigure(value) {
	// OK too:
	var exp = new RegExp('^[0-9]+$','g');
	return exp.test(value);
	
	// return !isNaN(value);
}

// return true if "value" is numeric (float with "." included)
function isNumeric(value) {
	// OK too:
	// var exp = new RegExp('^[0-9-.]+$','g');
	// return exp.test(value);
	
	return !isNaN(value);
}


// For RecordRuleManagment, used in manager.js
// TODO: Specify lang or directly the msg to use ?
function alertBeforeChange() {
	return confirm("Cette modification peut entrainer l'effacement de certaines données liées à la valeur précédente. Voulez-vous continuer ?"); 
}

function XMLtoString(data) {
	// for IE
	if (window.ActiveXObject) {
	    var string = data.xml;
	    // alert(string);
	}
	// code for Mozilla, Firefox, Opera, etc.
	else {
	   var string = (new XMLSerializer()).serializeToString(data);
	   // alert(string);
	}
	
	return string;
}

function getTime(lang) {
	var date = new Date();
	var separator = lang != undefined && lang == 'fr' ? 'h' : ':';
	var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
	return date.getHours() + separator + minutes;
}

function getDate(lang) {
	var whichLanguage = lang != undefined && lang != '' ? lang : 'fr';
	var tabDays = new Array("fr", "en");
	
	tabDays["fr"] = new Array("dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi");
	tabDays["en"] = new Array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
	
	var tabMonths = new Array('fr', 'en');
	tabMonths["fr"] = new Array('janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre');
	tabMonths["en"] = new Array('january', 'february', 'march', 'april', 'may', 'june', 'jully', 'august', 'september', 'october', 'november', 'december');
	
	
	var date = new Date();
	var dayLabel = tabDays[whichLanguage][date.getDay()];
	var monthLabel = tabMonths[whichLanguage][date.getMonth()];
	
	// TODO: change date format for english language.
	return dayLabel + ' ' + date.getDate() + ' ' + monthLabel + ' ' + date.getFullYear();
}

/**
 * getFieldRefFromAgentId
 * 
 * @param {String}
 *            agentId ex: slide_BlockSet_tFId_7_-8_2345
 * @return fieldRef ex: BlockSet_tFId_7_-8_2345
 */
 function getFieldRefFromAgentId(agentId) {
 	var fieldRef = "";
 	
 	var startPosition = agentId.indexOf('_');
 	if (startPosition != -1){
 		fieldRef = agentId.substr(startPosition+1);
 	} else {
 		alert("error: getFieldRefFromAgentId fail");
 	}
 	
 	return fieldRef;
 }
 
 /**
	 * getAgentTypeFromAgentId
	 * 
	 * @param {String}
	 *            agentId ex: slide_BlockSet_tFId_7_-8_2345
	 * @return agentType ex: slide
	 */
  function getAgentTypeFromAgentId(agentId) {
  	var agentType = "";
 	
 	var endPosition = agentId.indexOf('_');
 	if (endPosition != -1){
 		agentType = agentId.substr(0, endPosition);
 	} else {
 		alert("error: getAgentTypeFromAgentId fail");
 	}
 	
 	return agentType;
  }
  
/**
 * fieldRefToNotApplicable
 * 
 * @param {String}
 *            fieldRefApplicable
 * @return fieldRefNotApplicable
 */
function fieldRefToNotApplicable(fieldRefApplicable) {
	var fieldRefNotApplicable = '';
 var startPosition = fieldRefApplicable.lastIndexOf('_');
 if (startPosition != -1) {
 	var fieldId = fieldRefApplicable.substr(startPosition + 1);
 	
 	fieldRefNotApplicable = fieldRefApplicable.substr(0, fieldRefApplicable.substr(0, startPosition).lastIndexOf('_'))+ '_NA_'+ fieldId; 
 } else {
 	alert("error: fieldRefNotApplicable fail");
   	 }
   	 
   	 return fieldRefNotApplicable;
   }


/* ******************** */
/* Prototyped functions */
/* ******************** */

// Array prototyped "contains" function:
Array.prototype.contains = function (element) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == element) {
			return true;
		}
	}
	return false;
}

// String prototyped "trim" function:
String.prototype.trim = function(){
	return (this.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, ""));
}

// String prototyped "startsWith" function:
String.prototype.startsWith = function(str) {
	return (this.match("^"+str)==str);
}

// String prototyped "endsWith" function:
String.prototype.endsWith = function(str) {
	return (this.match(str+"$")==str);
}