// plugin jQuery
$.fn.replaceClass = function( sOldClass, sNewClass) {
	return this.each(function() {
		$(this).removeClass( sOldClass).addClass( sNewClass);
	});
};
$.fn.inverseClass = function( sClass, sClassBis) {
	return this.each(function() {
		$(this).hasClass( sClass) ?
			$(this).replaceClass( sClass, sClassBis) :
				$(this).replaceClass( sClassBis, sClass);
	});
};
$.fn.check = function(mode) {
	if ( $defined(mode) || mode != '') {
		return this.each(function() {
			this.checked = (mode == 'toggle') ? !this.checked : $is_true(mode, true);
		});
	} else {
		return this[0].checked;
	}
};
$.fn.visible = function() {
	return this.each(function() {
		$(this).css({ visibility: 'visible' });
	});
};
$.fn.hidden = function() {
	return this.each(function() {
		$(this).css({ visibility: 'hidden' });
	});
};

$.fn.overlabel = function( options) {
// pb avec la verif de form, si erreur ne pas réafficher l'overlabel
    var o = $.extend( {
        label_class: 'overlabel-defaut'
    }, options );

    return this.each(function(){
        var label = $(this),
			id = this.htmlFor || label.attr('for'),
			sId = id.replace(/\:/, '\\:');

		function overFocus( oL) {
			 oL.hide();
		}
		function overBlur(jqO) {
			if( jqO.val() == '') {
				label.css({ position: 'absolute'}).show();
			}
		}

		// si title on change le label
		if( $('#' + sId).attr('title') != '') {
			label.text( $('#' + sId).attr('title'));
		}
		label.addClass(o.label_class);

		$('#' + sId)
			.focus( function() {
				overFocus( label);
				$(this).stopTime( 'checkEmpty');
			})
			.blur( function() {
				overBlur( $(this));
				$(this).everyTime(500, 'checkEmpty', function() {
					if( this.value == '') {
						overBlur( $(this));
					} else {
						overFocus( label);
					}
				});
			})
			.trigger('focus').trigger('blur');
	});
};

$.fn.contenuAjax = function( options) {
	// Options
    var o = $.extend( {
		url: '',
		type: 'get',
		data: '',
		dataType: 'html',
		place: 'append',
		loadclass: 'ajaxloading_small'
    }, options );

	return this.each(function(){
		var t = $(this);

		$.ajax({
			url: o.url,
			type: o.type,
			data: o.data,
			dataType: o.dataType,
			beforeSend : function() {
				t.addClass(o.loadclass);
			},
			error: function(oXhr, sStatus, errorThrown) {
				//alert('Erreur');
			},
			success: function(data) {
				switch(o.place) {
					case 'after': t.after(data); break;
					case 'append': t.append(data); break;
					case 'appendTo': t.appendTo(data); break;
					case 'before': t.before(data); break;
					case 'insertAfter': t.insertAfter(data); break;
					case 'insertBefore': t.insertBefore(data); break;
					case 'prepend': t.prepend(data); break;
					case 'prependTo': t.prependTo(data); break;
					case 'html': t.html(data); break;
				}
			},
			complete: function() {
				t.removeClass(o.loadclass);
			}
		});
	});
};

// langue
function _lg(s) {
	return (!$defined(i18n) && i18n[s]) ? i18n[s] : s;
}
function _lgNombre(n) {
	var o = '';
	n += '';

	for ( i = n.length; i > 3; i -= 3) {
		o = i18n.thousands_sep + n.slice(i - 3, i) + o;
	}
	return ( n.slice(0, i) + o );
}
function sprintf(s) {
	var bits = s.split('%'),
		out = bits[0],
		re = /^([ds])(.*)$/;

	for (var i = 1; i < bits.length; i++) {
		var p = re.exec(bits[i]);
		if (!p || arguments[i] === null) continue;
		if (p[1] == 'd') {
			out += parseInt(arguments[i], 10);
		} else if (p[1] == 's') {
			out += arguments[i];
		}
		out += p[2];
	}
	return out;
}
function pluriel(s, p, n) {
	return (n != 1) ? p : s;
}
//ex: sprintf(pluriel( _lg("%s sungulier", _lg('%s pluriels"), iNb), _lgNombre(iNb))

