// encoding="UTF-8"

/*
 *	Web Basic Services (WBS) is a framework that proposes simple solutions using popular free softwares for usual web features.
 *	Copyright (C) 2009 Vincent Adelé
 *	
 *	This file is part of WBS.
 *	
 *	WBS is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.
 *	
 *	WBS is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *	GNU General Public License for more details.
 *	
 *	You should have received a copy of the GNU General Public License
 *	along with WBS. If not, see <http://www.gnu.org/licenses/>.
 */

// Ajout d'un event
wbsAddEventListener = function( object, eventType, eventCallback, useCapture ) {
	
	// Valeurs par défaut
	if( 'undefined' == typeof useCapture ) {
		useCapture = false;
	}
	
	//setup onload function
	if( typeof object.addEventListener != 'undefined' ) {	//.. gecko, safari, konqueror and standard
			
		return object.addEventListener( eventType, eventCallback, useCapture );
	} else if( typeof object.attachEvent != 'undefined' ) {	//.. win/ie
		return object.attachEvent( 'on'+eventType, eventCallback );
	} else {
		//if there's an existing onload function
		eval( 'var eventPrevious = this.on'+eventType );
		if( typeof eventPrevious == 'function' ) {
			//add new onload handler
			eval( 'this.on'+eventType+' = function( event ) { eventPrevious( event ); return eventCallback( event ); };' );
		} else {
			//setup onload function
			eval( 'this.on'+eventType+' = eventCallback;' );
		}
		return true;
	}
	
	return false;
}

// Application de la methode innerHTML avec execution des scripts et des styles (non enregistres par IE en standard)
// Les scripts doivent declarer les fonctions "window.maFunction=function() { ... }" et non pas "function maFunction() { ... }".
wbsSetInnerHTML = function( object, content ) {
	
	// Securite
	if( !content ) {
		content = '';
	}
	
	var result = true;
	
	// Utilisation de la methode standard
	object.innerHTML = content;
	
	// Gestion des scripts
	try {
		var scripts = content.getElementsByTagName( "script" );
		wbsMap(
			scripts,
			function( scriptContent ) {
				// Recherche de la source
				// Suppression des commentaires HTML
				var tagRegExp = new RegExp( '<script(?:\\s+(?!src)\\w+=(?:"[^"]*"|\'[^\']*\'))*(?:\\s+src=(?:"([^"]*)"|\'([^\']*)\'))?(?:\\s+\\w+=(?:"[^"]*"|\'[^\']*\'))*\\s*>\\s*(?:<!--)?\\s*([\\S\\s]*)\\s*</script\\s*>', 'im' );
				var matches = scriptContent.match( tagRegExp );
				if( !matches ) {
					return false;
				}
				// Execution du script
				if( matches[1] ) {
					wbsInclude( matches[1] );
				}
				if( matches[2] ) {
					wbsInclude( matches[2] );
				}
				if( matches[3] ) {
					eval( matches[3] );
				}
				return true;
			}
		)
	} catch( exception ) {
		result = false;
	}
	
	// Gestion des styles
	try {
		var styles = content.getElementsByTagName( "style" );
		wbsMap(
			styles,
			function ( styleContent ) {
				var styleSheet = object.createStyleSheet();
				styleSheet.cssText=styleContent;
				styleSheet.enabled=true;
			},
			true
		)
	} catch( exception ) {
		result = false;
	}
	
	return result;
}

// Inclusion de fichier JS
wbsInclude = function( filename ) {
	
	var script = document.createElement("script");
	script.type = "text/javascript";
	script.src = filename;
	
	var head = document.getElementsByTagName('head')[0];
	head.appendChild( script );
}

// Extraction du contenu de balise
String.prototype.getElementsByTagName = function( tagName ) {
	
	var tagStart = '<'+tagName+'(?:\\s+\\w+=(?:"[^"]*"|\'[^\']*\'))*\\s*>';
	var tagEnd = '</'+tagName+'\\s*>';
	var contentWithoutTag = '(?:(?!(?:'+tagStart+'|'+tagEnd+'))[\\S\\s])*';
	var tagRegExpAll = new RegExp( tagStart+'(?:'+contentWithoutTag+'|'+tagStart+contentWithoutTag+tagEnd+')*'+tagEnd, 'img' );
	
	var matches = this.match( tagRegExpAll );
	if( !matches ) {
		return new Array();
	}
	return matches;
}

// Exécute une fonction sur un tableau et renvoie un tableau contenant le résultat la fonction pour chaque élément du tableau d'entré.
wbsMap = function( object, callback ) {
	
	var results = new Array();
	var result = null;
	for( var index=0; index<object.length; index++ ) {
		result = null;
		try {
			result = callback( object[index] ) ;
		} catch( viaEx ) {}
		results.push( result );
	}
	
	return results;
}

