/******Méthode permettant de dupliquer un objet******/
Object.duplicate=function(oSrc,bDeep) {
	var objectClone;
	if(oSrc.constructor==undefined){
		objectClone=new Object();
	}
	else{
		objectClone = new oSrc.constructor();
	}
	for (var property in oSrc) {
		if (!bDeep)
			objectClone[property] = oSrc[property];
		else if (typeof oSrc[property] == 'object')
			objectClone[property] = Object.duplicate(oSrc[property],bDeep);
		else
			objectClone[property] = oSrc[property];
	}
	return objectClone;
}

// object SE
var SE = {
	Config: {
		"loggerAutoVanish": false,
		"debug": false,
		"warning": true,
		"error": true,
		"showRequestSection": false,
		"showRequestCriterion": false,
		"drawOnStartup": false,
		"glossaryTooltipTimeout": 20,
		"comparatorMaxProducts": 4,
		"comparatorLink1": "lien_comparateur_1",
		"comparatorLink2": "lien_comparateur_2",
		"pagination": {
			"nRestultsPerPage": 10
		},
		"message": {
			"addCriterion": "ajouter ce crit\u00E8re",
			"removeCriterion": "supprimer ce crit\u00E8re",
			"emptyRequest": "faites votre choix de crit\u00E8res",
			"clearRequest": "Supprimer les crit\u00E8res",
			"emptyResult": "aucun produit n'a ete trouv\u00E9",
			"closeGlossaryTooltip": "fermer l'aide contextuelle"
		},
		"gif": {
			"spinner": "../img/B2C/common/spinner.gif",
			"arrow1": "../img/B2C/common/arrow-red1.gif",
			"arrow2": "../img/B2C/common/arrow-red2.gif",
			"arrow3": "../img/B2C/common/arrow-black-down.gif",
			"arrow4": "../img/B2C/common/arrow-black-right.gif",
			"remove": "../img/B2C/common/remove_criter.gif",
			"help": "../img/B2C/common/picto_interro.gif",
			"closeGlossaryTooltip": "../img/B2C/common/remove_criter.gif"
		},
		"url": {
//			"catalogueGlossary": "../xml/glossary-%SECTIONID%.xml",
			"catalogueGlossary": "./RechercheFacette.asmx/GetCaracteristiques",
//			"catalogueSection": "../xml/catalogue-sections.xml",
			"catalogueSection": "./RechercheFacette.asmx/GetSections",
//			"catalogueCriteria": "../xml/catalogue-criteria-%PRESELECTIONID%.xml",
			"catalogueCriteria": "./RechercheFacette.asmx/GetCriterias",
//			"catalogueResults": "../xml/results-%PRESELECTIONID%-%SORTCRITERIONID%-%FROM%-%TO%.xml"
			"catalogueResults": "./RechercheFacette.asmx/GetResults",
//			"catalogueResults": "../sse/php/server.php",
			"catalogueComparator": "./Comparateur.aspx"
		},
		"preConfig": {}
	}
} ;

//point de départ
Event.observe(window, 'load', function() { SE.startup() ; }) ;