// "Constante" prédéfinie
function constante( sCode, aParam) {
	switch( sCode) {
		case 'ajaxError' : return _lg( 'Une erreur est survenue :!\n\nRafraichissez la page et essayer à nouveau.\nSi le problème persiste, contactez le webmaster.');
		case 'formError' : return sprintf(
				pluriel(
					_lg( 'Formulaire non valide : %d erreur rencontrée.'),
					_lg( 'Formulaire non valide : %d erreurs rencontrées.'),
					aParam
				),
				_lgNombre( aParam)
			);
		default: return '[Erreur code: "' + sCode + '" inconnu.]';
	}
}

// Encode
function js_encode( s) {
	return s.replace(/\\/g, '\\\\').replace(/"/g, '\&#34;').replace(/\'/g, '\&#39');
}
function url_encode( s) {
	return encodeURIComponent( s);
}
function html_encode( s) {
	return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
function html_decode( s) {
	return s.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
}
function isHtml_encode( s) {
	return (s.search(/&amp;/g) != -1 || s.search(/&lt;/g) != -1 || s.search(/&gt;/g) != -1);
}
function html_decode_if_encode() {
	return isHtml_encode(s) ? html_decode(s) : s;
}

// Tronque la chaine passée en paramètre
function tronquer( s, iMax) {
	s = $.trim( s);
	return ( s.length > iMax ) ? s.substr( 0, iMax / 2) + '[\u2026]' + Right(s, iMax / 2) : s;
}

function Left( s, n){
	if (n <= 0) {
	    return '';
	} else if (n > String(s).length){
	    return s;
	} else {
	    return String(s).substring(0, n);
	}
}
function Right( s, n){
    if (n <= 0) {
       return '';
    } else if (n > String(s).length) {
       return s;
    } else {
       var iLen = String(s).length;
       return String(s).substring(iLen, iLen - n);
    }
}

// Date
function date2timestamp( sFormat, value){
	var sPosD = sFormat.indexOf('d'),
		sPosM = sFormat.indexOf('m'),
		sPosY = sFormat.indexOf('y');
	var jour = value.substring( sPosD, sPosD + 2),
		mois = value.substring( sPosM, sPosM + 2),
		annee = value.substring( sPosY, sPosY + 4);
	return new Date( annee, mois, jour).getTime();
}

// syncho avec PHP
function format_html_id( s, sReplace) {
	sReplace = $defined(sReplace) ? sReplace : '';
	return s.replace(/^[^a-z_]+/i, sReplace).replace(/\W+/, sReplace);
}

// @see d_box_alert en php
function d_box_alert( options) {
	var o = $.extend({
		code: 'attention',
		text: '',
		id: 'box_alert'
	}, options);

	switch( o.code) {
		case 'attention': 			sCode = ' help-attention'; 		break;
		case 'information': 		sCode = ' help-information'; 	break;
		case 'critique': 			sCode = ' help-critique'; 		break;
		case 'interrogation': 		sCode = ' help-interrogation'; 	break;
		case 'formulaire-echec':	sCode = ' help-form-echec'; 	break;
		case 'formulaire-ok': 		sCode = ' help-form-ok'; 		break;
		default: sCode = '';
	}

	return '<div id="' + o.id + '" class="helpBoxInfos-ON ' + sCode + '">' + o.text + '</div>';
}

function alert_box( options) {
	var o = $.extend({
		 titre: '',
		 text: ''
	}, options);

	$('#dialog_alertBox').remove();
	$('body').append('<div id="dialog_alertBox" title="' + o.titre + '">' + o.text + '</div>');

	$('#dialog_alertBox').dialog({
		buttons: { "Ok": function() { $(this).dialog('close'); } },
		resizable: true,
		height: $('#dialog_alertBox').width(500).height() + 100,
		width: 500,
		modal: true,
		overlay: {
			opacity: 0.5,
			background: '#000'
		}
	});
}

// Events
function getEvent(e) { return e || window.event; }
function getSrcElement(e) { return	e.target || e.srcElement; }

function $redirect(sUrl, oWindow) {
	if ( !$defined(oWindow)) oWindow = window;
	if ( !$defined(sUrl) || sUrl == '' ) sUrl = oWindow.location;
	oWindow.location = sUrl;
}

function $defined(o) { return (o != undefined); }
function $is_true(t, v) { return $defined(t) ? t : v; }

function $type(o){
	if (!$defined(o)) return false; // non defini
	if (o.htmlElement) return 'element';
	var type = typeof o; // 'object', 'string', 'number', 'boolean', 'function'
	if (type == 'object' && o.nodeName){ // noeud
		switch(o.nodeType){
			case 1: return 'element'; // element
			case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
		}
	}
	if (type == 'object' || type == 'function'){
		switch(o.constructor){
			case Array: return 'array'; 	// tableau
			case RegExp: return 'regexp';	// expression
			//case Class: return 'class';		// class
		}
		if (typeof o.length == 'number'){
			if (o.item) return 'collection'; // childNodes, getElementsByTagName...
			if (o.callee) return 'arguments';// object argument
		}
	}
	return type;
}

function $id( s) {
	return (s) ? document.getElementById(s) : null;
}

function $insertCSS(url, sMedia) {
	$('head').append('<link rel="stylesheet" href="' + url + '" type="text/css" media="' + (sMedia || 'screen') + '" />');
}
function $insertScript(url) {
	$('head').append('<script src="' + url + '" type="text/javascript"></script>');
}

// tableau
function ArrayDedoublonne(aOrigine) {
	var bDoublon, j, k = 0, aTab = [];
	for ( var i = 0, length = aOrigine.length; i < length; i++ ) {
		bDoublon = false;
		for(j = 0; j < k && !bDoublon; j++) {
			if(aOrigine[i] === aTab[j]) {
				bDoublon = true;
			}
		}
		if(!bDoublon) {
			aTab[k++] = aOrigine[i];
		}
	}
	return aTab;
}

// recherche dichotomique si déjà trié sinon -> $.inArray
// bType (true = entier)
function ArrayRecherche_dicho(aOrigine, valeur, bType) {
	var trouve = -1, valTab, milieu = 0,
		debut = 0, // debut du tableau
		fin = aOrigine.length; // fin du tableau

	valeur = bType ? parseFloat(valeur) : valeur.toString();
	if(fin > 0) {
		while (trouve == -1) {
			milieu = Math.floor((debut + fin ) / 2);
			valTab = bType ? parseFloat(aOrigine[milieu]) : aOrigine[milieu].toString();
			if (valTab === valeur) {
				trouve = milieu;
			} else  {
				if (fin - debut <= 1) break;
				else {
				  if (valTab > valeur) fin = milieu;
				  else debut = milieu;
				}
			}
		}
	}
	return trouve;
}
// pour trier des nombres (croissant) : tab.sort(compare_num)
// tab.sort() (croissant) pour des chaines
function compare_num(a, b) { return a - b; }

// popup
var WindowPopupReference = null;
function popup(sURL, sNom, sOption, iW, iH, isCenter) {
//if(WindowPopupReference == null || WindowPopupReference.closed) {
	if (sOption == "all=yes") {
		sOption = 'directories=1,location=1,menubar=1,resizable=1,scrollbars=1,status=1,toolbar=1';
	}
	sOption += ((sOption != '') ? ',' : '') + 'width=' + iW + ',height=' + iH;
	if (window.screen && isCenter) {
		sOption += ',left=' + ((screen.width - iW) / 2) + ',top=' + ((screen.height - iH) / 2);
	}
	WindowPopupReference = window.open(sURL, sNom, sOption);
	WindowPopupReference.focus();
/*}
else
	WindowPopupReference.focus();*/
}

// DEBUG
function debug(text) {
	if (!window.top.dW || window.top.dW.closed) {
		showDebug();
	}
	window.top.dW.document.write(text + '\n');
}
function showDebug() {
	window.top.dW = window.open('', 'Debug', 'left=0,top=0,width=300,height=700,scrollbars=yes,status=yes,resizable=yes');
	window.top.dW.opener = self;
	window.top.dW.document.open();
	window.top.dW.document.write('<html><head><title>Debug</title></head><body><div align="right" onclick="if(wp = window.opener){wp.hideDebug();wp.showDebug();}">[ Reset ]</div><pre>\n');
}
function hideDebug() {
	if (window.top.dW && ! window.top.dW.closed) {
		window.top.dW.close();
		window.top.dW = null;
	}
}

/* Geolocalisation GOOGLE V3 */
var oGMAPV3_OPTION = null;
function gmapv3_async( option) {
	oGMAPV3_OPTION = option;
	$('#' + option.mapConteneur).addClass('ajaxloading_small');
	if( typeof google == 'undefined') {
		$insertScript( 'http://maps.google.com/maps/api/js?sensor=false&language=' + LANGUE_META_SITE + '&callback=gmapv3_init');
	} else {
		return gmapv3_init();
	}
}
function gmapv3_init( option) {
	var o = $defined(option) ? option : oGMAPV3_OPTION;
	return new oGmapv3( o).init();
}
function oGmapv3( option) { // return objet (sauf en async)
	this.o = $.extend({
		mapConteneur: null, // map
		mapH: 320,
		mapW: 'auto',
		mapLat:	46.5,
		mapLng:	2.4,
		mapTypeId: '',
		mapZoom: 5,
		aMarker: [], // [titre || title], [champLat, champLng]
		iwTpl: null,
		conteneur: null,
		rechercher: false,
		geolocMoi: false
	}, option);

	this.map = null;

	this.init = function() {
		var t = this;

		if( t.o.mapConteneur !== null && $id(t.o.mapConteneur)) {
			var oJQmapConteneur = $('#' + t.o.mapConteneur);

			if( t.o.conteneur !== null) {
				$('#' + t.o.conteneur).show();
			}
			oJQmapConteneur.removeClass('ajaxloading_small').css({ height: t.o.mapH, width: t.o.mapW});

			t.map = new google.maps.Map( $id(t.o.mapConteneur), {
				zoom: parseInt( t.o.mapZoom) || 5,
				center: new google.maps.LatLng( parseFloat( t.o.mapLat) || 46.5, parseFloat( t.o.mapLng) || 2.4),
				mapTypeId: google.maps.MapTypeId.ROADMAP,
				mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
				streetViewControl: true,
				scrollwheel: false
			});
			if( t.o.mapTypeId != '' && t.o.mapTypeId !== null) {
				t.map.setMapTypeId( t.o.mapTypeId);
			}

			t.genererMarkers();

			if( t.o.rechercher) {
				var geocoder = new google.maps.Geocoder();

				oJQmapConteneur
					.before('<label for="geomap_recherche_geocoding_' + t.o.mapConteneur + '" class="nomarge">' + _lg('Adresse&nbsp;:') + '</label>')
					.before( $('<input/>', {
							type: 'text',
							id: 'geomap_recherche_geocoding_' + t.o.mapConteneur,
							'class': 'mInput',
							'keypress': function(e) { // @#! IE
								if( e.which == 13) {
									$(this).next('input').click();
									return false;
								}
							}
						})
					).before( $('<input/>', {
						type: 'button',
						'class': 'small_btn',
						value: _lg('Rechercher'),
						click: function() {
							var sAdresse = $.trim( $('#geomap_recherche_geocoding_' + t.o.mapConteneur).val());
							if( sAdresse == '') {
								alert( _lg('Merci de renseigner le champ « adresse »'));
							} else {
								geocoder.geocode( { 'address': sAdresse }, function(results, status) {
									if( status == google.maps.GeocoderStatus.OK) {
										var oMarker = t.marker();
										oMarker.setPosition( results[0].geometry.location);
										t.map.setCenter( results[0].geometry.location);
										//t.map.setZoom(16);
										t.updateChamp( oMarker);
									} else {
										alert( _lg('La localisation a échouée.'));
									}
								});
							}
						}
					})
				);
			}
			if( t.o.geolocMoi && navigator.geolocation) {
				oJQmapConteneur.before( '<span/>').prev('span').append( $('<input/>', {
						type: 'button',
						'class': 'medium_btn',
						value: _lg('Géolocalisez-moi'),
						click: function() {
							var oBtn = $(this);
							oBtn.hide().closest('span').addClass('ajaxloading_small').css({ 'padding-left': oBtn.width()});
							navigator.geolocation.getCurrentPosition( function( position) {
								var oLatLng = new google.maps.LatLng( position.coords.latitude, position.coords.longitude),
									oMarker = t.marker();
								oMarker.setPosition( oLatLng);
								t.map.setCenter( oLatLng);
								//t.map.setZoom(5);
								t.updateChamp( oMarker);
								oBtn.show().parent().css({ padding:0 }).removeClass();
							}, function( errorcode) {
								oBtn.show().parent().css({ padding:0 }).removeClass();
							});
						}
					})
				);
			}
			return t;
		} else {
			return false;
		}
	};

	this.genererMarkers = function() {
		var t = this, iCount = t.o.aMarker.length;
		for( var i = 0; i < iCount; i++) {
			if( parseFloat(t.o.aMarker[i].lat) && parseFloat(t.o.aMarker[i].lng)) {
				var oMarker = new google.maps.Marker({
					position: new google.maps.LatLng( parseFloat(t.o.aMarker[i].lat), parseFloat(t.o.aMarker[i].lng)),
					map: t.map,
					title: t.o.aMarker[i].titre || t.o.aMarker[i].title || '',
					draggable: t.o.aMarker[i].draggable || false,
					champLat: t.o.aMarker[i].champLat || '',
					champLng: t.o.aMarker[i].champLng || ''
				});
				if( t.o.aMarker[i].draggable) {
					google.maps.event.addListener( oMarker, 'dragend', function() {
						t.map.setCenter( oMarker.position);
						t.updateChamp( oMarker, oMarker.position.lat(), oMarker.position.lng());
					});
				}

				// evite d'écraser des propriétés
				t.o.aMarker[i].marker = oMarker;

				if( $.isFunction(t.o.iwTpl)) {
					var oInfoWindow = new google.maps.InfoWindow({
						content: t.o.iwTpl( t.o.aMarker[i])
					});
					google.maps.event.addListener(oMarker, 'click', t.openInfoWindow( oInfoWindow, oMarker));
				}
			}
		}
	};

	this.updateChamp = function( oMarker) {
		if(	oMarker.champLat != '') { $('#' + oMarker.champLat).val( oMarker.position.lat()); }
		if(	oMarker.champLng != '') { $('#' + oMarker.champLng).val( oMarker.position.lng()); }
	};

	this.openInfoWindow = function(oInfoWindow, oMarker) {
		return function() {
			//var map = oMarker.getMap();
			// Fermer la dernière bulle ouverte avant d'ouvrir celle demandé
			if (this.map.visibleInfoWindow) {
				this.map.visibleInfoWindow.close();
			}
			oInfoWindow.open(this.map, oMarker);
			this.map.visibleInfoWindow = oInfoWindow;
		};
	};

	this.repereId = function( oRepere, bId) {
		for( var i = 0, iCount = this.o.aMarker.length; i < iCount; i++) {
			if ( this.o.aMarker[i] !== null) {
				if ( this.o.aMarker[i].marker == oRepere) {
					return $is_true( bId, true) ? this.o.aMarker[i] : i;
				}
			}
		}
		return $is_true( bId, true) ? null : 0;
	};

	this.marker = function( iIndex) {
		var iId = parseInt(iIndex) ? iIndex : 0;
		return this.o.aMarker[iId].marker || 0;
	};
}
