function decode_utf8_browser(utftext) {
			Nom = navigator.appName; 
			if (Nom == 'Microsoft Internet Explorer') { 
			    return utftext;
			} else {
			   return decode_utf8(utftext);
			}
		}
function entitycollection(method,url,entityType,params,async) {
	this.url=url+((url.indexOf('?')+1)?'&':'?')+'d='+(new Date()).getTime() || '';
	this.entityType=entityType || null;
	this.async=async || true;
	this.method=method || 'GET';
	this.params=params || null;
	this.entities=new Array();
	this.sorting;
	this.trident;
	this.duree;
	this.favorite;
	this.hasFavorite;
	var self=this;

	this.setparams = function(params) {
		this.params=params;
		this.method='POST';
	}
	this.load = function(urlparams, callback, arg1, arg2, arg3, arg4, arg5) {
		this.urlparams = urlparams;
		this.callback = callback;
		this.args = [arg1, arg2, arg3,arg4, arg5];

		this.xmlsrc=new xmlconnection();
		if (this.params != null) {
			this.method='POST';
		}

		if(!this.urlparams) {
			this.xmlsrc.open(this.method,this.url,this.async);
		} else {
			var url = this.url;
			url += (url.indexOf('?'))?'&':'?';
			var params = [];
			for(var pname in this.urlparams) {
				params.push(pname + '=' + encodeURIComponent(this.urlparams[pname]));
			}
			url = url + params.join('&');
			this.xmlsrc.open(this.method,url,this.async);
		}

		this.xmlsrc.onreadystatechange=function() {
			self.handleReadyState();
		}
		if (this.params != null) {
			this.xmlsrc.setRequestHeader('Content-Type','application/x-www-form-urlencoded;charset=UTF-8');
			this.xmlsrc.send(this.params);
		} else {
			this.xmlsrc.send(null);
		}
	}
	this.handleReadyState=function() {
		switch (this.xmlsrc.readyState) {
		  case 4:
			if (this.xmlsrc.status == 200) {
				self.toentities();
			}
		}
	}
	this.toentities=function() {
		var x = this.xmlsrc.responseXML.getElementsByTagName(this.entityType);
		switch (this.entityType) {
			case 'vi':
				var villagesList = this.xmlsrc.responseXML.getElementsByTagName('villages');
				villagesList = villagesList[0];
				this.sorting = villagesList.getAttribute('sort');
				this.trident = (villagesList.getAttribute('tris') == "true") ? true : false;
				this.vimode = villagesList.getAttribute('vimode');
				this.duree = (villagesList.getAttribute('duree') == "true") ? true : false;
				this.favorite = villagesList.getAttribute('favorite');
				this.hasFavorite = false;
				villages = map(makeVillage, x);
				break;
			case 'pe':
				// Only one preview element
				previews = makePreviewLocalization(x[0]);
				break;
			case 'pi':
				prices = {};
				map(makePrice, x);
				break;
			case 'me':
				messages = makeLocalizationMessages(x[0]);
				break;
			case 'ar':
				this.favorite = this.xmlsrc.responseXML.getElementsByTagName('archive')[0].getAttribute('val');
				break;
		}
		if(this.callback) {
			this.callback(this.args[0], this.args[1], this.args[2], this.args[3], this.args[4]);
		}
	}
	this.addparam=function(param,value) {
		this.url += '&'+param+'='+value;
	}
	this.reset=function() {
		this.entities=new Array();
	}
	this.setHasfavorite=function(x){
		this.hasFavorite = x;
	}
}

