var tools_fades = new Array();
var tools_clickSourceId = "";


// Vérifie la validité de l'email passé en paramètre
function Tools_IsValidEmail(email)
{
	return /^(([a-z0-9])+([\w\.\-]))*([a-z0-9])+\@(([a-z0-9])+([\w\.\-]))*([a-z0-9])+\.([a-z]{2,4})$/i.test(email);
}

function Tools_QuantifiableToString(items)
{
	var s = ''
	if (items)
	{
		var valueSeparator = '|', quantitySeparator  = '-';
		for (var i = 0; i < items.length; i++)
		{
			var item = items[i];
			if (s.length > 0)
				s += valueSeparator;

			if (!item.Quantity || (item.Quantity && item.Quantity > 0))
			{
				s += item.Id;
				if (item.Quantity && item.Quantity > 1)
					s += quantitySeparator + item.Quantity;
			}
		}
	}		
	return s;
}

function Tools_ArrayIndexOfAny(array, comparer)
{
	if (array && comparer)
	{
		for (var i = 0; i < array.length; i++)
			if (comparer(array[i]))
				return i;
		return -1;
	}
}

function Tools_ArrayIndexOf(array, item)
{
	if (array && item)
	{
		for (var i = 0; i < array.length; i++)
			if (array[i] == item)
				return i;
		return -1;
	}
}

function Tools_ArrayIndexOf_ById(array, itemId)
{
	if (array && itemId)
	{
		for (var i = 0; i < array.length; i++)
			if (array[i].Id == itemId)
				return i;
		return -1;
	}
}

function Tools_ArrayRemove(array, item)
{
	if (array && item)
	{
		var index = Tools_ArrayIndexOf(array, item);
		if (index != -1)
			array.splice(index, 1);
	}
}

function Tools_ArrayRemove_ById(array, itemId)
{
	if (array && itemId)
	{
		var index = Tools_ArrayIndexOf_ById(array, itemId);
		if (index != -1)
			array.splice(index, 1);
	}
}


function Tools_GetUrl(urlRoot, params)
{
	var url = urlRoot + "?";
	for (var key in params)
	{
		var value = params[key];
		if (typeof (value) != "undefined" && value != null)
			url += "&" + key + "=" + value;
	}
	return url.replace("?&", "?");
}

function Tools_RemoveChildren(node)
{
	if (node != null)
		while (node.hasChildNodes())
			node.removeChild(node.firstChild);
}


// Ajoute une action une fois que la page est chargee
function Tools_AddLoadEvent(func)
{
	var oldonload = window.onload;
	if (typeof window.onload != 'function')
		window.onload = func;
	else
	{
		window.onload = function()
		{
			if (oldonload)
				oldonload();
			func();
		}
	}
}

function Tools_IsNumeric(s, allowDecimal, allowNegative)
{
	if (allowDecimal)
	{
		if (allowNegative)
			return /^(-)?(\d+)(\.?)(\d*)$/.test(s);
		return /^(\d*)(\.?)(\d*)$/.test(s);
	}
	else
	{
		if (allowNegative)
			return /^(-)?(\d+)$/.test(s);
		return /^(\d+)$/.test(s);
	}
}

function Tools_GetPosition(obj)
{
	var top = 0, left = 0;
	while (obj != null)
	{
		top += obj.offsetTop;
		if (obj.style)
		{
			top += Tools_ParseInt(obj.style.marginTop, 0);
			top += Tools_ParseInt(obj.style.marginBottom, 0);
		}
		left += obj.offsetLeft;
		if (obj.style)
		{
			left += Tools_ParseInt(obj.style.marginLeft, 0);
			left += Tools_ParseInt(obj.style.marginRight, 0);
		}
		obj = obj.offsetParent;
	}
	return { Top: top, Left: left };
}

function Tools_ForEach(array, action)
{
	if (array != null)
		for (var i = 0; i < array.length; i++)
			action(array[i]);
}