//fonctions		
(function() {

	var tmpl = function(string, replacements) {
		for(var pattern in replacements)
		{
			var re = new RegExp(pattern) ;
			string = string.replace(re, replacements[pattern]) ;
		}
		return string ;
	} ;

	var domify = function(xmlNode) {
		var tagName = xmlNode.nodeName ;
		var attr = {} ;
		var n = xmlNode.attributes.length ;
		for(var i=0; i<n; i++)
		{
			var name = xmlNode.attributes[i].nodeName ;
			attr[name] = xmlNode.getAttribute(name) ;
		}
		var domNode = dom(null, tagName, attr) ;
		return domNode ;
	} ;

	var dom = function(element, tagName, attributes) {
		element = $(element) ;
		var tag ;
		if (tagName == "text")
		{
			tag = document.createTextNode(attributes) ;
			element.appendChild(tag) ;
			return element ;
		}
		else
		{
			tag = document.createElement(tagName) ;
			for(var k in attributes)
			{
				if (k == "innerHTML")
				{
					tag.innerHTML = attributes[k] ;
				}
				else
				{
					if (k.match(/^on/))
					{
						tag[k] = attributes[k] ;
					}					
					else
					{
						tag.setAttribute(k, attributes[k]) ;
					}
				}
			}
			if (element) element.appendChild(tag) ;
			return tag ;
		}
	} ;

	var isInstanceOf = function(o, className, name) {
		//FireFox 1.0 & Netscape bug on instanceof
		if (o.objectClass != null && o.objectClass == name)
			return true ;
		else
			return false ;
		/*
		if (navigator.userAgent.match(/Firefox\/1\.0|Netscape\/7/i))
		{
			var r = new RegExp(name) ;
			return o.toString().match(r) ;
		}
		else
		{
			return o instanceof className ;
		}
		*/
	} ;

	// object Glossary
	var Glossary = Class.create() ;
	Object.extend(Glossary.prototype, {

		// de l'object Glossary.prototype
		show: function(element) {
			var element = $("glossary-"+this.id) ;
			if (element)
			{
				while(element.lastChild)
				{
					element.removeChild(element.lastChild) ;
				}
				
				Element.hide(element);
				
				var div1 = dom(element, "div", {
					"class": "seGlossaryTitle",
					"className": "seGlossaryTitle"
				}) ;
				var a = dom(div1, "a", {
					"class": "seGlossaryClose",
					"className": "seGlossaryClose",
					"src": "/",
					"onclick": this.hide.bind(this)
				}) ;
				var img = dom(a, "img", {
					"src": SE.Config.gif.closeGlossaryTooltip,
					"alt": SE.Config.message.closeGlossaryTooltip,
					"align": "absmiddle"
				}) ;
				var span = dom(div1, "span", {
					"innerHTML": this.title
				} )
				var div2 = dom(element, "div", {
					"class": "seGlossaryDescription",
					"className": "seGlossaryDescription",
					"innerHTML": this.description
				}) ;
				Element.show(element) ;
				if (SE.Config.glossaryTooltipTimeout)
				{
					if (this.interval) clearInterval(this.interval) ;
					this.interval = setInterval(this.hide.bind(this), SE.Config.glossaryTooltipTimeout*1000) ;
				}
			}
			$('glossary-icon-'+this.id).onclick = this.hide.bind(this) ;
			return false ;
		},
		
		// de l'object Glossary.prototype
		hide: function() {
			if (this.interval) clearInterval(this.interval) ;

			if(this.id)
			{
				Element.hide("glossary-"+this.id) ;
			}
			$('glossary-icon-'+this.id).onclick = this.show.bind(this) ;
			return false ;
		},

		// de l'object Glossary.prototype
		toString: function() {
			return "[Glossary "+this.id+"]" ;
		},

		// de l'object Glossary.prototype
		initialize: function() {
			this.objectClass = "Glossary" ;
		}
	}) ;

	// object Section.prototype
	var Section = Class.create() ;
	Object.extend(Section.prototype, {

		// de l'object Section.prototype
		draw: function(element) {
			var h4 = dom(element, "h4", {
				"class": "criter_close",
				"className": "criter_close"
			}) ;
			var a = dom(h4, "a", {
				"href": "/",
				"onclick" : SE.Zone.onSectionEvent.bind(SE.Zone, "onclick", this.id)
			}) ;
			var span1 = dom(a, "span", {
				"innerHTML": this.label
			}) ;
		},

		// de l'object Section.prototype
		toString: function() {
			return "[Section "+this.id+"]" ;
		},

		// de l'object Section.prototype
		initialize: function() {
			this.objectClass = "Section" ;
		}
	}) ;

	// object Criterion.prototype
	var Criterion = Class.create() ;
	Object.extend(Criterion.prototype, {
		
		//de l'object Criterion.prototype
		draw: function(element, display) {
			/*
			<h4 class="criter_open">Marques <a href=""><img src="../../../img/common/picto_interro.gif" width="13" height="13" alt="" /></a></h4>
			<ul class="redarrow pbottom10">
				<li><a href="">Acer</a> (10)</li>
				...
			</ul>
			*/
			var h4 = dom(element, "h4", {
				"class": display=="none" ? "criter_close" : "criter_open",
				"className": display=="none" ? "criter_close" : "criter_open"
			}) ;
			var span1 = dom(h4, "span", {
				"innerHTML": this.label
			}) ;
			// Les Tooltips pour les critères sont pour version V2. Il n'y a a present aucun champ en DB pour une aide sur le critères. LT 19/09/06
			/*if (SE.Model.getGlossaryByID(this.id))
			{
				var a = dom(h4, "a", {
					"id": "glossary-icon-"+this.id,
					"href": "/",
					"sectionID": this.sectionID,
					"criterionID": this.id,
					"onclick": SE.Zone.openHelpOnCriterion.bind(SE.Zone, this.id),
					"onmouseover": SE.Zone.openHelpOnCriterion.bind(SE.Zone, this.id),
					"onmouseout": SE.Zone.closeHelpOnCriterion.bind(SE.Zone, this.id)
				}) ;
				var img1 = dom(a, "img", {
					"src": SE.Config.gif.help
				}) ;
				var div1 = dom(h4, "div", {
					"id": "glossary-"+this.id,
					"class": "seGlossary",
					"className": "seGlossary",
					"style": "display:none"
				}) ;
				Element.hide(div1) ;
				Element.setStyle(div1, { "position": "absolute" }) ;
			}*/

			// FS 2006-09-25 : récupère le model actuel dans la liste réponse si il existe
			var model = SE.Results.model || { statsByCriterionID: {} } ;
			var stats = model.statsByCriterionID[this.id] || {} ;
			
			var ul = dom(element, "ul", {
				"class": "redarrow pbottom10",
				"className": "redarrow pbottom10"
			}) ;
			var n = this.values.length ;
			for(var i=0; i<n; i++)
			{
				var value = this.values[i] ;
				var li = dom(ul, "li", {}) ;
				var a = dom(li, "a", {
					"href": "/",
					"title": SE.Config.message.addCriterion,
					"onclick" : SE.Zone.onCriterionEvent.bind(SE.Zone, "onclick", this.id, i),
					"innerHTML": value.label
				}) ;
				var span = dom(li, "span", {
					"id": "stats-"+value.id,
					//"innerHTML": " (" + value.count + ")" // FS 2006-09-25
					"innerHTML" : 
						value.count != null ? " (" + value.count + ")" :
							stats[value.id] != null ? " (" + stats[value.id].count + ")" : " (-)" // FS 2006-09-25
					
				}) ;
			}
			if (display == "none")
			{
				if(ul)
				{
					Element.hide(ul) ;
				}
			}
			else
			{
				Element.show(ul) ;
			}
		},
		
		//de l'object Criterion.prototype
		getValueByID: function(id) {
			return this.valuesByID[id] ;
		},
		
		//de l'object Criterion.prototype
		toString: function() {
			return "[Criterion "+this.id+"]" ;
		},

		//de l'object Criterion.prototype
		initialize: function() {
			this.objectClass = "Criterion" ;
			this.values = [] ;
			this.valuesByID = {} ;
		}
	}) ;

	// extention de l'object SE
	SE = Object.extend(SE, {
		
		bookmarkURL: function() {
			SE.debug(window.location.href) ;
		},
		
		createSpinner: function(element) {
			var div = dom(element, "div", { style: "display:none" }) ;
			var img = dom(div, "img", {
				"src": SE.Config.gif.spinner,
				"align": "absmiddle",
				"class": "seSpinner",
				"className": "seSpinner"
			})
			var span = dom(div, "span", { "class": "seSpinner", "className": "seSpinner", "innerHTML": "Chargement du catalogue..." } ) ;
			return div ;
		},

		//object SE.Model
		Model: Object.extend(new Object(), {
			sectionsByID: {},
			glossaryByID: {},
			criterionByID: {},
			criteriaByPreSelectionID: {},
			resultsByCriteria: {},
			glossariesBySectionID: {},

			// de l'object SE.Model
			modelizeGlossaryXML: function(xmlDocument) {
				var model = {
					headers: {},
					objects: [],
					objectsByID: {}
				} ;
				var headersNodes = xmlDocument.getElementsByTagName("headers") ;
				var n = headersNodes.length ;
				for(var i=0; i<n; i++)
				{
					var nodes = headersNodes[i].getElementsByTagName("*") ;
					var m = nodes.length ;
					for(var j=0; j<m; j++)
					{
						var node = nodes[j] ;
						model.headers[node.nodeName] = this.nodeValue(node) ;
					}
				}
				var nodes = xmlDocument.getElementsByTagName("item") ;
				var n = nodes.length ;
				for(var i=0; i<n; i++)
				{
					var node = nodes[i] ;
					var o = new Glossary() ;
					o.id = this.nodeValue(node.getElementsByTagName("id")[0]) ;
					o.title = this.nodeValue(node.getElementsByTagName("title")[0]) ;
					o.description = this.nodeValue(node.getElementsByTagName("description")[0]) ;
					o.xmlNodeIndex = i ;

					model.objects.push(o) ;
					model.objectsByID[o.id] = o ;
				}
				return model ;
			},

			// de l'object SE.Model
			modelizeResultXML: function(xmlDocument) {
				var model = {
					headers: {},
					statsByCriterionID: {},
					html: ""
				} ;
				var headersNodes = xmlDocument.getElementsByTagName("headers") ;
				var n = headersNodes.length ;
				for(var i=0; i<n; i++)
				{
					var nodes = headersNodes[i].getElementsByTagName("*") ;
					var m = nodes.length ;
					for(var j=0; j<m; j++)
					{
						var node = nodes[j] ;
						model.headers[node.nodeName] = this.nodeValue(node) ;
					}
				}
				var criterionsNodes = xmlDocument.getElementsByTagName("criterion") ;
				var n = criterionsNodes.length ;
				for(var i=0; i<n; i++)
				{
					var stats = {
						"id": this.nodeValue(criterionsNodes[i].getElementsByTagName("id")[0]),
						"valuesByID": {}
					}
					var nodes = criterionsNodes[i].getElementsByTagName("value") ;
					var m = nodes.length ;
					for(var j=0; j<m; j++)
					{
						var node = nodes[j] ;
						var o = {
							"id": this.nodeValue(node.getElementsByTagName("id")[0]),
							"count": this.nodeValue(node.getElementsByTagName("count")[0])
						} ;
						stats.valuesByID[o.id] = o ;
					}
					model.statsByCriterionID[stats.id] = stats ;
				}
				var resultNodes = xmlDocument.getElementsByTagName("results") ;
				if (resultNodes.length)
				{
					model.html = this.nodeValue(resultNodes[0]) ;
				}
				return model ;
			},

			// de l'object SE.Model
			modelizeGenericXML: function(xmlDocument, objectClass) {
				var model = {
					headers: {},
					objects: [],
					objectsByID: {}
				} ;
				var headersNodes = xmlDocument.getElementsByTagName("headers") ;
				var n = headersNodes.length ;
				for(var i=0; i<n; i++)
				{
					var nodes = headersNodes[i].getElementsByTagName("*") ;
					var m = nodes.length ;
					for(var j=0; j<m; j++)
					{
						var node = nodes[j] ;
						model.headers[node.nodeName] = this.nodeValue(node) ;
					}
				}
				var nodes = xmlDocument.getElementsByTagName("item") ;
				var n = nodes.length ;
				for(var i=0; i<n; i++)
				{
					var node = nodes[i] ;
					var o = new objectClass() ;
					o.id = this.nodeValue(node.getElementsByTagName("id")[0]) ;
					o.label = this.nodeValue(node.getElementsByTagName("label")[0]) ;
					o.isPlusCriterion = node.getElementsByTagName("isPlusCriterion").length>0 ;
					o.xmlNodeIndex = i ;

					var temps = node.getElementsByTagName("defaultPreSelectionID") ;
					if (temps.length)
						o.defaultPreSelectionID = this.nodeValue(temps[0]) ;

					var temps = node.getElementsByTagName("defaultSortCriterionID") ;
					if (temps.length)
						o.defaultSortCriterionID = this.nodeValue(temps[0]) ;
					
					var valuesNodes = node.getElementsByTagName("value") ;
					var m = valuesNodes.length ;
					for(var j=0; j<m; j++)
					{
						var node = valuesNodes[j] ;
						var value = {
							"id": this.nodeValue(node.getElementsByTagName("id")[0]),
							"label": this.nodeValue(node.getElementsByTagName("label")[0]),
							"count": this.nodeValue(node.getElementsByTagName("count")[0])
						} ;
						o.values.push(value) ;
						o.valuesByID[value.id] = value ;
						o.xmlNodeIndex = j ;
					
					}
					
					model.objects.push(o) ;
					model.objectsByID[o.id] = o ;
				}
				return model ;
			},

			// de l'object SE.Model
			modelizeCriteriaXML: function(xmlDocument) {
				return this.modelizeGenericXML(xmlDocument, Criterion) ;
			},
			
			// de l'object SE.Model
			modelizeSectionXML: function(xmlDocument) {
				return this.modelizeGenericXML(xmlDocument, Section) ;
			},
			
			// de l'object SE.Model
			synchronousGet: function(url, params) {
				params = params||{} ;
				var qs = $H(params).toQueryString() ;
				SE.debug("SE.Model.synchronousGet("+url+"?"+qs+")") ;
				SE.Zone.onLoading() ;
				var request = new Ajax.Request(url, {
					"method": "post",
					"parameters": $H(params).toQueryString(),
					"asynchronous": false
				}) ;
				SE.Zone.onReady() ;
				if (!request.responseIsSuccess())
				{
					SE.error("SE.Model.synchronousGet failed") ;
					return null ;
				}
				SE.debug("SE.Model.synchronousGet successfull") ;
				return request.transport ;
			},

			// de l'object SE.Model
			asynchronousGet: function(url, params, onComplete) {
				params = params||{} ;
				var qs = $H(params).toQueryString() ;
				SE.debug("SE.Model.asynchronousGet("+url+"?"+qs+")") ;
				var request = new Ajax.Request(url, {
					"method": "post",
					"parameters": $H(params).toQueryString(),
					"asynchronous": true,
					"onComplete": onComplete,
					"onException": function(request, exception) {
                        SE.error("SE.Model.asynchronousGet onException : "+exception+" at line "+(exception.line||exception.lineNumber)+" in "+(exception.sourceURL||exception.fileName)) ;
					}
				}) ;
			},

			// de l'object SE.Model
			getGlossaryByID: function(id) {
				return this.glossaryByID[id] ;
			},
			
			// de l'object SE.Model
			getCriterionByID: function(id) {
				return this.criterionByID[id] ;
			},
			
			// de l'object SE.Model
			getSectionByID: function(id) {
				return this.sectionsByID[id] ;
			},
			
			// de l'object SE.Model
			getGlossaries: function(sectionID, search) {
				var model;
								
				// use cache if exists
				if (this.glossariesBySectionID[sectionID])
				{
					model = this.glossariesBySectionID[sectionID] ;
				}
				else
				{
					//var url = catalogueGlossary(SE.Config.url.catalogueGlossary, {"%SECTIONID%": sectionID}) ;
					var url = SE.Config.url.catalogueGlossary ;
					var transport = this.synchronousGet(url, { sectionID: sectionID, search: search}) ;
					if (transport == null || transport.responseXML == null)
					{
						return null ;
					}
					model = this.modelizeGlossaryXML(transport.responseXML) ;
					this.glossariesBySectionID[sectionID] = model ;
				}
				
				var n = model.objects.length ;
				for(var i=0; i<n; i++)
				{
					var glossary = model.objects[i] ;
					this.glossaryByID[glossary.id] = glossary ;
				}
				return this.glossariesBySectionID[sectionID] ;
			},
			
			// de l'object SE.Model
			getCriteria: function(preSelectionID, search) {
			
				var criteria;
			
				// use cache if exists
				if (this.criteriaByPreSelectionID[preSelectionID])
				{
					criteria = this.criteriaByPreSelectionID[preSelectionID] ;
				}
				else
				{
					//var url = tmpl(SE.Config.url.catalogueCriteria, { "%PRESELECTIONID%": preSelectionID }) ;
					var url = SE.Config.url.catalogueCriteria
					var transport = this.synchronousGet(url, { preSelectionID: preSelectionID, search: search }) ;
					if (transport == null || transport.responseXML == null)
					{
						return null ;
					}
					criteria = this.modelizeCriteriaXML(transport.responseXML) ;
					this.criteriaByPreSelectionID[preSelectionID] = criteria ;
				}
				
				var n = criteria.objects.length ;
				for(var i=0; i<n; i++)
				{
					var criterion = criteria.objects[i] ;
					var values = [] ;
					var m = criterion.values.length ;
					for(var j=0; j<m; j++)
					{
						//if (criterion.values[j].lines > 0)
							values.push(criterion.values[j]) ;
					}
					criterion.values = values ;
					criterion.preSelectionID = preSelectionID ;
					this.criterionByID[criterion.id] = criterion ;
				}
				return this.criteriaByPreSelectionID[preSelectionID] ;
			},
						
			// de l'object SE.Model
			getSections: function(sectionID, search) {
				
				var sections;
				
				// use cache if exists
				if (this.sections)
				{
					sections = this.sections ;
				}
				else
				{
					//var url = tmpl(SE.Config.url.catalogueSection, {}) ;
					var url = SE.Config.url.catalogueSection
					var transport = this.synchronousGet(url, {sectionID: sectionID, search: search}) ;
					if (transport == null || transport.responseXML == null)
					{
						return null ;
					}
					sections = this.modelizeSectionXML(transport.responseXML) ;
					this.sections = sections ;
				}
				
				var n = sections.objects.length ;
				for(var i=0; i<n; i++)
				{
					var section = sections.objects[i] ;
					this.sectionsByID[section.id] = section ;
				}
				
				return this.sections ;
			},

			// de l'object SE.Model
			onStartup: function() {
				if (window.document.body.textContent != null)
				{
					SE.debug("XML node content will be retreived with .textContent property") ;
					this.nodeValue = function(xmlNode) { return xmlNode ? xmlNode.textContent : null ; } ;
				}
				else
				{
					SE.debug("XML node content will be retreived with .nodeValue property") ;
					
					// FS 2006-09-25
					//this.nodeValue = function(xmlNode) { return xmlNode.firstChild ? xmlNode.firstChild.nodeValue : null ; } ;
					this.nodeValue = function(xmlNode) { return xmlNode && xmlNode.firstChild ? xmlNode.firstChild.nodeValue : null ; } ;
				}
			},
			
			// de l'object SE.Model
			_getResults: function(transport, object) {
				var model = SE.Model.modelizeResultXML(transport.responseXML) ;
				if (model)
				{
					SE.debug("SE.Model._getResults: function("+transport+","+object+") -> model OK") ;
					if (model.headers)
					{
					}
					var key = SE.Model._getResultsKey ;
					SE.debug("SE.Model._getResults: function, Mise en cache du XML sous clef : "+key) ;
					SE.Model.resultsByCriteria[key] = model ;
					SE.Results._drawPage(model, SE.Model._getResultsScroll) ;
				}
				else
				{
					SE.debug("SE.Model._getResults("+transport+","+object+") -> model NOK") ;
					// retry in 3 seconds
					setTimeout(SE.Results.drawPage.bind(SE.Results, 0), 3000) ;
					SE.Results.onNetworkError() ;
				}
			},
			
			// de l'object SE.Model
			getResults: function(criteria, fromResult, toResult, scroll) {
				var sortcriterionID = SE.Results.sortcriterionID || "TRI_PAGE_LOAD" ;
				var sortdirection = SE.Results.sortdirection || "direct" ;
				var preselectionID = SE.Results.preselectionID || "" ;
				var sectionID = SE.Results.sectionID || "";
				var search = SE.Results.search || "";
				var cookieName = self.location.hash;
				var params = {
					"sectionID" : sectionID,
					"preSelectionID": preselectionID,
					"sortResultsBy": sortcriterionID,
					"sortDirection": sortdirection,
					"selectFromResult": fromResult,
					"selectToResult": toResult,
					"search": search,
					"cookieName": cookieName
				} ;
				var n = criteria.length ;

				SE.debug("SE.Model.getResults: function") ;
				for(var i=0; i<n; i++)
				{
					var criterion = criteria[i] ;
					//if (isInstanceOf(criterion, Section, "Section"))
					//{
					//	params["sectionID"] = criterion.id ;
					//}
					if (isInstanceOf(criterion, Criterion, "Criterion"))
					{
						params["criteria["+criterion.id+"]"] = criterion.values[criterion.selectedIndex].id ;
					}
				}
				var key = $H(params).toQueryString() ;
				SE.debug("SE.Model.getResults: function, Clef du cache XML : "+key) ;

				// use cache
				if (SE.Model.resultsByCriteria[key])
				{
					SE.debug("SE.Model.getResults: function, Cette clef existe dans le cache, RETURN") ;
					SE.Results._drawPage(SE.Model.resultsByCriteria[key], scroll) ;
					return false ;
				}

				var url = tmpl(SE.Config.url.catalogueResults, {
					"%SECTIONID%": sectionID,
					"%PRESELECTIONID%": preselectionID,
					"%SORTCRITERIONID%": sortcriterionID,
					"%SORTDIRECTION%": sortdirection,
					"%FROM%": fromResult,
					"%TO%": toResult,
					"%SEARCH%": search,
					"%COOKIENAME%": cookieName
					}) ;
				
				this._getResultsKey = key ;
				this._getResultsScroll = scroll ;
				this.asynchronousGet(url, params, SE.Model._getResults) ;
			},
			
      /********************************************************************************************************************/
			
			// de l'object SE.Model
			getResultsSynchrone: function(criteria, fromResult, toResult, scroll) {
				var sortcriterionID = SE.Results.sortcriterionID || "TRI_PAGE_LOAD" ;
				var sortdirection = SE.Results.sortdirection || "direct" ;
				var preselectionID = SE.Results.preselectionID || "" ;
				var sectionID = SE.Results.sectionID || "";
				var search = SE.Results.search || "";
				var cookieName = self.location.hash;
				var params = {
					"sectionID" : sectionID,
					"preSelectionID": preselectionID,
					"sortResultsBy": sortcriterionID,
					"sortDirection": sortdirection,
					"selectFromResult": fromResult,
					"selectToResult": toResult,
					"search": search,
					"cookieName": cookieName
				} ;
				var n = criteria.length ;
				
				SE.debug("SE.Model.getResultsSynchrone: function") ;
				
				for(var i=0; i<n; i++)
				{
					var criterion = criteria[i] ;
					//if (isInstanceOf(criterion, Section, "Section"))
					//{
					//	params["sectionID"] = criterion.id ;
					//}
					if (isInstanceOf(criterion, Criterion, "Criterion"))
					{
						params["criteria["+criterion.id+"]"] = criterion.values[criterion.selectedIndex].id ;
					}
				}
				var key = $H(params).toQueryString() ;
				SE.debug("SE.Model.getResultsSynchrone: function, Clef du cache XML : "+key) ;

				// use cache
				if (SE.Model.resultsByCriteria[key])
				{
					SE.debug("SE.Model.getResultsSynchrone: function, Cette clef existe dans le cache, RETURN") ;
					SE.Results._drawPage(SE.Model.resultsByCriteria[key], scroll) ;
					return false ;
				}

				var url = tmpl(SE.Config.url.catalogueResults, {
					"%SECTIONID%": sectionID,
					"%PRESELECTIONID%": preselectionID,
					"%SORTCRITERIONID%": sortcriterionID,
					"%SORTDIRECTION%": sortdirection,
					"%FROM%": fromResult,
					"%TO%": toResult,
					"%SEARCH%": search,
					"%COOKIENAME%": cookieName
					}) ;
				
				this._getResultsSynchroneKey = key ;
				this._getResultsSynchroneScroll = scroll ;
				
				var transport=this.synchronousGet(url, params) ;
				if (transport == null || transport.responseXML == null)
				{
					return null ;
				}
				var model = SE.Model.modelizeResultXML(transport.responseXML) ;
				
				if (model)
				{
					SE.debug("SE.Model.getResultsSynchrone: function, SE.Model._getResults("+transport+") -> model OK") ;
					if (model.headers)
					{
					}
					var key = SE.Model._getResultsSynchroneKey ;
					SE.debug("SE.Model.getResultsSynchrone: function, Mise en cache du XML sous clef : "+key) ;
					SE.Model.resultsByCriteria[key] = model ;
					SE.Results._drawPage(model, SE.Model._getResultsSynchroneScroll) ;
				}
				else
				{
					SE.debug("SE.Model.getResultsSynchrone: SE.Model._getResults("+transport+") -> model NOK") ;
					// retry in 3 seconds
					setTimeout(SE.Results.drawPage.bind(SE.Results, 0), 3000) ;
					SE.Results.onNetworkError() ;
				}
			},
			
			// de l'object SE.Model
			initialize: function() {
					    this.objectClass = "Model" ;
			}
		}),

		//object SE.Zone
		Zone: Object.extend(new Object(), {
			criteria: [],
			
			//de l'object SE.Zone
			closeHelpTooltip: function(criterionID) {

				this.getGlossaryByID(criterionID).hide() ;
			},
			
			//de l'object SE.Zone
			openHelpOnCriterion: function(criterionID) {
				SE.debug("SE.Zone.openHelpOnCriterion("+criterionID+")") ;
				var glossary = SE.Model.getGlossaryByID(criterionID) ;
				if (glossary)
				{
					glossary.show() ;
				}
				return false ;
			},
			
			//de l'object SE.Zone
			closeHelpOnCriterion: function(criterionID) {
				SE.debug("SE.Zone.closeHelpOnCriterion("+criterionID+")") ;
				var glossary = SE.Model.getGlossaryByID(criterionID) ;
				if (glossary)
				{
					glossary.hide() ;
				}
				return false ;
			},
			
			//de l'object SE.Zone
			syncRequest: function(doNotSyncResults) {
				SE.debug("SE.Zone.syncRequest()") ;
				SE.Request.objects = [] ;
				if (this.sectionID)
				{
					SE.Request.objects.push(SE.Model.getSectionByID(this.sectionID)) ;
					var n = this.criteria.length ;
					for(var i=0; i<n; i++)
					{
						SE.Request.objects.push(this.criteria[i]) ;
					}
				}
				SE.Request.draw(doNotSyncResults) ;
			},
			
			//de l'object SE.Zone
			syncRequestSynchrone: function(doNotSyncResults) {
				SE.debug("SE.Zone.syncRequestSynchrone()") ;
				SE.Request.objects = [] ;
				if (this.sectionID)
				{
					SE.Request.objects.push(SE.Model.getSectionByID(this.sectionID)) ;
					var n = this.criteria.length ;
					for(var i=0; i<n; i++)
					{
						SE.Request.objects.push(this.criteria[i]) ;
					}
				}
				SE.Request.drawSynchrone(doNotSyncResults) ;
			},
			

			//de l'object SE.Zone
			clearCriteria: function() {
				this.criteria = [] ;
				// FS 2006-09-26
				SE.Request.objects = [] ;
				SE.Results.criteria = [] ;
				
				SE.CookiesCriteres = "";
			},

			//de l'object SE.Zone
			addCriterion: function(id, selectedIndex) {
				var criterion = SE.Model.getCriterionByID(id) ;
				
				if (criterion)
				{
					criterion.selectedIndex = selectedIndex ;
					if (this.criteria.indexOf(criterion) == -1)
					{
						this.criteria.push(criterion) ;
					}
				}
				//ajout du critere dans un cookie
				var criteres=new Array();
				for(var i=0;i<this.criteria.length;i++)
				{
					var obj=new Object();
					obj.id=this.criteria[i].id;
					obj.selectedIndex=this.criteria[i].selectedIndex;
					criteres.push(JSON.stringify(obj));
				}
				
				//recuperation du cookie s'il existe et modification de la donnee avec la nouvelle
				SE.CookiesCriteres = "[" + criteres.toString() + "]";
			},
			
			//de l'object SE.Zone
			removeCriterion: function(id) {
				var criterion = SE.Model.getCriterionByID(id) ;
				var criteria = [] ;
				var n = this.criteria.length ;
				for(var i=0; i<n; i++)
				{
					if (this.criteria[i] != criterion)
					{
						criteria.push(this.criteria[i]) ;
					}
				}
				this.criteria = criteria ;
				//ajout du critere dans un cookie
				var criteres=new Array();
				for(var i=0;i<this.criteria.length;i++)
				{
					var obj=new Object();
					obj.id=this.criteria[i].id;
					obj.selectedIndex=this.criteria[i].selectedIndex;
					criteres.push(JSON.stringify(obj));
		        }
				
				SE.CookiesCriteres = "[" + criteres.toString() + "]";
			},

			//de l'object SE.Zone
			onCriterionEvent: function(type, targetID, selectedIndex) {
				SE.debug("SE.Zone.onCriterionEvent("+type+","+targetID+","+selectedIndex+")")
				this.addCriterion(targetID, selectedIndex) ;
				this.draw() ;
				return false ; // required : prevent <a> from firing its href
			},
			
			//de l'object SE.Zone
			onSectionEvent: function(type, targetID) {
				SE.debug("SE.Zone.onSectionEvent("+type+","+targetID+")") ;
				this.sectionID = targetID ;
				var model = SE.Model.getSections() ;
				SE.Results.preselectionID = model.objectsByID[targetID].defaultPreSelectionID ;
				SE.Results.sortcriterionID = model.objectsByID[targetID].defaultSortCriterionID ;
				SE.Results.sortdirection = model.objectsByID[targetID].defaultSortDirection ;
				var model = SE.Model.getGlossaries(this.sectionID, SE.Results.search) ;
				this.draw() ;
				return false ; // required : prevent <a> from firing its href
			},

			// FS 2006-09-21
			//de l'object SE.Zone
			criterionIsSelected: function(o) {
				var n = this.criteria.length ;
				for(var i=0; i<n; i++)
				{
					if (this.criteria[i].id == o.id)
						return true ;
				}
				return false ;
			},

			// FS 2006-09-25
			//de l'object SE.Zone
			updateZoneWithStatsOf: function(model) {
				if (!model) return false ;
				if (!model.statsByCriterionID) return false ;
				for(var criterionID in model.statsByCriterionID)
				{
					var stats = model.statsByCriterionID[criterionID] ;
					for(var valueID in stats.valuesByID)
					{
						var el = $("stats-"+valueID) ;
						if (el) el.innerHTML = " ("+stats.valuesByID[valueID].count+")" ;
					}
				}
				return true ;
			},
			
			//de l'object SE.Zone
			drawZoneWith: function(model) {
				if(this.element){
					// remove existing nodes but my spinner
					while(this.spinner != this.element.lastChild && this.element.lastChild)
					{
						Element.remove(this.element.lastChild) ;
					}

					// draw new nodes
					if (model.headers && model.headers.title)
					{
						dom(this.element, "div", {
							"class": "seZoneListTitle",
							"className": "seZoneListTitle",
							"innerHTML": model.headers.title
						})
					}
				
					var div = dom(this.element, "div", {
						"id": "seZoneList",
						"class": "seZoneList",
						"className": "seZoneList"
					})
				
					var n = model.objects.length ;
					// display first not selected criteria...
					for(var i=0; i<n; i++)
					{
						if (model.objects[i].isPlusCriterion)
							continue ;
					
						if (isInstanceOf(model.objects[i], Criterion, "Criterion"))
						{
							//if (this.criteria.indexOf(model.objects[i]) == -1)
							if (!this.criterionIsSelected(model.objects[i])) // FS 2006-09-21
							{
								model.objects[i].draw(div, "block") ;
							}
						}
						else
						{
							model.objects[i].draw(div) ;
						}
					}
					// then display selected criteria
					for(var i=0; i<n; i++)
					{
						if (model.objects[i].isPlusCriterion)
							continue ;
						if (isInstanceOf(model.objects[i], Criterion, "Criterion"))
						{
							//if (this.criteria.indexOf(model.objects[i]) != -1)
							if (this.criterionIsSelected(model.objects[i])) // FS 2006-09-21
							{
								model.objects[i].draw(div, "none") ;
							}
						}
					}
				
					// FS 2006-09-25
					this.updateZoneWithStatsOf(SE.Results.model) ;
				}
			},

			//de l'object SE.Zone
			draw: function(doNotSyncResults) {
				SE.debug("SE.Zone.draw()") ;
				var model ;
				if (this.sectionID)
				{
					model = SE.Model.getGlossaries(this.sectionID, SE.Results.search) ;
					model = SE.Model.getSections() ;
					model = SE.Model.getCriteria(SE.Results.preselectionID, SE.Results.search) ;
				}
				else
				{
					this.criteria = [] ;
					model = SE.Model.getSections() ;
					
				}
				if (model)
				{
					this.onDrawing() ;
					this.drawZoneWith(model) ;
					this.syncRequest(doNotSyncResults) ;
					this.onReady() ;
				}
				else
				{
					// retry in 3 seconds
					setTimeout(this.draw.bind(this), 3000) ;
					this.onNetworkError() ;
				}
			},
			
			//de l'object SE.Zone
			drawSynchrone: function(doNotSyncResults) {
				SE.debug("SE.Zone.drawSynchrone()") ;
				var model ;
				if (this.sectionID)
				{
					model = SE.Model.getGlossaries(this.sectionID, SE.Results.search) ;
					model = SE.Model.getSections() ;
					model = SE.Model.getCriteria(SE.Results.preselectionID, SE.Results.search) ;
				}
				else
				{
					this.criteria = [] ;
					model = SE.Model.getSections() ;
					
				}
				if (model)
				{
					this.onDrawing() ;
					this.drawZoneWith(model) ;
					this.syncRequestSynchrone(doNotSyncResults) ;
					this.onReady() ;
				}
				else
				{
					// retry in 3 seconds
					setTimeout(this.draw.bind(this), 3000) ;
					this.onNetworkError() ;
				}
			},
			

			//de l'object SE.Zone
			onNetworkError: function() {
				this.spinner.lastChild.innerHTML = "Network error, retry in 3 seconds..." ;
				Element.show(this.spinner) ;
			},
			
			//de l'object SE.Zone
			onDrawing: function() {
				this.spinner.lastChild.innerHTML = "Drawing UI..." ;
				Element.show(this.spinner) ;
				
			},
			
			//de l'object SE.Zone
			onLoading: function() {
				this.spinner.lastChild.innerHTML = "Chargement du catalogue..." ;
				Element.show(this.spinner) ;
			},
			
			//de l'object SE.Zone
			onReady: function() {

				if (this.spinner)
				{
					Element.hide(this.spinner) ;
					/* init events zoom + descriptions */
					//initZoomNDesc();
				}
			},

			//de l'object SE.Zone
			onStartup: function() {
				if($('SEZone')){
					this.element = $('SEZone') ;
					if (this.element == null)
					{
						SE.error("div #SEZone not found in page !") ;
						this.element = dom(document.body, "div", {id: "SEZone"}) ;
					}
					this.spinner = SE.createSpinner(this.element) ;
					this.onLoading() ;
				}
			},
			
			//de l'object SE.Zone
			initialize: function() {
					    this.objectClass = "Zone" ;
			}
		}),

		//object SE.Request
		Request: Object.extend(new Object(), {
			objects: [],
			
			//de l'object SE.Request
			syncResults: function() {
				SE.debug("SE.Request.syncResults()") ;
				if (this.objects.length)
				{
					SE.Results.registerCriteria(this.objects) ;
					SE.Results.draw() ;
				}
			},
			
			//de l'object SE.Request
			syncResultsSynchrone: function() {
				SE.debug("SE.Request.syncResultsSynchrone()") ;
				if (this.objects.length)
				{
					SE.Results.registerCriteria(this.objects) ;
					SE.Results.drawSynchrone() ;
				}
			},
			
			
			//de l'object SE.Request
			clearRequest: function(){
				if (SE.Config.showRequestSection)
				{
					SE.Zone.sectionID = null ;
					SE.Zone.preselectionID = null ;
				}
				SE.Zone.clearCriteria() ;
				SE.Zone.draw() ;
			},
			
			//de l'object SE.Request
			clearJustRequest: function(){
				if (SE.Config.showRequestSection)
				{
					SE.Zone.sectionID = null ;
					SE.Zone.preselectionID = null ;
				}
				SE.Zone.clearCriteria() ;
				SE.Zone.draw(!SE.Config.drawOnStartup) ;
			},
			
			//de l'object SE.Request
			draw: function(doNotSyncResults) {
				if(this.element){
					SE.debug("SE.Request.draw(" + doNotSyncResults + ")") ;
					this.onDrawing() ;

					// remove existing nodes but my spinner
					while(this.spinner != this.element.lastChild && this.element.lastChild)
					{
						Element.remove(this.element.lastChild) ;
					}

					var n = this.objects.length ;
					if (
						(!SE.Config.showRequestSection && n>1)
						||
						(SE.Config.showRequestSection && n>0)
					){
						for(var i=0; i<n; i++)
						{
							var object = this.objects[i] ;
					
							if (object.isPlusCriterion)
								continue ;
							if (!SE.Config.showRequestSection)
							{
								if (isInstanceOf(object, Section, "Section"))
									continue ;
							}
							var ul = dom(this.element, "ul", {}) ;
							var li = dom(ul, "li", {}) ;
							var innerHTML = "x" ;
							if (isInstanceOf(object, Section, "Section"))
							{
								innerHTML = object.label ; 
								if (SE.Config.showRequestCriterion)
									innerHTML += " (sectionID="+object.id+")" ;
							}
							if (isInstanceOf(object, Criterion, "Criterion"))
							{
								innerHTML = object.label+" "+object.values[object.selectedIndex].label ;
								if (SE.Config.showRequestCriterion)
									innerHTML += " ("+object.id+"="+object.values[object.selectedIndex].id+")" ;
							}
							var span = dom(li, "span", {
								"innerHTML": innerHTML
							}) ;
							var a = dom(li, "a", {
								"href": "/",
								"title": SE.Config.message.removeCriterion,
								"onclick": this.onRemoveItemAt.bind(this, i)
							}) ;
							var image = dom(a, "img", {
								"alt": SE.Config.message.removeCriterion,
								"src": SE.Config.gif.remove
							}) ;
						}
					
						//<p><a href="" class="redarrow">Supprimer les crit&egrave;res</a></p>
						var p = dom(this.element, "p", {}) ;
						var a = dom(p, "a", {
							"class": "redarrow",
							"className": "redarrow",
							"href": "/",
							"onclick": function() { SE.Request.clearRequest() ; return false ; },
							"innerHTML": SE.Config.message.clearRequest
						}) ;
					}
					else
					{
						var span = dom(this.element, "span", {
							"innerHTML": SE.Config.message.emptyRequest
						}) ;
					}
					this.onReady() ;
					//if (!doNotSyncResults)
						this.syncResults() ;
				}
			},
			
			//de l'object SE.Request
			drawSynchrone: function(doNotSyncResults) {
				if(this.element){
					SE.debug("SE.Request.drawSynchrone(" + doNotSyncResults + ")") ;
					this.onDrawing() ;

					// remove existing nodes but my spinner
					while(this.spinner != this.element.lastChild && this.element.lastChild)
					{
						Element.remove(this.element.lastChild) ;
					}

					var n = this.objects.length ;
					if (
						(!SE.Config.showRequestSection && n>1)
						||
						(SE.Config.showRequestSection && n>0)
					)
					{
						for(var i=0; i<n; i++)
						{
							var object = this.objects[i] ;
						
							if (object.isPlusCriterion)
								continue ;
							if (!SE.Config.showRequestSection)
							{
								if (isInstanceOf(object, Section, "Section"))
									continue ;
							}
							var ul = dom(this.element, "ul", {}) ;
							var li = dom(ul, "li", {}) ;
							var innerHTML = "x" ;
							if (isInstanceOf(object, Section, "Section"))
							{
								innerHTML = object.label ; 
								if (SE.Config.showRequestCriterion)
									innerHTML += " (sectionID="+object.id+")" ;
							}
							if (isInstanceOf(object, Criterion, "Criterion"))
							{
								innerHTML = object.label+" "+object.values[object.selectedIndex].label ;
								if (SE.Config.showRequestCriterion)
									innerHTML += " ("+object.id+"="+object.values[object.selectedIndex].id+")" ;
							}
							var span = dom(li, "span", {
								"innerHTML": innerHTML
							}) ;
							var a = dom(li, "a", {
								"href": "/",
								"title": SE.Config.message.removeCriterion,
								"onclick": this.onRemoveItemAt.bind(this, i)
							}) ;
							var image = dom(a, "img", {
								"alt": SE.Config.message.removeCriterion,
								"src": SE.Config.gif.remove
							}) ;
						}
						
						//<p><a href="" class="redarrow">Supprimer les crit&egrave;res</a></p>
						var p = dom(this.element, "p", {}) ;
						var a = dom(p, "a", {
							"class": "redarrow",
							"className": "redarrow",
							"href": "/",
							"onclick": function() { SE.Request.clearRequest() ; return false ; },
							"innerHTML": SE.Config.message.clearRequest
						}) ;
					}
					else
					{
						var span = dom(this.element, "span", {
							"innerHTML": SE.Config.message.emptyRequest
						}) ;
					}
					this.onReady() ;
					//if (!doNotSyncResults)
						this.syncResultsSynchrone() ;
				}
			},

			//de l'object SE.Request
			onRemoveItemAt: function(index) {
				SE.debug("SE.Request.onRemoveItemAt("+index+")") ;
				switch(index)
				{
					case 0 :
						SE.Zone.sectionID = null ;
						break ;

					default :
						SE.Zone.removeCriterion(this.objects[index].id) ;
						break ;
				}
				SE.Zone.draw(false) ;
				return false ; // required : prevent <a> from firing its href
			},

			//de l'object SE.Request
			onNetworkError: function() {
				this.spinner.lastChild.innerHTML = "Network error, retry in 3 seconds..." ;
				Element.show(this.spinner) ;
			},
			
			//de l'object SE.Request
			onDrawing: function() {
				this.spinner.lastChild.innerHTML = "Drawing UI..." ;
				Element.show(this.spinner) ;
			},
			
			//de l'object SE.Request
			onLoading: function() {
				this.spinner.lastChild.innerHTML = "Chargement du catalogue..." ;
				Element.show(this.spinner) ;
			},
			
			//de l'object SE.Request
			onReady: function() {
			
				if(this.spinner)
				{
					Element.hide(this.spinner) ;
				}
			},
			
			//de l'object SE.Request
			onStartup: function() {
				if($('SERequest')){
					this.element = $('SERequest') ;
					if (this.element == null)
					{
						SE.error("div #SERequest not found in page !") ;
						this.element = dom(document.body, "div", {id: "SERequest"}) ;
					}
					this.spinner = SE.createSpinner(this.element) ;
					this.onLoading() ;
				}
			},
			
			//de l'object SE.Request
			initialize: function() {
					    this.objectClass = "Request" ;
			}
		}),

		//Object    Comparator
		Comparator: Object.extend(new Object(), {
			productIDs: [],

			// de l'Object    SE.Comparator
			checkBoxes: function() {
				return SE.Results.element.getElementsByTagName("input") ;
			},
			
			// de l'Object    SE.Comparator
			gray: function() {
				var isFull = this.isFull() ;
				var nodes = this.checkBoxes() ;
				var n = nodes.length ;
				for(var i=0; i<n; i++)
				{
					var node = nodes[i] ;
					if (node.type == "checkbox")
					{
						if (isFull)
						{
							if (node.checked)
							{
								node.disabled = false ;
							}
							else
							{
								node.disabled = true ;
							}
						}
						else
						{
							node.disabled = false ;
						}
					}
				}
				this.goLinks() ;
			},

			// de l'Object    SE.Comparator
			clear: function() {
				this.productIDs = [] ;
				var nodes = this.checkBoxes() ;
				var n = nodes.length ;
				for(var i=0; i<n; i++)
				{
					var node = nodes[i] ;
					node.checked = false ;
				}
				this.gray() ;
			},
			
			// de l'Object    SE.Comparator
			register: function(productID) {
				if (this.productIDs.indexOf(productID) == -1)
				{
					SE.debug("SE.Comparator.register("+productID+")") ;
					this.productIDs.push(productID) ;
				}
			},
			
			// de l'Object    SE.Comparator
			unregister: function(productID) {
				SE.debug("SE.Comparator.unregister("+productID+")") ;
				this.productIDs = this.productIDs.without(productID) ;
			},
			
			// de l'Object    SE.Comparator
			isFull: function() {
				return (this.productIDs.length == SE.Config.comparatorMaxProducts)
			},
			
			// de l'Object    SE.Comparator
			notify: function(checkbox, productID) {
				if (checkbox.checked)
				{
					if (!this.isFull())
					{
						this.register(productID) ;
					}
					else
					{
						checkbox.checked = false ;
					}
				}
				else
				{
					this.unregister(productID) ;
				}
				setTimeout(this.gray.bind(this), 50) ;
			},
			
			// de l'Object    SE.Comparator
			sync: function(element) {
				var isFull = this.isFull() ;
				var nodes = this.checkBoxes() ;
				var n = nodes.length ;
				for(var i=0; i<n; i++)
				{
					var node = nodes[i] ;
					if (node.type == "checkbox")
					{
						var productID = node.value ;
						if (this.productIDs.indexOf(productID) == -1)
						{
							if (isFull)
							{
								node.disabled = true ;
								//Element.setOpacity(node, 0.3) ;
							}
						}
						else
						{
							node.disabled = false ;
							node.checked = true ;
							//Element.setOpacity(node, 0.99) ;
						}
					}
				}
				this.goLinks() ;
			},
			
			// de l'Object    SE.Comparator
			goLinks: function() {
				if (this.productIDs.length>1)
				{
					var el = $(SE.Config.comparatorLink1) ;
					if (el)
					{
						el.onclick = function() { SE.Comparator.go(); return false; } ;
						Element.setOpacity(el, 0.99) ;
						// FS 2006-09-26
						Element.setStyle(el, { "color": "" }) ;
					}

					var el = $(SE.Config.comparatorLink2) ;
					if (el)
					{
						el.onclick = function() { SE.Comparator.go(); return false; } ;
						Element.setOpacity(el, 0.99) ;
						// FS 2006-09-26
						Element.setStyle(el, { "color": "" }) ;
					}
				}
				else
				{
					var el = $(SE.Config.comparatorLink1) ;
					if (el)
					{
						el.onclick = function() { return false ;} ;
						Element.setOpacity(el, 0.3) ;
						// FS 2006-09-26
						Element.setStyle(el, { "color": "#AAAAAA" }) ;
					}

					var el = $(SE.Config.comparatorLink2) ;
					if (el)
					{
						el.onclick = function() { return false ;} ;
						Element.setOpacity(el, 0.3) ;
						// FS 2006-09-26
						Element.setStyle(el, { "color": "#AAAAAA" }) ;
					}
				}	
			},
			
			// de l'Object    SE.Comparator
			go: function() {
				var n = this.productIDs.length ;
				var pairs = [] ;
				for(var i=0; i<n; i++)
				{
					pairs.push("productIDs["+i+"]="+escape(this.productIDs[i])) ;
				}
				window.location = SE.Config.url.catalogueComparator+"?idnoeud=" + SE.Zone.sectionID +"&search=" + SE.Results.search +"&" + pairs.join("&") ;
			},
			
			initialize: function() {
					    this.objectClass = "Comparator" ;
			}
		}),


		// Object    SE.Results
		Results: Object.extend(new Object(), {
			criteria: [],
			
			// de l'Object    SE.Results
			preSelectionID: function(preselectionID) {
				if(this.element)
				{
					SE.debug("SE.Results.preSelectionID("+preselectionID+")") ;
					this.preselectionID = preselectionID ;
      
					// remove all existing nodes
					Element.hide(this.element) ;

					while(this.element.firstChild)
					{
						this.element.removeChild(this.element.firstChild) ;
					}
				
					this.spinner = SE.createSpinner(this.element) ;
					Element.show(this.element) ;
					this.onDrawing() ;
				
					SE.Zone.clearCriteria() ;
					this.drawPage(0) ;
			
					SE.Zone.draw(true) ;
				}
			},
			
			// de l'Object    SE.Results
			preSelectionIDSynchrone: function(preselectionID) {
				if(this.element)
				{
				
					SE.debug("SE.Results.preSelectionIDSynchrone("+preselectionID+")") ;
					this.preselectionID = preselectionID ;
      
					// remove all existing nodes
					Element.hide(this.element) ;

					while(this.element.firstChild)
					{
						this.element.removeChild(this.element.firstChild) ;
					}
				
					this.spinner = SE.createSpinner(this.element) ;
					Element.show(this.element) ;
					this.onDrawing() ;
				
					SE.Zone.clearCriteria() ;
					this.drawPageSynchrone(0) ;
			
					SE.Zone.draw(true) ;
				}
			},
			
			// de l'Object    SE.Results
			preSelectionIDBis: function(preselectionID) {
			
				if(this.element)
				{
					SE.debug("SE.Results.preSelectionIDBis("+preselectionID+")") ;
					this.preselectionID = preselectionID ;
      
					// remove all existing nodes
					Element.hide(this.element) ;
					while(this.element.firstChild)
					{
						this.element.removeChild(this.element.firstChild) ;
					}
					this.spinner = SE.createSpinner(this.element) ;
					Element.show(this.element) ;
					this.onDrawing() ;
					SE.Zone.clearCriteria() ;
					SE.Zone.draw(true) ;
				}
			},
			
			// de l'Object    SE.Results
			sortResultsBy: function(criterionID, direction) {
				this.sortcriterionID = criterionID ;
				this.sortdirection = direction ;
				this.drawPage(0) ;
			},
			
			// de l'Object    SE.Results
			registerCriteria: function(criteria) {
				this.criteria = criteria ;
			},
			
			// de l'Object    SE.Results
			_drawPage: function(model, scroll) {
				if(this.element){
					SE.debug("SE.Results._drawPage("+model+")") ;
					var chaine="";
					// FS 2006-09-25 : permettra à d'autres routines d'exploiter les stats de ce model
					this.model = model ;
					
					if (model)
					{
						// remove all existing nodes
						while(this.element.firstChild)
						{
							this.element.removeChild(this.element.firstChild) ;
						}
						this.spinner = SE.createSpinner(this.element) ;
						
						dom(this.element, "div", { "innerHTML": model.html||SE.Config.message.emptyResult }) ;
						
						if (scroll)
						{
							window.scroll(0, 0) ;
						}
						
						for(var criterionID in model.statsByCriterionID)
						{
							var stats = model.statsByCriterionID[criterionID] ;
							for(var valueID in stats.valuesByID)
							{
								var el = $("stats-"+valueID) ;
								if (el) el.innerHTML = " ("+stats.valuesByID[valueID].count+")" ;
							}
						}
						SE.Comparator.sync(this.element) ;
						this.onReady() ;
					}
				}
			},
			
			// de l'Object    SE.Results
			drawPage: function(page, scroll) {
				if(this.element){
					this.page = page || 0 ;

					if(SE.ValideCookies){
						
						var ValeurCookies = "";
						
						ValeurCookies = SE.Results.preselectionID;
						
						if(SE.CookiesCriteres != undefined  && SE.CookiesCriteres != "")
							ValeurCookies += ";" + SE.CookiesCriteres;
						else
							ValeurCookies += ";";

						if(SE.Results.sortcriterionID != undefined && SE.Results.sortcriterionID != "")
							ValeurCookies += ";" + SE.Results.sortcriterionID;
						else
							ValeurCookies += ";";

						if(SE.Results.sortdirection != undefined && SE.Results.sortdirection != "")
							ValeurCookies += ";" + SE.Results.sortdirection;
						else
							ValeurCookies += ";";

						ValeurCookies += ";" + this.page;
						
						if(SE.ValeurCookiesEncours != ValeurCookies){
						
							if(SE.NbListeProduit == 0)
								DeleteCookiesListeProduit();
									
							if ((document.cookie.length < TailleMaxCookies) && (SE.NbListeProduit < MaxEnregistre)){
							
								SE.Results.ListeNum = SE.Results.ListeNum + 1;

								SE.NbListeProduit = SE.NbListeProduit + 1;
								
								clearTimeout(SE.ObjTimerBack);
								
								document.location = ("#ListeNum" + SE.Results.ListeNum);
							
								AncreUrlBack = ("ListeNum" & SE.Results.ListeNum);
							
								SE.ObjTimerBack = setTimeout(GestionHistory, 1000);
							}
							else{
								UpdateCookiesListeProduit();
								
								var sListe = ("ListeNum" + SE.Results.ListeNum + "=" + ValeurCookies);
								
								if ((document.cookie.length + sListe.length) > TailleMaxCookies){
									UpdateCookiesListeProduit();
									
									SE.Results.ListeNum = SE.Results.ListeNum - 1;
							
									clearTimeout(SE.ObjTimerBack);
								
									document.location = ("#ListeNum" + SE.Results.ListeNum);
							
									AncreUrlBack = ("ListeNum" & SE.Results.ListeNum);
							
									SE.ObjTimerBack = setTimeout(GestionHistory, 1000);
								}
							}
							
							setCookieListeProduit(("ListeNum" + SE.Results.ListeNum), ValeurCookies);
						
							SE.ValeurCookiesEncours = ValeurCookies;
						}
					}

//alert("cookie : " + document.cookie + "\nTaille  cookie : " + document.cookie.length);		
		
					SE.debug("SE.Results.drawPage("+page+")") ;
					// remove all existing nodes
					while(this.element.firstChild)
					{
						this.element.removeChild(this.element.firstChild) ;
					}
					this.spinner = SE.createSpinner(this.element) ;

					this.onLoading() ;
					var model = SE.Model.getResults(this.criteria,
					(page+0)*SE.Config.pagination.nRestultsPerPage,
					(page+1)*SE.Config.pagination.nRestultsPerPage-1,
					scroll) ;
				}
			},
			
			// de l'Object    SE.Results
			drawPageSynchrone: function(page, scroll) {
				if(this.element){
					this.page = page || 0 ;

					if(SE.ValideCookies){
						
						var ValeurCookies = "";
						
						ValeurCookies = SE.Results.preselectionID;
						
						if(SE.CookiesCriteres != undefined  && SE.CookiesCriteres != "")
							ValeurCookies += ";" + SE.CookiesCriteres;
						else
							ValeurCookies += ";";

						if(SE.Results.sortcriterionID != undefined && SE.Results.sortcriterionID != "")
							ValeurCookies += ";" + SE.Results.sortcriterionID;
						else
							ValeurCookies += ";";

						if(SE.Results.sortdirection != undefined && SE.Results.sortdirection != "")
							ValeurCookies += ";" + SE.Results.sortdirection;
						else
							ValeurCookies += ";";

						ValeurCookies += ";" + this.page;
						
						if(SE.ValeurCookiesEncours != ValeurCookies){
						
							if(SE.NbListeProduit == 0)
								DeleteCookiesListeProduit();
							
							if ((document.cookie.length < TailleMaxCookies) && (SE.NbListeProduit < MaxEnregistre)){
							
								SE.Results.ListeNum = SE.Results.ListeNum + 1;
									
								SE.NbListeProduit = SE.NbListeProduit + 1;
								
								clearTimeout(SE.ObjTimerBack);
								
								document.location = ("#ListeNum" + SE.Results.ListeNum);
							
								AncreUrlBack = ("ListeNum" + SE.Results.ListeNum);
							
								SE.ObjTimerBack = setTimeout(GestionHistory, 1000);
							}
							else{
								UpdateCookiesListeProduit();
							
								var sListe = ("ListeNum" + SE.Results.ListeNum + "=" + ValeurCookies);
								
								if ((document.cookie.length + sListe.length)> TailleMaxCookies){
									UpdateCookiesListeProduit();
									
									SE.Results.ListeNum = SE.Results.ListeNum - 1;
							
									clearTimeout(SE.ObjTimerBack);
								
									document.location = ("#ListeNum" + SE.Results.ListeNum);
							
									AncreUrlBack = ("ListeNum" + SE.Results.ListeNum);
							
									SE.ObjTimerBack = setTimeout(GestionHistory, 1000);
								}
							}
							
							setCookieListeProduit(("ListeNum" + SE.Results.ListeNum), ValeurCookies);
						
							SE.ValeurCookiesEncours = ValeurCookies;
						}
					}
					
//alert("cookie : " + document.cookie + "\nTaille  cookie : " + document.cookie.length);		
					
					SE.debug("SE.Results.drawPageSynchrone("+page+")") ;
					// remove all existing nodes
					while(this.element.firstChild)
					{
						this.element.removeChild(this.element.firstChild) ;
					}
					this.spinner = SE.createSpinner(this.element) ;

					this.onLoading() ;
					var model = SE.Model.getResultsSynchrone(this.criteria,
					(page+0)*SE.Config.pagination.nRestultsPerPage,
					(page+1)*SE.Config.pagination.nRestultsPerPage-1,
					scroll
					) ;				
				}
			},
			
			// de l'Object    SE.Results
			draw: function() {
				SE.debug("SE.Results.draw()") ;
				this.drawPage(0) ;
			},
			
			// de l'Object    SE.Results
			drawSynchrone: function() {
				SE.debug("SE.Results.drawSynchrone()") ;
				this.drawPageSynchrone(0) ;
			},
			
			// de l'Object    SE.Results
			onNetworkError: function() {
				this.spinner.lastChild.innerHTML = "Network error, retry in 3 seconds..." ;
				Element.show(this.spinner) ;
			},
			
			// de l'Object    SE.Results
			onDrawing: function() {
				this.spinner.lastChild.innerHTML = "Drawing UI..." ;
				Element.show(this.spinner) ;
			},

			// de l'Object    SE.Results
			onLoading: function() {
				this.spinner.lastChild.innerHTML = "Chargement du catalogue..." ;
				Element.show(this.spinner) ;
			},
			
			// de l'Object    SE.Results
			onReady: function() {
				if(this.spinner)
				{
					Element.hide(this.spinner) ;
					initZoomNDesc();
				}
			},
			
			// de l'Object    SE.Results
			onStartup: function() {
				if($('SEResults')){
					this.element = $('SEResults') ;
					if (this.element == null)
					{
						SE.error("div #SEResults not found in page !") ;
						this.element = dom(document.body, "div", {id: "SEResults"}) ;
					}
					this.spinner = SE.createSpinner(this.element) ;
					this.onReady();
				}
			},
			
			// de l'Object    SE.Results
			initialize: function() {
					    this.objectClass = "Results" ;
			}
		}),

		//("startup") de l'object SE
		startup: function()	{

			if(this.alreadyExist!=undefined)
				return false;
			
			this.alreadyExist=true;
			SE.debug("SE.startup begin") ;

			SE.Model.onStartup() ;
			SE.Zone.onStartup() ;
			SE.Request.onStartup() ;
			SE.Results.onStartup() ;
			SE.debug("SE.startup end") ;

			if (SE.Config.preConfig instanceof Object)
			{
				var config = SE.Config.preConfig ;
				var model = SE.Model.getSections(config.sectionID, config.search) ;
				if (model && model.objectsByID[config.sectionID])
				{
					
					SE.Zone.sectionID = config.sectionID ;
					var section = model.objectsByID[SE.Zone.sectionID] ;
					SE.Results.sectionID = config.sectionID;
					SE.Results.preselectionID = config.preSelectionID || section.defaultPreSelectionID ;
					SE.Results.sortcriterionID = config.sortCriterionID || section.defaultSortCriterionID ;
					SE.Results.sortdirection = config.sortDirection || section.defaultSortDirection ;
					SE.Results.search = config.search || "";
					SE.Results.preselectionIDstartUp = SE.Results.preselectionID;
					SE.Results.ListeNum = 0;
					delete config.sectionID ;
					delete config.preSelectionID ;
					delete config.sortCriterionID ;
					delete config.sortDirection ;
					delete config.search;
					
					if (config.productComp1ID > 0) {
						SE.Comparator.register (config.productComp1ID);
					}
					if (config.productComp2ID > 0) {
						SE.Comparator.register (config.productComp2ID);
					}
					if (config.productComp3ID > 0) {
						SE.Comparator.register (config.productComp3ID);
					}
					if (config.productComp4ID > 0) {
						SE.Comparator.register (config.productComp4ID);
					}
					if (config.productComp5ID > 0) {
						SE.Comparator.register (config.productComp5ID);
					}

					SE.Comparator.goLinks();
					
					delete config.productComp1ID
					delete config.productComp2ID
					delete config.productComp3ID
					delete config.productComp4ID
					delete config.productComp5ID
					
					model = SE.Model.getCriteria(SE.Results.preselectionID, SE.Results.search) ;
					if (model)
					{
						for(var criterionID in config)
						{
							if (model.objectsByID[criterionID])
							{
								var criterion = model.objectsByID[criterionID] ;
								var values = criterion.values ;
								var n = values.length ;
								for(var i=0; i<n; i++)
								{
									if (values[i].id == config[criterionID])
									{
										SE.Zone.addCriterion(criterionID, i) ;
										i = n ;
									}
								}
							}
							else
							{
								SE.warning("SE.Config.preConfig : unknown criterionID '"+criterionID+"' for sectionID '"+SE.Zone.sectionID+"'") ;
							}
						}
					}
				}
			}
			
			SE.ValideCookies = false;
			SE.ObjTimerBack;
			SE.NbListeProduit = 0;

			if( (document.location.href).indexOf("#ListeNum", 0) == -1){
				SE.Results.ListeNum = getDerCookieListeProduit();
				//SE.Zone.draw(!SE.Config.drawOnStartup) ;
				SE.Zone.drawSynchrone(!SE.Config.drawOnStartup) ;
			}
			
			GestionHistory();
			
			SE.ValideCookies = true;
	
		},
		
		// de l'object SE
		logger: function() {
			var element = $("debug") ;
			if (!element)
			{
				element = dom(document.body, "div", {
					"id":"debug",
					"style":"width:97%; height:200px; overflow:scroll; background-color:#C0C0C0; position:fixed; top:0px; padding:5px; z-index: 99999"
				})
			}
			else
			{
				Element.show(element) ;
			}
			if (SE.Config.loggerAutoVanish)
			{
				if (this.autoVanish)
				{
					clearInterval(this.autoVanish) ;
					this.autoVanish = null ;
				}
				this.autoVanish = setInterval(function() { Element.hide('debug') ; }, 3000) ;
			}
			return element ;
		},

		// de l'object SE
		debug: function(msg) {
			if (!SE.Config.debug) return ;
			element = SE.logger() ;
			if (element)
			{
				dom(element, "span", { "class":"seDebug", "className":"seDebug", "innerHTML":msg }) ;
				dom(element, "br", {}) ;
			}
		},

		// de l'object SE
		warning: function(msg) {
			if (!SE.Config.warning) return ;
			element = SE.logger() ;
			if (element)
			{
				dom(element, "span", { "class":"seWarning", "className":"seWarning", "innerHTML":msg }) ;
				dom(element, "br", {}) ;
			}
		},

		// de l'object SE
		error: function(msg) {
			if (!SE.Config.error) return ;
			element = SE.logger() ;
			if (element)
			{
				dom(element, "span", { "class":"seError", "className":"seError", "innerHTML":msg }) ;
				dom(element, "br", {}) ;
			}
		}

	}) ;

}).call() ; ////fin fonctions	