function makeLocalizationMessages(node) {
	var errors = node.getElementsByTagName('errors')[0];
	var villageTypes = node.getElementsByTagName('villageTypes')[0];
	var villagesCount = node.getElementsByTagName('villagesCount')[0];
	var mentionsLegales = node.getElementsByTagName('mentionsLegales')[0];
	return {
		errors : {
			nodeparture: errors.getElementsByTagName('nodeparture')[0].firstChild.data,
			birthdate: {
				single: errors.getElementsByTagName('single')[0].firstChild.data,
				multiple: errors.getElementsByTagName('multiple')[0].firstChild.data
			},
			villagecomparison: errors.getElementsByTagName('villagecomparison')[0].firstChild.data
		},
		mentionsLegales : {
			mentionLegaleTransport: mentionsLegales.getElementsByTagName('mentionLegale')[0].firstChild == null ? "" : mentionsLegales.getElementsByTagName('mentionLegale')[0].firstChild.data,
			mentionLegaleVV: mentionsLegales.getElementsByTagName('mentionLegale')[1].firstChild == null ? "" : mentionsLegales.getElementsByTagName('mentionLegale')[1].firstChild.data
		},
		titles : {
			visu: decode_utf8_browser(node.getElementsByTagName('visuImageTitle')[0].firstChild.data),
			strongPoint: node.getElementsByTagName('strongPointImageTitle')[0].firstChild.data
		},
		villageTypes : {
			adultsonly : villageTypes.getElementsByTagName('adultsonly')[0].firstChild.data,
			nochildcare : villageTypes.getElementsByTagName('nochildcare')[0].firstChild.data,
			withchildcare : villageTypes.getElementsByTagName('withchildcare')[0].firstChild.data
		},
		villagesCount : {
			none : getAround(villagesCount.getElementsByTagName('none')[0]),
			one : getAround(villagesCount.getElementsByTagName('one')[0]),
			multiple : getAround(villagesCount.getElementsByTagName('multiple')[0]),
			fittingcriteria : node.getElementsByTagName('fittingcriteria')[0].firstChild.data
		},
		helps : getHelps(node)
	}
}
function getAround(node) {
	return {
		pre: node.getElementsByTagName('pre')[0].firstChild.data,
		post: node.getElementsByTagName('post')[0].firstChild.data
	}
}
function getHelps(node){
	var helps = [];
	for (var i=0;i<node.getElementsByTagName('helps')[0].getElementsByTagName('help').length;i++){
		helps[i] = {
			id : node.getElementsByTagName('helps')[0].getElementsByTagName('help')[i].getAttribute('id'),
			text : node.getElementsByTagName('helps')[0].getElementsByTagName('help')[i].firstChild.data
		}
	}
	return helps;
}
function getIntegerContent(node) {
	return function (elementName) {
		if(node.getElementsByTagName(elementName)[0]) {
			return parseDec(node.getElementsByTagName(elementName)[0].firstChild.data);
		}
	}
}
function getISOFromBizarreDate(datestring) {
	var dateItems = /(\d{4})(\d{2})(\d{2})/.exec(datestring).slice(1);
	return new Date(parseInt(dateItems[0], 10), parseInt(dateItems[1], 10)-1, parseInt(dateItems[2], 10));
}
function strToBool(str) {
	if("true" == str) {
		return true;
	} else {
		return false;
	}
}
function parseDec(str) {
	return parseInt(str, 10);
}