function Tools_ParseInt(s, defaultValue)
{
	if (Tools_IsNullOrEmpty(s))
		return defaultValue;

	var result;
	try { result = parseInt(s); }
	catch (ex) { return defaultValue; }
		
	return isNaN(result) ? defaultValue : result;
}

function Tools_ParseFloat(s, defaultValue)
{
	if (Tools_IsNullOrEmpty(s))
		return defaultValue;

	var result;
	try { result = parseFloat(s); }
	catch (ex) { return defaultValue; }
		
	return isNaN(result) ? defaultValue : result;
}

// Permet de récupérer un objet flash
// dans la page à partir de son nom
function Tools_GetFlashObject(name)
{
	var flash = window.document[name];
	if ((flash == null) && (window.document.embeds != null))
		flash = window.document.embeds[name];
	return flash;
}

function Tools_GetEventSender(e)
{
	var target = null;
	if (e.target)
		target = e.target;
	else if (e.srcElement)
		target = e.srcElement;
	if (target.nodeType == 3) // defeat Safari bug
		target = target.parentNode;
	return target;
}

function Tools_AddEventHandler(handlers, handler)
{
	if (handlers != null)
		handlers.push(handler);
}

function Tools_DispatchEvent(handlers, sender, argument)
{
	if (handlers != null)
		for (var i = 0; i < handlers.length; i++)
			handlers[i](sender, argument);
}



function Tools_Min(a, b)
{
	var c = a ? a : 0;
	var d = b ? b : 0;
	return (c < d) ? a : b;
}

function Tools_Max(a, b)
{
	var c = a ? a : 0;
	var d = b ? b : 0;
	return (c > d) ? a : b;
}

function Tools_Clone(obj)
{
	if ((typeof(obj) != 'object') || (obj == null))
		return obj;

	var clone = new Object();
	for (var i in obj)
		clone[i] = Tools_Clone(obj[i]);
	return clone;
}

function Tools_ToString(obj)
{
	var s = "";
	for (var property in obj)
	{
		if (s.length > 0)
			s += ", ";
		s += property + " = " + obj[property];
	}
	return s;
}

function Tools_UseExtensions()
{
	Tools_UseExtension_StringFormat();
	Tools_UseExtension_ArrayFilter();
	Tools_UseExtension_ArrayMap();
	Tools_UseExtension_ArrayReduce();
	Tools_UseExtension_ArrayGroupBy();
	Tools_UseExtension_ArrayForEach();
	Tools_UseExtension_ArrayClone();
	Tools_UseExtension_ArrayIndexOf();
	Tools_UseExtension_ArrayContains();
}


function Tools_UseExtension_StringFormat()
{
	String.prototype.format = function()
	{
		var str = this;
		for (var i = 0; i < arguments.length; i++)
		{
			var re = new RegExp('\\{' + (i) + '\\}', 'gm');
			str = str.replace(re, arguments[i]);
		}
		return str;
	}
}

function Tools_IsSubsetOf(a, b)
{
	if (b == null)
		return false;
	for (var key in a)
		if (a[key] != b[key])
			return false;
	return true;
}

// Ajoute la méthode filter sur Array
function Tools_UseExtension_ArrayFilter()
{
	if (!Array.prototype.filter)
	{
		Array.prototype.filter = function(fun /*, thisp*/)
		{
			var len = this.length;
			if (typeof fun != "function")
				throw new TypeError();

			var res = new Array();
			var thisp = arguments[1];
			for (var i = 0; i < len; i++)
			{
				if (i in this)
				{
					var val = this[i]; // in case fun mutates this
					if (fun.call(thisp, val, i, this))
						res.push(val);
				}
			}

			return res;
		};
	}
}

// Ajoute la méthode map sur Array
function Tools_UseExtension_ArrayMap()
{
	if (!Array.prototype.map)
	{
		Array.prototype.map = function(fun /*, thisp*/)
		{
			var len = this.length;
			if (typeof fun != "function")
				throw new TypeError();

			var res = new Array(len);
			var thisp = arguments[1];
			for (var i = 0; i < len; i++)
			{
				if (i in this)
					res[i] = fun.call(thisp, this[i], i, this);
			}

			return res;
		};
	}
}

