/**************************/
/* Media players */
var _mediaTested = false;
var _mediaHaveQuickTime = false;
var _mediaHaveWindowsMediaPlayer = false;

/* http://developer.apple.com/internet/webcontent/examples/detectplugins_source.html */
if (isInternetExplorer()) {
    document.writeln('<script language="VBscript">');

    document.writeln('\'do a one-time test for a version of VBScript that can handle this code');
    document.writeln('detectableWithVB = False');
    document.writeln('If ScriptEngineMajorVersion >= 2 then');
    document.writeln('  detectableWithVB = True');
    document.writeln('End If');

    document.writeln('\'this next function will detect most plugins');
    document.writeln('Function detectActiveXControl(activeXControlName)');
    document.writeln('  on error resume next');
    document.writeln('  detectActiveXControl = False');
    document.writeln('  If detectableWithVB Then');
    document.writeln('     detectActiveXControl = IsObject(CreateObject(activeXControlName))');
    document.writeln('  End If');
    document.writeln('End Function');

    document.writeln('\'and the following function handles QuickTime');
    document.writeln('Function detectQuickTimeActiveXControl()');
    document.writeln('  on error resume next');
    document.writeln('  detectQuickTimeActiveXControl = False');
    document.writeln('  If detectableWithVB Then');
    document.writeln('    detectQuickTimeActiveXControl = False');
    document.writeln('    hasQuickTimeChecker = false');
    document.writeln('    Set hasQuickTimeChecker = CreateObject("QuickTimeCheckObject.QuickTimeCheck.1")');
    document.writeln('    If IsObject(hasQuickTimeChecker) Then');
    document.writeln('      If hasQuickTimeChecker.IsQuickTimeAvailable(0) Then ');
    document.writeln('        detectQuickTimeActiveXControl = True');
    document.writeln('      End If');
    document.writeln('    End If');
    document.writeln('  End If');
    document.writeln('End Function');

    document.writeln('</scr' + 'ipt>');
}

function detectMediaPlayers() {
	if (_mediaTested) return;
	detectQuickTime();
	detectWindowsMediaPlayer();
	_mediaTested = true;
}

function detectWindowsMediaPlayer() {
	if (isInternetExplorer()) {
		_mediaHaveWindowsMediaPlayer = detectActiveXControl('MediaPlayer.MediaPlayer.1');
	}
	else if (navigator && navigator.plugins) {
		for (var i=0; i < navigator.plugins.length; i++ ) {
			if (navigator.plugins[i].name.indexOf("Windows Media") >= 0) {
				_mediaHaveWindowsMediaPlayer = true;
				break;
			}
		}
	}
}

function all_checked(suffix, number) {
	var i = 0;
	var loopOk = true;
	while(i < number && loopOk) {
		var d = document.getElementById(suffix + i);		
		loopOk = d.checked || !d.checked && d.disabled;
		i++;
	}
	return loopOk;
}

function at_least_one_checked(suffix, number) {
	var i = 0;
	while(i < number && !document.getElementById(suffix+i).checked) {
		i++;
	}
	return i < number;
}

function checkboxes(form, name) {
    var arr = getFormElementsByName(form, name);        
    for(var i = 0; i < arr.length; i++) {
        if (i == 0) {
            arr[i].checked = !arr[i].checked;
        } else {
            arr[i].checked = arr[0].checked;
        }
    }
}

function checkboxes_n(suffix, number, state) {
    for(var i = 0; i < number; i++) {
		var check = document.getElementById(suffix+i);
		if (check && !check.disabled) {
			check.checked = state;
		}
    }
}

function hide_n(suffix, number) {
	for(var i = 0; i < number; i++) {
		var hide = document.getElementById(suffix+i);
		if (hide) hide.style.display = 'none';
    }
}

function deploy(id) {
	var comp = document.getElementById(id);
	if (comp != null) {
		if (comp.style.display != 'none') {
			comp.setAttribute('old_display', comp.style.display);
			comp.style.display = 'none';
		} else {
			if (comp.getAttribute('old_display') != null) {
				comp.style.display = comp.getAttribute('old_display');
			}
			else {
				comp.style.display = '';
			}
		}
	}
}

function apply_opacity(elt, op) {
	if (elt.style.display != 'block') {
		elt.style.display = 'block';
	}
	elt.style.MozOpacity = op;
	elt.style.filter = "alpha(opacity=" + parseInt(op * 100) + ")";
	elt.style.opacity = op;
}

function detectQuickTime() {
	if (isInternetExplorer()) {
		_mediaHaveQuickTime = detectQuickTimeActiveXControl();
	}
	else if (navigator.plugins) {
		for (i=0; i < navigator.plugins.length; i++ ) {
			if (navigator.plugins[i].name.indexOf("QuickTime") >= 0) {
				_mediaHaveQuickTime = true;
				break;
			}
		}
	}
}