// is not a number
function isNotNan(element) {
	return !isNaN(element);
}
function getEncadrements(array_of_encadrements) {
	// shift encadrements & OR them
	var out = [];
	for(var i=0, len=array_of_encadrements.length; i<len; ++i) {
		switch(array_of_encadrements[i]) {
			case 1:out.push(1);break;
			case 2:out.push(2);break;
			case 3:out.push(4);break;
			case 4:out.push(8);break;
		}
	}
	return reduce(function (a, b) { return a|b; }, out, 0);
}
function getRealVillageType(tpe) {
	switch(tpe) {
		case 0: return 1;
		case 1: return 2;
		case 2: return 4;
		case 3: return 8;
		case 4: return 16;
		case 5: return 32;
		case 6 : return 64;
		default: return 0;
	}
}
function getRealVillageTridents(tpe) {
	switch(tpe) {
		case 2: return 2;
		case 3: return 4;
		case 4: return 8;
		case 5: return 16;
		case 6 : return 32;
		default: return 0;
	}
}
function extractSeason(xmlSeason) {
	var act = xmlSeason.getElementsByTagName('acs')[0].firstChild;
	if (act != null) {
		act = xmlSeason.getElementsByTagName('acs')[0].firstChild.data.split(',');
	}
	else {
		act = "";
	}
	var enc = xmlSeason.getElementsByTagName('enc')[0].firstChild;
	if (enc != null) {
		enc = xmlSeason.getElementsByTagName('enc')[0].firstChild.data.split(',');
	}
	else {
		enc = "";
	}

	return {
		from: getISOFromBizarreDate(xmlSeason.getAttribute('dfrom')),
		to: getISOFromBizarreDate(xmlSeason.getAttribute('dto')),
		pe: replaceEmptyAttr(xmlSeason,'periode'),
		activities: filter(isNotNan, map(parseDec, act)),
		encadrements: getEncadrements(filter(isNotNan, map(parseDec, enc))),
		region: xmlSeason.getElementsByTagName('reg')[0].firstChild.data,
		timezone: parseDec(xmlSeason.getAttribute('h')),
		pays: (xmlSeason.getElementsByTagName('count')[0])?xmlSeason.getElementsByTagName('count')[0].firstChild.data:"",
		dest: (xmlSeason.getElementsByTagName('dest')[0])?xmlSeason.getElementsByTagName('dest')[0].firstChild.data:"",
		couleur: (xmlSeason.getElementsByTagName('couleur')[0])?xmlSeason.getElementsByTagName('couleur')[0].firstChild.data:"",
		plaisir: getRealVillageType(parseDec(replaceEmptyChild(xmlSeason.getElementsByTagName('pid')))),
		tridents: getRealVillageTridents(parseDec(xmlSeason.getElementsByTagName('t')[0].firstChild.data)),
		esp5Trid: getRealVillageTridents(parseDec(xmlSeason.getElementsByTagName('e5T')[0].firstChild.data)),
		spokenLang: strToBool(xmlSeason.getElementsByTagName('lang')[0].firstChild.data),
		typeVillage: parseDec(xmlSeason.getElementsByTagName('tv')[0].firstChild.data), // adultes - sans enfants - avec enfants
		typeV: parseDec(replaceEmptyChild(xmlSeason.getElementsByTagName('typeV'))), // montagne - mer - neige ...
		preview: extractPreview(xmlSeason.getElementsByTagName('preview')[0]),
		pictos: extractPictos(xmlSeason.getElementsByTagName('pictos')[0]),
		defaultPrices: extractDefaultPrices(xmlSeason.getElementsByTagName('defaultPrices')[0])
	}
}

// s'assure que le node en question n'est pas nul ou vide
// renvoie vide le cas echeant
function replaceEmptyChild(nod) {
	if (nod[0] == null  ||  nod[0].firstChild == null  ||  nod[0].firstChild.data == null) 
		return "";
	return nod[0].firstChild.data;
}

function replaceEmptyAttr(node, attr){
	if (node != null  &&  node.getAttribute( attr) != null) 
		return node.getAttribute( attr);
	return '';
}