function Tools_UseExtension_ArrayReduce()
{
	if (!Array.prototype.reduce)
	{
		Array.prototype.reduce = function(fun /*, initial*/)
		{
			var len = this.length;
			if (typeof fun != "function")
				throw new TypeError();
			// no value to return if no initial value and an empty array
			if (len == 0 && arguments.length == 1)
				throw new TypeError();

			var i = 0;
			if (arguments.length >= 2)
			{
				var rv = arguments[1];
			}
			else
			{
				do
				{
					if (i in this)
					{
						rv = this[i++];
						break ;
			        }

					// if array contains no values, no initial value to return
					if (++i >= len)
						throw new TypeError();
				}
				while (true);
			}

			for (; i < len; i++)
			{
				if (i in this)
					rv = fun.call(null, rv, this[i], i, this);
		    }

			return rv;
		};
	}
}

function Tools_UseExtension_ArrayGroupBy()
{
	if (!Array.prototype.groupBy)
	{
		Array.prototype.groupBy = function(callback)
		{
			var length = this.length;
			var groups = [];
			var keys = {};
			for (var index = 0; index < length; index++)
			{
				var key = callback(this[index], index);
				if (!key || !key.length)
					continue;
				var items = keys[key];
				if (!items)
				{
					items = [];
					items.key = key;
					keys[key] = items;
					groups.push(items);
				}
				items.push(this[index]);
			}
			return groups;
		}
	}
}


function Tools_UseExtension_ArrayForEach()
{
	if (!Array.prototype.forEach)
	{
		Array.prototype.forEach = function(fun /*, thisp*/)
		{
			var len = this.length;
			if (typeof fun != "function")
				throw new TypeError();

			var thisp = arguments[1];
			for (var i = 0; i < len; i++)
			{
				if (i in this)
					fun.call(thisp, this[i], i, this);
			}
		};
	}
}

function Tools_UseExtension_ArrayClone()
{
	if (!Array.prototype.clone)
	{
		Array.prototype.clone = function()
		{
			var length = this.length;
			var array = new Array(length);
			for (var index = 0; index < length; index++)
				array[index] = this[index];
			return array;
		};
	}
}

function Tools_UseExtension_ArrayIndexOf()
{
	if (!Array.prototype.indexOf)
	{
		Array.prototype.indexOf = function(elt /*, from*/)
		{
			var len = this.length;

			var from = Number(arguments[1]) || 0;
			from = (from < 0)
				? Math.ceil(from)
				: Math.floor(from);
			if (from < 0)
			from += len;

			for (; from < len; from++)
			{
			if (from in this &&
				this[from] === elt)
				return from;
			}
			return -1;
		};
	}
}

function Tools_UseExtension_ArrayContains()
{
	if (!Array.prototype.contains)
	{
		Array.prototype.contains = function(item)
		{
			return (this.indexOf(item) != -1);
		};
	}
}


function Tools_ShowLayerPopup(id, value)
{
	Tools_EnableScrollBars(!value);
	
	if (value)
	{
		Tools_CenterMessageLayer(id);
		
		// On redimensionne le masque gris pour qu'il ait la même taille que le body
		var mask = document.getElementById("gli_mask");
		if (mask != null && document.body)
		{
			mask.style.width = Tools_GetWindowWidth() + "px";
			mask.style.height = Tools_GetWindowHeight() + "px";
		}
				
		Tools_MoveToTop("gli_mask");
	}
	
	Tools_Show("gli_mask", value);
	Tools_Show(id, value);
	return false;
}

function Tools_MoveToTop(id)
{
	var obj = document.getElementById(id);
	obj.style.top = document.body.scrollTop;
}