Element.setOpacity = function(element, value){
  element= $(element);
  if (value == 1){
    Element.setStyle(element, { opacity:
      (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
      0.999999 : null });
    if(/MSIE/.test(navigator.userAgent))
      Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
  } else {
    if(value < 0.00001) value = 0;
    Element.setStyle(element, {opacity: value});
    if(/MSIE/.test(navigator.userAgent))
     Element.setStyle(element,
       { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
                 'alpha(opacity='+value*100+')' });
  }
}


function linkdescEvnt()
{
	var myLnkDesc = getElementsByClass('linkdesc',document,'a');
	//alert('nombre de description : ' + myLnkDesc.length)
	for(i=0;i<myLnkDesc.length;i++)
	{
		myLnkDesc[i].onclick = function(){
			//alert('Chargement linkdescEvnt')
			obj = this.parentNode.getElementsByTagName('div')[0];
			if(obj)
			{
				switch(obj.className){
					case 'shortdesc':
						this.className='linkdesc_off';
						obj.className='displayBlock';
					break;
					case 'displayBlock':
						this.className='linkdesc';
						obj.className='shortdesc';
					break;
					default:
					break;
				}
			}
		}
	}

}

function openzoom()
{
	var myVisuProd = getElementsByClass('TDvisu',document,'td');
	//alert('nombre de zoom : ' + myVisuProd.length)
	for(i=0;i<myVisuProd.length;i++){
		myVisuProd[i].onmouseover = function(){
			//alert('Chargement openzoom')
			obj = this.getElementsByTagName('div')[0];
			if(obj)
			{
				switch(obj.className){
					case 'displayNone':
						obj.className='zoomVisu';
					break;
					default:
					break;
				}
			}
		}
		
		myVisuProd[i].onmouseout = function(){
			obj = this.getElementsByTagName('div')[0];
			if(obj)
			{
				switch(obj.className){
					case 'zoomVisu':
						obj.className='displayNone';
					break;
					default:
					break;
				}
			}
		}
	}
}
/** onload ***/
function initZoomNDesc()
{
	linkdescEvnt();
	openzoom();
}

if (typeof getElementsByClass != "function")
{
	function getElementsByClass(searchClass,node,tag) {
		var classElements = new Array();
		if ( node == null )
			node = document;
		if ( tag == null )
			tag = '*';
		var els = node.getElementsByTagName(tag);
		var elsLen = els.length;
		var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
		for (i = 0, j = 0; i < elsLen; i++) {
			if ( pattern.test(els[i].className) ) {
				classElements[j] = els[i];
				j++;
			}
		}
		return classElements;
	}
}