function extractPreview(xmlPreview) {
	return {
		imgOpen: xmlPreview.getElementsByTagName('img_opened')[0].firstChild.data,
		imgClosed: xmlPreview.getElementsByTagName('img_closed')[0].firstChild.data,
		localization: xmlPreview.getElementsByTagName('geo')[0].firstChild.data,
		strongPoints: map(function (node) { if(node.firstChild!=null){ return node.firstChild.data;}else{return '';} }, xmlPreview.getElementsByTagName('adv')).slice(0,4)
	}
}
function extractPictos(xmlPictos) {
	if (!xmlPictos) {return;} 
	return {
		confort: (xmlPictos.getElementsByTagName('confort')[0].firstChild!=null)?xmlPictos.getElementsByTagName('confort')[0].firstChild.data:"",
		cible: map(function (node) { if(node!=null){ return extractPictosChilds(node);}else{return '';} }, xmlPictos.getElementsByTagName('cible')[0].getElementsByTagName('picto')).slice(),
		activites: map(function (node) { if(node!=null){ return extractPictosChilds(node);}else{return '';} }, xmlPictos.getElementsByTagName('activites')[0].getElementsByTagName('picto')).slice(),
		produits: map(function (node) { if(node!=null){ return extractPictosChilds(node);}else{return '';} }, xmlPictos.getElementsByTagName('produits')[0].getElementsByTagName('picto')).slice()
	}
}
function extractDefaultPrices(xmlDefaultPrices) {
	if (!xmlDefaultPrices) {return;} 
	return {
		priceMinVV: (typeof xmlDefaultPrices.getElementsByTagName('priceMinVV')[0] == "undefined" || xmlDefaultPrices.getElementsByTagName('priceMinVV')[0] == null)? null : xmlDefaultPrices.getElementsByTagName('priceMinVV')[0].firstChild.data,
		dateMinVV: (typeof xmlDefaultPrices.getElementsByTagName('dateMinVV')[0] == "undefined" || xmlDefaultPrices.getElementsByTagName('dateMinVV')[0] == null)? null : xmlDefaultPrices.getElementsByTagName('dateMinVV')[0].firstChild.data,
		priceMinPackage: (typeof xmlDefaultPrices.getElementsByTagName('priceMinPackage')[0] == "undefined" ||  xmlDefaultPrices.getElementsByTagName('priceMinPackage')[0] == null)? null : xmlDefaultPrices.getElementsByTagName('priceMinPackage')[0].firstChild.data,
		dateMinPackage: (typeof xmlDefaultPrices.getElementsByTagName('dateMinPackage')[0] == "undefined" || xmlDefaultPrices.getElementsByTagName('dateMinPackage')[0] == null)? null : xmlDefaultPrices.getElementsByTagName('dateMinPackage')[0].firstChild.data
	}
}
function extractPictosChilds(node) {
	return {
		cssClass: (node!=null)?node.getAttribute('class'):"",
		title: (node!=null)?node.getAttribute('title'):""
	}
}
function makeVillage(xmlNode) {
	if (xmlNode.getAttribute('favorite')=="true"){
		villages_collection.setHasfavorite(true);
	}
	var summer = xmlNode.getElementsByTagName('s')[0];
	var winter = xmlNode.getElementsByTagName('w')[0];
	var village = {
		id: xmlNode.getAttribute('id'),
		defaultSaison: xmlNode.getAttribute('defaultSaison'),
		vendu: (xmlNode.getAttribute('vendu')=="true")?true:false,
		name: xmlNode.getElementsByTagName('name')[0].firstChild.data,
		favorite: (xmlNode.getAttribute('favorite')=="true")?true:false,
		isWinter: Boolean(parseInt(xmlNode.getAttribute('hiver'))),
		name: xmlNode.getElementsByTagName('name')[0].firstChild.data,
		selected: false
	}
	if(summer) {
		if(summer.getElementsByTagName('*').length > 0) {
			village.summer = extractSeason(summer);
		}
	}
	if(winter) {
		if(winter.getElementsByTagName('*').length > 0) {
			village.winter = extractSeason(winter);
		}
	}
	return setCurrentSeason(village);
}
function makePrice(xmlNode) {
	var getElem = getIntegerContent(xmlNode);
	prices[xmlNode.getAttribute('vid')] = [getElem('ad'), getElem('ki'), getElem('mi'), getElem('pe'), getElem('ba'), xmlNode.getAttribute('dispo')=="false"?false:true, xmlNode.getAttribute('duration')?xmlNode.getAttribute('duration'):0];
}
function makePreviewLocalization(xmlNode) {
	var currencyNode = xmlNode.getElementsByTagName('currency')[0];
	return {
		price: xmlNode.getElementsByTagName('pricetext')[0].firstChild.data,
		date: xmlNode.getElementsByTagName("datetext")[0].firstChild.data,
		duration: xmlNode.getElementsByTagName("durationtext")[0].firstChild.data,
		durationDate: xmlNode.getElementsByTagName("durationtext1")[0].firstChild.data,
		preview: xmlNode.getElementsByTagName('preview')[0].firstChild.data,
		details : xmlNode.getElementsByTagName('details')[0].firstChild.data,
		compare : xmlNode.getElementsByTagName('compare')[0].firstChild.data,
		book : xmlNode.getElementsByTagName('book')[0].firstChild.data,
		title : xmlNode.getElementsByTagName('title')[0].firstChild.data,
		pour : xmlNode.getElementsByTagName('durationtext')[0].firstChild.data,
		adultes : xmlNode.getElementsByTagName('adultes')[0].firstChild.data,
		children : xmlNode.getElementsByTagName('children')[0].firstChild.data,
		and : xmlNode.getElementsByTagName('and')[0].firstChild.data,
		villageClosed : decode_utf8_browser(xmlNode.getElementsByTagName('villageClosed')[0].firstChild.data),
		currency : currencyNode.firstChild.data,
		prefixPosition : Boolean(parseInt(currencyNode.getAttribute('prefix'), 10)),
		priceUnavailable : xmlNode.getElementsByTagName('priceUnavailable')[0].firstChild == null ? "" : xmlNode.getElementsByTagName('priceUnavailable')[0].firstChild.data,
		pricePerAdults : xmlNode.getElementsByTagName('pricePerAdults')[0].firstChild == null ? "" : xmlNode.getElementsByTagName('pricePerAdults')[0].firstChild.data
	};
}