function Tools_CenterMessageLayer(id)
{
	var obj = document.getElementById(id);
	if (obj == null)
		return ;
	
	// On retrouve le bon layer
	var divs = obj.getElementsByTagName("div");
	for (var i = 0; i < divs.length; i++)
	{
		var div = divs[i];
		if (div.className.indexOf("globalLayerInfosInt") != -1)
		{
			obj.style.left = (Tools_GetWindowWidth() - 300) / 2 + "px";	/* div.clientWidth */
			obj.style.top = document.body.scrollTop + ((Tools_GetWindowHeight() - 300) / 2) + "px";	/* div.clientHeight */
			return ;
		}
	}
}

function Tools_EnableScrollBars(value)
{
	var overflow = value ? "" : "hidden";

	// Le body
	document.body.style.overflow = overflow;

	// La root du document HTML
	if (document.documentElement)
		document.documentElement.style.overflow = overflow

	// Le tag HTML principal de la page (IE7)
	var html = Tools_GetHtmlTag();
	if (html != null)
		html.style.overflow = overflow;
}

function Tools_GetHtmlTag()
{
	var htmls = document.getElementsByTagName("html");
	if (htmls.length > 0)
		return htmls[0];
	return null;
}

function Tools_GetWindowWidth()
{
	// Non-IE
	if (typeof (window.innerWidth) == 'number')
		return window.innerWidth;
	
	// IE 6+ in 'standards compliant mode'
	if (document.documentElement && document.documentElement.clientWidth)
		return document.documentElement.clientWidth;
	
	// IE 4 compatible
	if (document.body && document.body.clientWidth)
		return document.body.clientWidth;
}

function Tools_GetWindowHeight()
{
	// Non-IE
	if (typeof (window.innerHeight) == 'number')
		return window.innerHeight;
	
	// IE 6+ in 'standards compliant mode'
	if (document.documentElement && document.documentElement.clientHeight)
		return document.documentElement.clientHeight;
	
	// IE 4 compatible
	if (document.body && document.body.clientHeight)
		return document.body.clientHeight;
}

function Tools_GetComputedStyle(id)
{
	var obj = document.getElementById(id);
	if (obj == null)
		return null;
		
	// IE 
	if (obj.currentStyle)
		return obj.currentStyle;

	// Firefox
	return document.defaultView.getComputedStyle(obj, null); 
}

function Tools_Smooth(t)
{
	// return 0.5 + Math.sin((t - 0.5) * Math.PI) * 0.5; --> ???
	return Math.sin(t * Math.PI * 0.5);
}


function Tools_DisableSelection(object)
{
	if (typeof object.onselectstart != "undefined") // IE
		object.onselectstart = function() { return false; }
	else if (typeof (object.style.MozUserSelect) != "undefined") // FF
		object.style.MozUserSelect = "none";
	else // Opera
		object.onmousedown = function() { return false; }
	object.style.cursor = "hand";
}


function Tools_FireClickEvent(object)
{
	if (object == null)
		return false;

	if (Tools_IsNullOrEmpty(object.click))
	{
		var result;
		if (Tools_IsNullOrEmpty(object.onclick) == false)
			result = object.onclick()
		
		if (object.tagName.toLowerCase() == "a")
		{
			// Attention, le != false est important car "undefined" doit passer...
			if ((result != false) && (object.href != null))
			{
				var href = object.href.toLowerCase();
				if (href.indexOf("javascript:") == 0)
					eval(object.href.substring(href.indexOf(":") + 1));
				else
					window.location = object.href;
			}
			return result;
		}
		else
		{
			if (Tools_IsNullOrEmpty(object.onclick) == false)
				return result;

			var evt = document.createEvent("MouseEvents");
			evt.initMouseEvent("click", true, true, document.defaultView,
				1, 0, 0, 0, 0, false, false, false, false, 0, null);
			return object.dispatchEvent(evt);
		}
	}
	else
		return object.click();
}


function Tools_Absolute(value)
{
	return (value > 0) ? value : -value;
}


function Tools_Contains(array, value)
{
	return (Tools_IndexOf(array, value) != -1);
}

function Tools_IndexOf(array, value)
{
	if (array != null)
		for (var i = 0; i < array.length; i++)
			if (array[i] == value)
				return i;
	return -1;
}