function showMedia(mediaUrl, mediaExt, mediaId) {
	var elem = document.getElementById(mediaId);
	if (!elem) return "Missing div element";
	
	/* navigateurs */
	var opera = isOpera();
	var ie = isInternetExplorer();
	
	/* type et dimensions */
	var video = new Array('mov', '3gp', 'avi', 'wmv', 'mp4');
	var width = 100;
	var height;
	var mediaType;
	if (inArray(mediaExt, video)) {
		height = 100;
		mediaType = "video";
	}
	else {
		height = 20;
		mediaType = "audio";
	}
	
	/* extensions par player */
	var quicktime = new Array('mov', '3gp', 'wav', 'mp3');
	var windowsmediaplayer = new Array('avi', 'wav', 'mp3', 'wmv', 'mp4');
	
	/* Audio Opera avec Quicktime */
	if (opera && _mediaHaveQuickTime && mediaType == 'audio') {
		elem.innerHTML =
			'<embed src="'+mediaUrl+'" width="'+width+'" height="'+height+'" autoplay="'+false+'"/>';
	}		
	/* Quicktime */
	else if (_mediaHaveQuickTime && inArray(mediaExt, quicktime) ) {
		elem.innerHTML = 
			"<object classid=\"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B\""+
			(ie ? " width=\"" + width + "\" height=\"" + height + "\"" : "") +
			" codebase=\"http://www.apple.com/qtactivex/qtplugin.cab\">" +
    		"<param name=\"src\" value=\"" + mediaUrl + "\"/>" +
    		"<param name=\"href\" value=\"" + mediaUrl + "\"/>" +
			"<param name=\"controller\" value=\"true\"/>" +
    		"<param name=\"autoplay\" value=\"false\"/>" +
    		(mediaType == "video" ? "<param name=\"scale\" value=\"aspect\"/>" : "") +
    		"<object type=\""+
    		(mediaType == "video" ? "video/quicktime" : "audio/x-wav") + 
    		"\" data=\"" + mediaUrl + "\""+
    		(!ie ? " width=\"" + width + "\" height=\"" + height + "\"" : "") +
    		" class=\"" + mediaExt + "\">" +
    		"<param name=\"href\" value=\"" + mediaUrl + "\"/>" +
			"<param name=\"controller\" value=\"true\"/>" +
    		"<param name=\"autoplay\" value=\"false\"/>" +
    		(mediaType == "video" ? "<param name=\"scale\" value=\"aspect\"/>" : "") +
    		"Failed initializing quicktime player<br/>(plugin: " + _mediaHaveQuickTime + ", ext: "+mediaExt+")"+
    		"</object>" +
    		"</object>";
	}
	/* Windows Media Player */
	else if (_mediaHaveWindowsMediaPlayer && inArray(mediaExt, windowsmediaplayer) && !(opera && mediaType == 'audio') ) {
		if (mediaType == 'audio') {
			if (ie) {
				height += 45;
				width += 60;
			}
			else {
				height += 25;
				width += 70;
			}
		}
		
		if (ie) {
			elem.innerHTML = 
				"<object classid=\"clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6\""+
				" width=\"" + width + "\" height=\"" + height + "\"" +
	    		" type='application/x-mplayer2'>" +
	    		"<param name=\"url\" value=\"" + mediaUrl + "\"/>" +
	    		"<param name='uiMode' value='mini'/>"+
	    		"<param name=\"autoStart\" value=\"false\"/>" +
	    		(mediaType == "video" ? "<param name=\"stretchToFit\" value=\"true\"/>" : "") +
	    		"Failed initializing windows media player<br/>(plugin: " + _mediaHaveWindowsMediaPlayer + ", ext: "+mediaExt+")"+
	    		"</object>";
		}
		else {
			elem.innerHTML = 
				"<object classid=\"clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6\">" +
	    		"<object type='application/x-mplayer2' data=\"" + mediaUrl + "\""+
	    		" width=\"" + width + "\" height=\"" + height + "\"" +
	    		">" +
	    		"<param name=\"src\" value=\"" + mediaUrl + "\"/>" +
	    		"<param name=\"autostart\" value=\"0\"/>" +
	    		"<param name=\"uiMode\" value=\"0\"/>" +
	    		"Failed initializing windows media player<br/>(plugin: " + _mediaHaveWindowsMediaPlayer + ", ext: "+mediaExt+")"+
	    		"</object>" +
	    		"</object>";
	    }
	}
	else {
		elem.innerHTML = "<em class='textSmall'>(no player for "+mediaExt+")</em>";
	}
}

/**************************/
function isOpera() {
	return navigator.userAgent.indexOf('Opera') != -1;
}