// Retourne la largeur de la fenêtre
wbsWindowWidth = function() {
	
	var windowWidth = 0;
	if( 'number' == typeof window.innerWidth ) {
		// Non-IE
		windowWidth = window.innerWidth;
	} else if( document.documentElement && document.documentElement.clientWidth ) {
		// IE 6+ in "standards compliant mode"
		windowWidth = document.documentElement.clientWidth;
	} else if( document.body && document.body.clientWidth ) {
		// IE 6+ in "standards compliant mode"
		windowWidth = document.body.clientWidth;
	}
	
	return windowWidth;
}

// Retourne la hauteur de la fenêtre
wbsWindowHeight = function() {
	
	var windowHeight = 0;
	if( 'number' == typeof window.innerHeight ) {
		// Non-IE
		windowHeight = window.innerHeight;
	} else if( document.documentElement && document.documentElement.clientHeight ) {
		// IE 6+ in "standards compliant mode"
		windowHeight = document.documentElement.clientHeight;
	} else if( document.body && document.body.clientHeight ) {
		// IE 6+ in "standards compliant mode"
		windowHeight = document.body.clientHeight;
	}
	
	return windowHeight;
}

// Agrandit un élément à la taille de la fenêtre.
// La position courante de l'objet est sauvegardée en vue de la restauration.
wbsMaximize =  function( object ) {
	
	// Récupération de la sauvegarde
	if( !object.wbsMaximizeSave ) {
		object.wbsMaximizeSave = new Array();
	}
	var save = object.wbsMaximizeSave;
	
	// Sauvegarde
	save.parentNode = object.parentNode;
	save.style = new Array();
	save.style.position = object.style.position;
	save.style.top = object.style.top;
	save.style.right = object.style.right;
	save.style.bottom = object.style.bottom;
	save.style.left = object.style.left;
	save.style.width = object.style.width;
	save.style.height = object.style.height;
	
	// Agrandissement
	object.parentNode.removeChild( object );
	var body = document.getElementsByTagName( 'body' )[0];
	body.appendChild( object );
	object.style.position = 'fixed';
	object.style.top = '0px';
	object.style.left = '0px';
	object.style.width = wbsWindowWidth()+'px';
	object.style.height = wbsWindowHeight()+'px';
		
	return true;
}
// Restaure un élément après agrandissement.
// Si aucun agrandissement n'a été fait, cela n'a pas d'effet.
wbsRestore =  function( object ) {
	
	// Récupération de la sauvegarde
	if( !object.wbsMaximizeSave ) {
		return false;
	}
	var save = object.wbsMaximizeSave;
	
	// Restauration
	object.parentNode.removeChild( object );
	save.parentNode.appendChild( object );
	object.style.position = save.style.position;
	object.style.top = save.style.top;
	object.style.right = save.style.right;
	object.style.bottom = save.style.bottom;
	object.style.left = save.style.left;
	object.style.width = save.style.width;
	object.style.height = save.style.height;
	
	return true;
}

window.location.splitSearch = 
String.prototype.splitSearch = function()
{
	var params = new Array();
	var search;
	
	// Suppression du '?' sur les parametres courant.
	if ('?'==this.charAt(0)) {
		search = this.substr( 1, this.length-1 );
	} else {
		search = this;
	}
	if( 0==search.length ) {
		return params;
	}
	
	// Découpage en param/value
	var param;
	var value;
	var pair;
	var chunks = search.split( '&' );
	for( var index=0; index<chunks.length; index++ ) {
		pair = chunks[index].split( '=' );
		param = pair.shift();
		if( 0==param.length ) {
			continue;
		}
		if( 0<pair.length ) {
			value = pair.join();
		} else {
			value = null;
		}
		// Ajout au résultat
		params[param] = value;
	}
	
	return params;
}

// Ajoute ou remplace un paramètre de l'URI
window.location.updateSearch = function( newSearch ) {
	
	// Cas particuliers
	if( 0==newSearch.length ) {
		// On utilise la réaffectation plutot que la méthode reload pour éviter des anomalies dû à l'éventuelle différence de comportement de certains navigateur.
		this.search = this.search;
		return;
	}
	
	var currentParams = currentSearch.splitSearch();
	var newParams = newSearch.splitSearch();
	
	// Fusion
	for(var param in newParams) {
		currentParams[param] = newParams[param];
	}
	
	// Reconstruction
	var results = new Array();
	for( var param in currentParams ) {
		if( null!=currentParams[param] ) {
			results.push( param+'='+currentParams[param] );
		} else {
			results.push( param );
		}
	}
	this.search = results.join( '&' );
	return;
}