function Tools_EndsWith(s, end)
{
	if (Tools_IsNullOrEmpty(s) || (s.length < end.length))
		return false;
	return (end == s.substr(s.length - end.length, end.length));
}

function Tools_GetQueryParams(querystring, keepEncoding)
{
	var query = querystring ? querystring : location.search.substring(1);
	if (Tools_IsNullOrEmpty(query) == false)
	{
		var index = query.indexOf('?');
		if (index != -1)
			query = query.substring(index + 1);
	}
	return Tools_ParseValues(query, '&', '=', keepEncoding);
}


function Tools_ParseValues(toParse, varSeparator, valueSeparator, keepEncoding)
{
	var values = new Object();
	var pairs = toParse.split(varSeparator);
	for (var i = 0; i < pairs.length; i++)
	{
		var pos = pairs[i].indexOf(valueSeparator);
		if (pos < 0)
			continue ;
		var name = pairs[i].substring(0, pos);
		var value = pairs[i].substring(pos + 1);
		values[name] = keepEncoding ? value : decodeURI(value);
	} 
	return values;
}

function Tools_PerformClick(objectId)
{
	if (tools_clickSourceId == objectId)
		return false;


	tools_clickSourceId = objectId;
	var obj = document.getElementById(objectId);
	if (obj == null)
		return false;
	
	var result = Tools_FireClickEvent(obj);
	tools_clickSourceId = "";
	return result;
}

function Tools_IsNullOrEmpty(s)
{
	if (typeof (s) == "undefined" || !s)
		return true;
	if (typeof (s) == "string" && s.match(/^(\s)*$/))
		return true;
	return false;
}

function Tools_SetVisibility(id, visible)
{
	var obj = document.getElementById(id);
	if (obj != null)
		obj.style.visibility = visible ? "visible" : "hidden";
}

function Tools_Show(id, show)
{
	var obj = document.getElementById(id);
	if (obj != null)
		obj.style.display = show ? "block" : "none";
}


function Tools_Trim(s)
{
	return s.replace(/^\s+|\s+$/g, '');
}


function Tools_SelectByClass(obj, className)
{
	if (obj != null && obj.childNodes.length > 0)
		for (var i = 0; i < obj.childNodes.length; i++)
			if (obj.childNodes[i].className == className)
				return obj.childNodes[i];
	return null;
}


function Tools_SetHtml(id, html)
{
	var obj = document.getElementById(id);
	if (obj != null)
		obj.innerHTML = html;
}


function Tools_CreateGuid()
{
	return 'g' + Math.ceil(Math.random() * 10000)
		 + '-' + Math.ceil(Math.random() * 10000)
		 + '-' + Math.ceil(Math.random() * 10000)
		 + '-' + Math.ceil(Math.random() * 10000);
}

function Tools_SetAlpha(id, value)
{
	var obj = document.getElementById(id);
	if (obj != null)
	{
		var style = obj.style;
		style.opacity = (value / 100); 
		style.MozOpacity = (value / 100); 
		style.KhtmlOpacity = (value / 100); 
		style.filter = "alpha(opacity=" + value + ")"; 
	}	
}


function Tools_Fade(id, start, end, onEnd, speed)
{ 
	if (!speed)
		speed = 7;
	var step = (start < end) ? 1 : -1;
	var timer = 0;

	var fadeId = Tools_CreateGuid();
	tools_fades[id] = fadeId;
	for (var i = start; i != end; i += step)
	{ 
		// On doit vérifier qu'il n'y a pas deux fondus simultanés sur le même objet
		var check = "if (tools_fades['" + id + "'] == '" + fadeId + "')";
		setTimeout(check + "Tools_SetAlpha('" + id + "', " + i + ")", timer * speed); 
		timer++;
	}
	
	// Optionnel: Permet de faire une action quand le fondu est fini
	if (onEnd)
		setTimeout(onEnd, timer * speed);
}

function Tools_GetChildrenByTagName(obj, tagName)
{
	var children = new Array();
	if (obj != null && obj.children)
		for (var i = 0; i < obj.children.length; i++)
			if (obj.children[i].tagName.toLowerCase() == tagName)
				children.push(obj.children[i]);
	return children;
}