function isInternetExplorer() {
	return (navigator.userAgent.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Win') != -1);
}

function isMozilla() {
	return 
		("" + navigator.userAgent).toLowerCase().indexOf('mozilla') != -1 &&
		!isInternetExplorer();
}

function isSafari() {
	 return ("" + navigator.userAgent).toLowerCase().indexOf('safari') > 0
}

function getInternetExplorerVersion()
// Returns the version of Internet Explorer or a -1
// (indicating the use of another browser).
{
  var rv = -1; // Return value assumes failure.
  if (navigator.appName == 'Microsoft Internet Explorer')
  {
    var ua = navigator.userAgent;
    var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    if (re.exec(ua) != null)
      rv = parseFloat( RegExp.$1 );
  }
  return rv;
}


/**************************/
var cssCacheValues = new Array;
var cssCacheRules = new Array;

function getCssProperty(ruleName, property) {
	for(var c = 0; c < cssCacheRules.length; c++) {
		if (cssCacheRules[c] == ruleName + '_' + property) {
			return cssCacheValues[c];
		}
	}	
	
	for(var i = 0; i < document.styleSheets.length; i++) {
		var rules = document.styleSheets.item(i);
		rules = rules.cssRules ? rules.cssRules : rules.rules;
		for (var j = 0; j < rules.length; j++) {
			if (rules.item(j).selectorText && rules.item(j).selectorText.indexOf(ruleName) >= 0) {
				var r = null;
				eval('r = rules.item(j).style.' + property + ';');
				if (r && r != null) {
					cssCacheRules.push(ruleName + '_' + property);
					cssCacheValues.push(r);
					return r;
				}
			}
		}
	}
	return null;
}
/**************************/

function burstBubble(e) {
	var ev;
	if (!e) ev = window.event;
	else ev = e;
	ev.cancelBubble = true;
	if (ev.stopPropagation) ev.stopPropagation();
}

function inArray(elem, arr) {
	var found = false;
	var i = 0;
	while(!found && i < arr.length) {
		found = arr[i] == elem;
		i++;
	}
	return found;
}

function getScreenWidth() {
	if (navigator.appName.indexOf("Microsoft") != -1) {
        if (window.clientInformation.width) return window.clientInformation.width;
		if (document.documentElement.clientWidth) return document.documentElement.clientWidth;
        return document.body.clientWidth;		
    } else {
        var netscapeScrollWidth=15;
        return window.innerWidth - netscapeScrollWidth;
    }
}

function getScreenHeight() {
	if (navigator.appName.indexOf("Microsoft") != -1) {
		if (window.clientInformation.height) return window.clientInformation.height;
		if (document.documentElement.clientHeight) return document.documentElement.clientHeight;
		return document.body.clientHeight;		
    } else {
        return window.innerHeight;
    }
}

function hex2dec(hex) {
	var h = hex.toLowerCase();
	var p = h.indexOf('0x');
	if (p >= 0) {
		h = h.substring(p + 1);
	}
	var ref = '0123456789abcdef';
	var res = 0;
	var start = h.length - 1;
	for(var i = start; i >= 0; i--) {
		res += ( ref.indexOf(h.charAt(i)) *  Math.pow(16, start - i ) );
	}
	
	return res;
}

function InfoBox(id, show, event/*, time*/) {
    /*if (id == null) return false;*/
    var ibox = document.getElementById(id);
    if (!ibox) return false;
    /* foutus browsers incapables de parler la m�me langue */
    /* http://www.quirksmode.org/js/events_properties.html */
    var x = 0;    
    var y = 24;    
    var posx = 0;
	var posy = 0;    
	if (event.pageX || event.pageY) {
		posx = event.pageX;
		posy = event.pageY;
	}
	else /*if (event.clientX || event.clientY)*/ {
		posx = event.clientX + document.body.scrollLeft;
		posy = event.clientY + document.body.scrollTop;
	}    
    x += posx;
    y += posy;        
    /*if (ibox) { != null && ibox != 'undefined') {*/
        if (show) {
            /*if (ibox.style.display != 'block' && time > 0) {
                clearTimeout(infoBoxTimeOut);
                infoBoxTimeOut = setTimeout("_DispInfoBox('"+ibox.id+"', "+x+", "+y+")", time);   
            }
            else {
                _DispInfoBox(ibox.id, x, y);
            }*/
            ibox.style.left = x + 'px';
	        ibox.style.top = y + 'px';
	        ibox.style.display = 'block';
        }
        else {
            /*clearTimeout(infoBoxTimeOut);*/
            ibox.style.display = 'none';
        }
    /*}*/
    return true;
}
/*
function _DispInfoBox(id, x, y) {
    var ibox = document.getElementById(id);
    if (ibox != null) {
        ibox.style.left = x + 'px';
        ibox.style.top = y + 'px';
        ibox.style.display = 'block';
    }
}*/

function getElementLeft(elmID) {
	var obj = document.getElementById(elmID);
	if (!obj) return 0;
	var curleft = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x){
		curleft += obj.x;
	}
	return curleft;
}

function getElementTop(elmID) {
	var obj = document.getElementById(elmID);
	if (!obj) return 0;
	var curtop = 0;
	if (obj.offsetParent) {
		while (obj.offsetParent) {
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}

function getElementHeight(elmID) {
	var elem = document.getElementById(elmID);
	if (elem) {
		if(elem.clientHeight) {
			return elem.clientHeight;
		}
		
		if(elem.offsetHeight) {
			return elem.offsetHeight;
		}
		
			
	}
	return 0;
}

function getElementWidth(elmID) {
	var elem = document.getElementById(elmID);
	if (elem) {
		if (elem.scrollWidth) {
			return elem.scrollWidth;
		}
		
		if (elem.clientWidth) {
			return elem.clientWidth;
		}
		
		if (elem.offsetWidth) {
			return elem.offsetWidth;
		}
		
		var w = null;
		
		if (elem.className) {
			w = getCssProperty(elem.className, 'width');			
		}
		if (!w && elem.style && elem.style.width) {
			w = style.width;
		}
		
		if (w) {
			return w.replace(/[^0-9]/g, '');
		}
	}
	return 0;
}

function getFormElementsByName(form, name) {
    var tab;
    var ev = "";
    for(var i = 0; i < form.elements.length; i++) {
        if (form.elements[i].name == name) {
            if (ev == "") {
                ev = "tab = new Array(";   
            }
            else {
                ev += ", ";
            }
            ev += "form.elements["+i+"]";
        }
    }
    ev += ");";
    eval(ev);
    return tab;
}


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(nom) {
	var arg=nom+"=";
	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;
}
/* http://www.actulab.com/ecrire-les-cookies.php */
function WriteCookie(nom, valeur) {
    var argv = arguments;
    var argc = arguments.length;
    
    var date=new Date;
    date.setDate(date.getDate()+ (365 * 5));
    var expires = date;
    
    var path=(argc > 3) ? argv[3] : null;
    var domain=(argc > 4) ? argv[4] : null;
    var secure=(argc > 5) ? argv[5] : false;
    
    document.cookie=nom+"="+escape(valeur)+
    ((expires==null) ? "" : ("; expires="+expires.toGMTString() ))+
    ((path==null) ? "" : ("; path="+path))+
    ((domain==null) ? "" : ("; domain="+domain))+
    ((secure==true) ? "; secure" : "");
}

function DeleteCookie( name, path, domain ) {
	if ( ReadCookie( name ) ) document.cookie = name + "=" +
	( ( path ) ? ";path=" + path : "") +
	( ( domain ) ? ";domain=" + domain : "" ) +
	";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}

function trim(chaine) { 
	return chaine.replace(/(^\s*)|(\s*$)/g, "");
}

var calendarsI = new Array;
var calendarsV = new Array;
function getCalendar(elemId) {
	var cal = null;
	var i = 0;
	while(cal == null && i < calendarsI.length) {
		if (calendarsI[i] == elemId) {
			cal = calendarsV[i];
		}
		else {
			i++;
		}
	}

	if (cal == null) { 
		cal = new CalendarPopup('calendar_popup_zone');
		cal.setCssPrefix('calendar_');
		calendarsI.push(elemId);
		calendarsV.push(cal);
	}
	
	return cal;
}
function openCalendar(elemId, format) {
	var cal = getCalendar(elemId);	 
	cal.select(document.getElementById(elemId), 'anchor_field_' + elemId, format);
}

// http://blog.vishalon.net/Post/57.aspx
function getCaretPosition (ctrl) {
	var CaretPos = 0;
	// IE Support
	if (document.selection) {

		ctrl.focus ();
		var Sel = document.selection.createRange ();

		Sel.moveStart ('character', -ctrl.value.length);

		CaretPos = Sel.text.length;
	}
	// Firefox support
	else if (ctrl.selectionStart || ctrl.selectionStart == '0')
		CaretPos = ctrl.selectionStart;

	return (CaretPos);
}
// http://blog.vishalon.net/Post/57.aspx
function setCaretPosition(ctrl, pos) {

	if(ctrl.setSelectionRange)
	{
		ctrl.focus();
		ctrl.setSelectionRange(pos,pos);
	}
	else if (ctrl.createTextRange) {
		var range = ctrl.createTextRange();
		range.collapse(true);
		range.moveEnd('character', pos);
		range.moveStart('character', pos);
		range.select();
	}
}

function highlightRowAndColumnHeads(element,table,col){
	element.className += " highlight_nobold";
	element.parentNode.firstChild.className += " highlight_nobold";
	document.getElementById('element_'+table+'_'+col).className += " highlight_nobold";
}

function downlightRowAndColumnHeads(element,table,col){
	element.className = "";
	element.parentNode.firstChild.className = element.parentNode.firstChild.className.replace("highlight_nobold", "");
	document.getElementById('element_'+table+'_'+col).className = document.getElementById('element_'+table+'_'+col).className.replace("highlight_nobold", "");
}

function hideSubformPopup() {
	disablePopup();
}

function showSubformPopup() {
	//centering with css  
	centerPopup(); 

	//Click out event!  
	$("#overlay").click(function(){  
		disablePopup();  
	});  
	//Press Escape event!  
	$(document).keypress(function(e){  
		if(e.keyCode==27 && popupStatus==1){  
			disablePopup();  
		}  
	});  	
	var bodyheight = document.body.clientHeight + 20;
	if(bodyheight>screen.height)
		document.getElementById('overlay').style.height = bodyheight +'px';
	document.getElementById('ancre_subform').style.marginTop = getScrollPosition()[1]+'px';
	
	//load popup  
	loadPopup();
}

var popupStatus = 0;
function centerPopup(){  
	//request data for centering  
	var windowWidth = document.documentElement.clientWidth;  
	var windowHeight = document.documentElement.clientHeight;  
	var popupHeight = $("#ancre_subform").height();  
	var popupWidth = $("#ancre_subform").width();  
	//centering  
	var top = windowHeight/2-popupHeight/2;
	var left = windowWidth/2-popupWidth/2;
	if(top<10) top=10;
	if(left<10) left=10;
	$("#ancre_subform").css({  
		"position": "absolute",  
		"top": top,  
		"left": left  
	});  
	//only need force for IE6  
	  
	$("#overlay").css({  
		"height": windowHeight  
	});  
	  
}  

function loadPopup(){  
	//loads popup only if it is disabled  
	if(popupStatus==0){  
		$("#overlay").css({  
			"opacity": "0.7"  
		});  
		$("#overlay").fadeIn("slow");  
		$("#ancre_subform").fadeIn("slow");  
		popupStatus = 1;  
	}  
}

function disablePopup(){  
	//disables popup only if it is enabled  
	if(popupStatus==1){  
		$("#overlay").fadeOut("slow");  
		$("#ancre_subform").fadeOut("slow");  
		popupStatus = 0;  
	}  
}  

function getScrollPosition()
{
    return Array((document.documentElement && document.documentElement.scrollLeft) || window.pageXOffset || self.pageXOffset || document.body.scrollLeft,(document.documentElement && document.documentElement.scrollTop) || window.pageYOffset || self.pageYOffset || document.body.scrollTop);
}

var map;
var map_api = "googlemap";
var directionDisplay;
var directionsService;

var new_markers = new Array;
var old_markers = new Array;
var hidden_markers = new Array();
var infowindow;
function add_marker_to_map(map_id, latitude, longitude, comments, icon, rememberMarker, id, draggable, custom_icon, icon_class){
	var marker = null;
	
	if(rememberMarker && id!="" && id!=0 && (old_markers[map_id]!=undefined && old_markers[map_id][id]!=undefined || hidden_markers[map_id]!=undefined && hidden_markers[map_id][id]!=undefined)){
		if(hidden_markers[map_id][id]!=undefined){
			//if(hidden_markers[map_id][id].getIcon() != icon)
			//	hidden_markers[map_id][id].setIcon(icon);
			if(map_api=="googlemap"){
				hidden_markers[map_id][id].setMap(map);
			}
			else if(map_api=="bing"){
				hidden_markers[map_id][id].Show();
			}
			
			new_markers[map_id][id] = hidden_markers[map_id][id];
			delete hidden_markers[map_id][id];
		}
		else{
			//if(old_markers[map_id][id].getIcon() != icon)
			//	old_markers[map_id][id].setIcon(icon);
			new_markers[map_id][id] = old_markers[map_id][id];
			delete old_markers[map_id][id];
		}
		marker = new_markers[map_id][id];
	}
	else{
		if(map_api=="googlemap" && typeof(google) != 'undefined') {
			point = new google.maps.LatLng(latitude, longitude);
			marker = new google.maps.Marker({
				map: map,
				position: point, 
				title: comments,
				icon:icon,
				draggable:draggable
			});
			google.maps.event.addListener(marker, 'click', function() {
				if (infowindow) {
					infowindow.close();
				}
				infowindow = new google.maps.InfoWindow({ 
				    content: comments,
			        size: new google.maps.Size(50,50),
			        position: new google.maps.LatLng(latitude, longitude)
			    });
			  	infowindow.open(map);
			});	
		}
		else if(map_api=="bing"){
			point = new VELatLong(latitude, longitude);
			marker = new VEShape(VEShapeType.Pushpin, point);
			marker.SetTitle(comments);
	        if(icon != "")
	        	marker.SetCustomIcon('<img src="'+icon+'" alt="Pushpin" class="'+icon_class+'"/>');
	        if(custom_icon != "")
	        	marker.SetCustomIcon(custom_icon);
	        marker.Draggable = draggable;
	        map.AddShape(marker);
		}
		
		if(rememberMarker && id!="" && id!=0 && marker){
			if(new_markers[map_id] == undefined)
				new_markers[map_id] = new Array;
			new_markers[map_id][id] = marker;
		}
	}
	return marker;
}
function remove_old_markers(map_id){
	for(i in old_markers[map_id]){
		if(old_markers[map_id][i]!=undefined){
			if(map_api=="googlemap"){
				old_markers[map_id][i].setMap(null);
			}
			else if(map_api=="bing"){
				old_markers[map_id][i].Hide();
			}
			hidden_markers[map_id][i] = old_markers[map_id][i];
		}
	}
}

var bing_map_waypts, bing_map_options;
function bing_map_save_waypts_and_options(waypts, options){
	bing_map_waypts = waypts;
	bing_map_options = options;
}

function bing_map_finish_direction_work(route){
	if(route.Distance == 0 && route.Time == 0)
		bing_map_use_MWS_for_route(route);
	else
		bing_maps_hide_directions_shapes(route);
}

function bing_map_use_MWS_for_route(route){
	bing_map_options.UseMWS = true;
	bing_map_options.RouteCallback = bing_maps_hide_directions_shapes;
	bing_map_options.ShowErrorMessages = true;
	map.GetDirections(bing_map_waypts, bing_map_options);
}

function bing_maps_hide_directions_shapes(route)
{	
  // Unroll route and populate DIV
  var legs = route.RouteLegs;
  var leg = null;
  var legItinerary = null;

  for (var i = 0; i < legs.length; i++) {
	    leg = legs[i];
	    legItinerary = leg.Itinerary;
	    
	    for (var j = 0; j < legItinerary.Items.length; j++) {
	          legItinerary.Items[j].Shape.Hide(); 
	    }
	}
}

function bing_map_resize(){
	map.Resize();
	var width = $('#gpsmap_frame').width();
	if($('#gpsmap_arbo').css('position') != "absolute"){
		width -= $('#gpsmap_arbo').width();
	}
	map.Resize(width, $('#gpsmap_map').height());
}

function ReplaceAll(Source, stringToFind, stringToReplace){
	if(Source == null){
		return false;
	}
	var temp = Source;
	var index = temp.indexOf(stringToFind);
	while(index != -1){
	    temp = temp.replace(stringToFind,stringToReplace);
	    index = temp.indexOf(stringToFind);
	}
	return temp;
}

function array_keys(input, search_value, argStrict) {
    // Return just the keys from the input array, optionally only for the specified search_value  
    // 
    // version: 1008.1718
    // discuss at: http://phpjs.org/functions/array_keys    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: array_keys( {firstname: 'Kevin', surname: 'van Zonneveld'} );
    // *     returns 1: {0: 'firstname', 1: 'surname'}    
    var tmp_arr = {}, strict = !!argStrict, include = true, cnt = 0;
    var key = '';
    
    for (key in input) {        include = true;
        if (search_value != undefined) {
            if (strict && input[key] !== search_value){
                include = false;
            } else if (input[key] != search_value){                include = false;
            }
        }
        
        if (include) {            tmp_arr[cnt] = key;
            cnt++;
        }
    }
        return tmp_arr;
}

function in_array(needle, haystack, argStrict) {
    // Checks if the given value exists in the array  
    // 
    // version: 1008.1718
    // discuss at: http://phpjs.org/functions/in_array    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: vlado houba
    // +   input by: Billy
    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
    // *     example 1: in_array('van', ['Kevin', 'van', 'Zonneveld']);    // *     returns 1: true
    // *     example 2: in_array('vlado', {0: 'Kevin', vlado: 'van', 1: 'Zonneveld'});
    // *     returns 2: false
    // *     example 3: in_array(1, ['1', '2', '3']);
    // *     returns 3: true    // *     example 3: in_array(1, ['1', '2', '3'], false);
    // *     returns 3: true
    // *     example 4: in_array(1, ['1', '2', '3'], true);
    // *     returns 4: false
    var key = '', strict = !!argStrict; 
    if (strict) {
        for (key in haystack) {
            if (haystack[key] === needle) {
                return true;            }
        }
    } else {
        for (key in haystack) {
            if (haystack[key] == needle) {                return true;
            }
        }
    }
     return false;
}

function short(string, length) {
	if (string.length <= length) return string;
	
	return string.substr(0, length) + "...";
}

/**
* http://www.meanfreepath.com/support/getting_iso_week.html
* Returns the week number for this date. dowOffset is the day of week the week
* "starts" on for your locale - it can be from 0 to 6. If dowOffset is 1 (Monday),
* the week returned is the ISO 8601 week number.
* @param int dowOffset
* @return int
*/
Date.prototype.getWeek = function (dowOffset) {
/*getWeek() was developed by Nick Baicoianu at MeanFreePath: http://www.meanfreepath.com */

dowOffset = typeof(dowOffset) == 'int' ? dowOffset : 0; //default dowOffset to zero
var newYear = new Date(this.getFullYear(),0,1);
var day = newYear.getDay() - dowOffset; //the day of week the year begins on
day = (day >= 0 ? day : day + 7);
var daynum = Math.floor((this.getTime() - newYear.getTime() -
(this.getTimezoneOffset()-newYear.getTimezoneOffset())*60000)/86400000) + 1;
var weeknum;
//if the year starts before the middle of a week
if(day < 4) {
weeknum = Math.floor((daynum+day-1)/7) + 1;
if(weeknum > 52) {
nYear = new Date(this.getFullYear() + 1,0,1);
nday = nYear.getDay() - dowOffset;
nday = nday >= 0 ? nday : nday + 7;
/*if the next year starts before the middle of
the week, it is week #1 of that year*/
weeknum = nday < 4 ? 1 : 53;
}
}
else {
weeknum = Math.floor((daynum+day-1)/7);
}
return weeknum;
}; 

/*
 * Month between 1 and 12
 * Note that javascript getMonth is between 0 and 11
 */
function daysInMonth(month,year) {
	var m = [31,28,31,30,31,30,31,31,30,31,30,31];
	if (month != 2) return m[month - 1];
	if (year%4 != 0) return m[1];
	if (year%100 == 0 && year%400 != 0) return m[1];
	return m[1] + 1;
} 

function generate_string(length, base){
	var minuscules = new Array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
	var majuscules = new Array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');

	string = base != undefined ? base : ''; //On déclare notre variable
	var type, caractere, nbre_aleatoire;
    for (var i = 1; i <= length; i++)
    {
    //On génère un type aléatoire
    type = Math.floor(Math.random()*3);
        switch (type)
        {
            case 0:
                 caractere = Math.floor(Math.random()*10);
                 string += caractere;
            break;
            
            case 1:
                 nbre_aleatoire = Math.floor(Math.random()*26);
                 caractere = majuscules[nbre_aleatoire];
                 string += caractere;
            break;
            
            case 2:
                 nbre_aleatoire = Math.floor(Math.random()*26);
                 caractere = minuscules[nbre_aleatoire];
                 string += caractere;
            break;
        }
    }
	return string; 
}

function event_is_over_one_of_dom_elements(e, domE) {
	var over = false;
	domE.each(function(){
		if(event_is_over_dom_element(e, $(this))){
			over = true;
			return false;
		}
	})
	return over;
}

function event_is_over_dom_element(e, domE) {
	return e.pageX > domE.offset().left && e.pageX < domE.offset().left + domE.width()
		&& e.pageY > domE.offset().top && e.pageY < domE.offset().top + domE.height();
}

function load_XML_from_string( string ){
	var xmlDoc;
	if (window.DOMParser) {
		var parser=new DOMParser();
		xmlDoc=parser.parseFromString(string,"text/xml");
	}
	else { // Internet Explorer
		xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async="false";
		xmlDoc.loadXML(string);
	} 
	return xmlDoc;
}


//http://n8v.enteuxis.org/2010/12/parsing-iso-8601-dates-in-javascript/
//Edited By S.Clement, Penbase
function parseISO8601Date(s){
  // parenthese matches:
  // year month day    hours minutes seconds  
  // dotmilliseconds 
  // tzstring plusminus hours minutes
  var re = /(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d+)?(Z|([+-])(\d\d):(\d\d))/;
 
  var d = [];
  d = s.match(re);
 
  // "2010-12-07T11:00:00.000-09:00" parses to:
  //  ["2010-12-07T11:00:00.000-09:00", "2010", "12", "07", "11",
  //     "00", "00", ".000", "-09:00", "-", "09", "00"]
  // "2010-12-07T11:00:00.000Z" parses to:
  //  ["2010-12-07T11:00:00.000Z",      "2010", "12", "07", "11", 
  //     "00", "00", ".000", "Z", undefined, undefined, undefined]
 
  if (! d) {
    throw "Couldn't parse ISO 8601 date string '" + s + "'";
  }
 
  // parse strings, leading zeros into proper ints
  var a = [1,2,3,4,5,6,10,11];
  for (var i in a) {
    d[a[i]] = parseInt(d[a[i]], 10);
  }
  d[7] = parseFloat(d[7]);
 
  // Date.UTC(year, month[, date[, hrs[, min[, sec[, ms]]]]])
  // note that month is 0-11, not 1-12
  // see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC
  var ms = Date.UTC(d[1], d[2] - 1, d[3], d[4], d[5], d[6]);
 
  // if there are milliseconds, add them
  if (d[7] > 0) {  
    ms += Math.round(d[7] * 1000);
  }
 
  // if there's a timezone, calculate it
  if (d[8] != "Z" && d[10]) {
	var offset = d[10] * 60 * 60 * 1000;
	if (d[11]) {
	  offset += d[11] * 60 * 1000;
	}
	////Edited By S.Clement, Penbase: if sign is +, offset should be substracted to have unix time
	if (d[9] == "+") {
	  ms -= offset;
	}
	else {
	  ms += offset;
	}
  }
 
  return new Date(ms);
};

String.prototype.format = function() {
  var args = arguments;
  return this.replace(/{(\d+)}/g, function(match, number) { 
    return typeof args[number] != 'undefined'
      ? args[number]
      : '{' + number + '}'
    ;
  });
};

//http://phpjs.org/functions/nl2br:480
function nl2br (str, is_xhtml) {
    // Converts newlines to HTML line breaks
	//Edited to always use <br/>
    return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br/>$2');
}

//http://www.codingforums.com/showthread.php?t=10477
function caseInsensitiveSort(a, b) 
{ 
   var ret = 0;
   a = a.toLowerCase();b = b.toLowerCase();
   if(a > b) 
      ret = 1;
   if(a < b) 
      ret = -1; 
   return ret;
}

//Modified from http://stackoverflow.com/questions/1353684/detecting-an-invalid-date-date-instance-in-javascript
//Checks if date is Date and returns a not Nan value (which means it is not valid)
function isValidDate(d) {
  //if ( Object.prototype.toString.call(d) !== "[object Date]" )
  //  return false;
  return d instanceof Date && !isNaN(d.getTime());
}

//http://phpjs.org/functions/ksort:460
function ksort (inputArr, sort_flags) {
// Sort an array by key  
// 
// version: 1109.2015
// discuss at: http://phpjs.org/functions/ksort    // +   original by: GeekFG (http://geekfg.blogspot.com)
// +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// +   improved by: Brett Zamir (http://brett-zamir.me)
// %          note 1: The examples are correct, this is a new way
// %        note 2: This function deviates from PHP in returning a copy of the array instead    // %        note 2: of acting by reference and returning true; this was necessary because
// %        note 2: IE does not allow deleting and re-adding of properties without caching
// %        note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
// %        note 2: get the PHP behavior, but use this only if you are in an environment
// %        note 2: such as Firefox extensions where for-in iteration order is fixed and true    // %        note 2: property deletion is supported. Note that we intend to implement the PHP
// %        note 2: behavior by default if IE ever does allow it; only gives shallow copy since
// %        note 2: is by reference in PHP anyways
// %        note 3: Since JS objects' keys are always strings, and (the
// %        note 3: default) SORT_REGULAR flag distinguishes by key type,    // %        note 3: if the content is a numeric string, we treat the
// %        note 3: "original type" as numeric.
// -    depends on: i18n_loc_get_default
// -    depends on: strnatcmp
// *     example 1: data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};    // *     example 1: data = ksort(data);
// *     results 1: {a: 'orange', b: 'banana', c: 'apple', d: 'lemon'}
// *     example 2: ini_set('phpjs.strictForIn', true);
// *     example 2: data = {2: 'van', 3: 'Zonneveld', 1: 'Kevin'};
// *     example 2: ksort(data);    // *     results 2: data == {1: 'Kevin', 2: 'van', 3: 'Zonneveld'}
// *     returns 2: true
    var tmp_arr = {},
        keys = [],
        sorter, i, k, that = this,        strictForIn = false,
        populateArr = {};
 
    switch (sort_flags) {
    case 'SORT_STRING':        // compare items as strings
    sorter = function (a, b) {
        return that.strnatcmp(a, b);
    };
    break;    case 'SORT_LOCALE_STRING':
    // compare items as strings, based on the current locale (set with  i18n_loc_set_default() as of PHP6)
    var loc = this.i18n_loc_get_default();
    sorter = this.php_js.i18nLocales[loc].sorting;
    break;    case 'SORT_NUMERIC':
    // compare items numerically
    sorter = function (a, b) {
        return ((a + 0) - (b + 0));
    };        break;
    // case 'SORT_REGULAR': // compare items normally (don't change types)
default:
    sorter = function (a, b) {
        var aFloat = parseFloat(a),                bFloat = parseFloat(b),
            aNumeric = aFloat + '' === a,
            bNumeric = bFloat + '' === b;
        if (aNumeric && bNumeric) {
            return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;            } else if (aNumeric && !bNumeric) {
            return 1;
        } else if (!aNumeric && bNumeric) {
            return -1;
        }            return a > b ? 1 : a < b ? -1 : 0;
    };
    break;
}
 // Make a list of key names
    for (k in inputArr) {
        if (inputArr.hasOwnProperty(k)) {
            keys.push(k);
        }    }
    keys.sort(sorter);
 
    // BEGIN REDUNDANT
this.php_js = this.php_js || {};    this.php_js.ini = this.php_js.ini || {};
// END REDUNDANT
strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
populateArr = strictForIn ? inputArr : populateArr;
 // Rebuild array with sorted key names
    for (i = 0; i < keys.length; i++) {
        k = keys[i];
        tmp_arr[k] = inputArr[k];
        if (strictForIn) {            delete inputArr[k];
        }
    }
    for (i in tmp_arr) {
        if (tmp_arr.hasOwnProperty(i)) {            populateArr[i] = tmp_arr[i];
        }
    }
 
    return strictForIn || populateArr;}