function Tools_FindByClass(obj, tagName, className)
{
	if (obj != null && Tools_IsNullOrEmpty(tagName) == false && Tools_IsNullOrEmpty(className) == false)
	{
		var tags = obj.getElementsByTagName(tagName);
		for (var i = 0; i < tags.length; i++)
			if (tags[i].className == className)
				return tags[i];
	}
	return null;
}


function Tools_FindAllByClass(obj, tagName, className)
{
	var list = new Array();
	if (obj != null && Tools_IsNullOrEmpty(tagName) == false && Tools_IsNullOrEmpty(className) == false)
	{
		var tags = obj.getElementsByTagName(tagName);
		for (var i = 0; i < tags.length; i++)
			if (tags[i].className == className)
				list.push(tags[i]);
	}
	return list;
}

function Tools_FindByClasses(obj, tagName, classNames)
{
	if (obj != null && Tools_IsNullOrEmpty(tagName) == false && classNames != null && classNames.length > 0)
	{
		var tags = obj.getElementsByTagName(tagName);
		for (var i = 0; i < tags.length; i++)
			for (var j=0; j<classNames.length; j++)
				if (tags[i].className == classNames[j])
					return tags[i];
	}
	return null;
}


function Tools_FindAllByClasses(obj, tagName, classNames)
{
	var list = new Array();
	if (obj != null && Tools_IsNullOrEmpty(tagName) == false && classNames != null && classNames.length > 0)
	{
		var tags = obj.getElementsByTagName(tagName);
		for (var i = 0; i < tags.length; i++)
		{
			for (var j=0; j<classNames.length; j++)
			{
				if (tags[i].className == classNames[j])
				{
					list.push(tags[i]);
					break;
				}
			}
		}
	}
	return list;
}

// Synchronise les largeurs des cellules entre 2 tableaux
function Tools_SynchronizeCellsWidth(firstTableId, secondTableId)
{
	var header = document.getElementById(firstTableId);
	var mainTable = document.getElementById(secondTableId);
	if (header != null && mainTable != null)
	{
		var headerBody = Tools_GetChildrenByTagName(header, "tbody")[0];
		var headerRows = Tools_GetChildrenByTagName(headerBody, "tr");
		var headerCells = Tools_GetMaxCells(headerRows);
		if ((headerCells != null) && (headerCells.length > 0))
		{
			var mainBody = Tools_GetChildrenByTagName(mainTable, "tbody")[0];
			var rows = Tools_GetChildrenByTagName(mainBody, "tr");
			var cells = Tools_GetMaxCells(rows);
			if (cells != null && cells.length == headerCells.length)
				for (var i = 0; i < headerCells.length; i++)
					cells[i].style.width = headerCells[i].offsetWidth + "px";
		}
	}
}

// Retourne les cellules de la ligne qui en a le plus
function Tools_GetMaxCells(rows)
{
	var max = null;
	if ((rows != null) && (rows.length > 0))
		for (var i = 0; i < rows.length; i++)
		{
			var cells = Tools_GetChildrenByTagName(rows[i], "td");
			if (max == null || max.length < cells.length)
				max = cells;
		}
	return max;
}

function Tools_Default(s, defaultValue)
{
	return Tools_IsNullOrEmpty(s) ? defaultValue : s;
}


// Essaie de retrouver les différentes parties d'un URL et
// retourne un objet avec les propriétés "Root" et "Params".
// Dans "Root" on retrouve l'URL racine (ie. sans la QueryString) et
// dans "Params" on retrouve tous les paramètres de la QueryString.
// Si l'URL passé en paramètre est pourri ca retourne null.
function Tools_ParseUrl(url)
{
	if (!url)
		return null;

	var queryStart = url.indexOf('?');
	if (queryStart < 0)
		return { Root: url, Params: null };
	
	return { Root: url.substring(0, queryStart),
		Params: Tools_GetQueryParams(url.substring(queryStart + 1)) };
}



