function map_core() {
	
	/*#####################################################
	# var init
	#####################################################*/
	var listing_values = {},
		listing_keys = {},
		listing_keys_actu = '',
		detail_values = {},
		zoom_actu = 0,
		page_actu = 1,
		temp,
		pos = {},
		$this,
		blocs = new Array();
	
	var carnet_values = {},
		carnet_keys = {},
		carnet_keys_actu = '';
		
	var viewports = new Array();
		viewports['x'] = '-1';
		viewports['y'] = '-1';
	var viewable = new Array();
	
	var scrolls = new Array();
		scrolls['x'] = '-1';
		scrolls['y'] = '-1';
		
	/*#####################################################
	# count function
	#####################################################*/
	function count(obj){
	
		var t=0;
		for(var z in obj) {
			t++;
		}
	
		return t;
	}
	
	/*#####################################################
	# viewport function
	#####################################################*/
	function viewPort(){

		var map = $this.opts.map;
		var path = $this.opts.path.image;
		
		//take scroll
		var scroll = new Array();
			scroll['x'] = $(map).scrollLeft();
			scroll['y'] = $(map).scrollTop();
		
		//take size
		var size = new Array();
			size['x'] = parseInt($(map).css('width'));
			size['y'] = parseInt($(map).css('height'));
		
		$(map).children('div').eq(0).css('width');
		
		var xx=parseInt(scroll['x'])/blocs['width'];
		var yy=parseInt(scroll['y'])/blocs['height'];
		
		var xxx=parseInt(size['x'])/blocs['width']+xx;
		var yyy=parseInt(size['y'])/blocs['height']+yy;
		
		if(parseInt(xxx)<xxx){xxx++;}
		if(parseInt(yyy)<yyy){yyy++;}
		
		xx++; // start at 1 not 0
		yy++; // start at 1 not 0
		
		if(xx != viewports['x'] || yy != viewports['y']){
			
			viewports['x'] = xx;
			viewports['y'] = yy;
			
			for(var x = parseInt(xx);x <= parseInt(xxx);x++){
				
				for(var y = parseInt(yy);y <= parseInt(yyy);y++){
					
					viewable[y+'_'+x] = 1;
				}
			}
			
			for(var x = 1;x <= $this.opts.zoom.level[zoom_actu].x;x++){
				
				for(var y = 1;y <= $this.opts.zoom.level[zoom_actu].y;y++){
					
					if(viewable[y+'_'+x]==1) {
						
						$('#map'+y+'_'+x).css('background',"url('"+path+'zoom'+zoom_actu+'/'+y+'_'+x+".png') no-repeat");
						viewable[y+'_'+x]=false;
					}
					else {
						
						$('#map'+y+'_'+x).css('background',"");
					}
				}
			}
		}
	}
	
	/*#####################################################
	# makePages method
	#####################################################*/
	function makePages () {
		if(listing_keys_actu) {
			
			page_actu = parseInt(page_actu);
			
			var listing = listing_keys[listing_keys_actu].keys;
			var length = listing.length;
			
			var nb_page = length / $this.opts.result_by_page;
			if(parseInt(nb_page) < nb_page){nb_page++;}
			nb_page = parseInt(nb_page);
			
			var next = page_actu + 1;
			if(next > nb_page){next = '';}
			
			var previous = page_actu-1;
			if(previous <= 0){previous = '';}
			
			var to = page_actu*$this.opts.result_by_page;
			if(to>length){to = length;}
		
			var html = {
					'total':length+'',
					'start': ((page_actu - 1) * 4 + 1),
					'to': to,
					'first': 1,
					'last': nb_page,
					'next': next,
					'previous': previous,
					'test' : (length>0) ? 1 : 0
				};
			
			var marger = 1;
			html.link = '';
			
			for(var x = 1; x <= 4;x++) {
			
				if(page_actu == 2){marger = 2;}
				else if(page_actu > 2){marger = 3;}
				
				if((x + page_actu-marger) != page_actu){
					
					html.link += ' <a href="#viewPage-'+(x+page_actu-marger)+'" class="page">'+(x+page_actu-marger)+'</a>';
				}
				else{
					
					html.link += ' <span class="page_active">'+(x+page_actu-marger)+'</span>';
					
				}
				if(x == nb_page){break;}            //limit page
				else if(page_actu == 1 && x == 3){break;}            //3 links max for the first page
				else if(page_actu == nb_page && x == 3){break;} //3 links max for the last page
			}
			

			if($this.opts.nav.type!='linear' && (nb_page-3)>=page_actu && nb_page>4) {
				html.link += ' ... ';
				for(var x=nb_page-1;x<=nb_page;x++) {
					html.link += ' <a href="#viewPage-'+x+'" class="page">'+x+'</a>';
				}
			}
			else if($this.opts.nav.type!='linear' && (nb_page-3)<=page_actu && nb_page>4) {
				var tmp='';
				for(var x=1;x<=2;x++) {
					tmp += ' <a href="#viewPage-'+x+'" class="page">'+x+'</a>';
				}
				
				html.link = tmp+' ...'+html.link;
			}
			
			
			html.resultats=html.start+' ?'+html.to;
			
			html.pages = ''
			var next_html = '';
			var previous_html = '';
			
			if(html.previous){				
				if($this.opts.nav.first) {
					previous_html +=' <a href="#viewPage-'+html.first+'" class="page '+$this.opts.nav.classPrev+'">'+$this.opts.nav.first+'</a> ';					
				}
				if($this.opts.nav.previous) {
					previous_html +=' <a href="#viewPage-'+html.previous+'" class="page '+$this.opts.nav.classPrev+'">'+$this.opts.nav.previous+'</a> ';					
				}			
			}
			else {
			
				if($this.opts.nav.view=='class') {
					if($this.opts.nav.first) {
						previous_html +=' <a href="#" class="page disabled '+$this.opts.nav.classPrev+'">'+$this.opts.nav.first+'</a> ';					
					}
					if($this.opts.nav.previous) {
						previous_html +=' <a href="#" class="page disabled '+$this.opts.nav.classPrev+'">'+$this.opts.nav.previous+'</a> ';					
					}
				}			
			}
			
			if(html.next){				
				if($this.opts.nav.next) {
					next_html +=' <a href="#viewPage-'+html.next+'" class="page '+$this.opts.nav.classNext+'">'+$this.opts.nav.next+'</a> ';					
				}
				if($this.opts.nav.last) {
					next_html +=' <a href="#viewPage-'+html.last+'" class="page '+$this.opts.nav.classNext+'">'+$this.opts.nav.last+'</a> ';					
				}				
			}
			else {
			
				if($this.opts.nav.view=='class') {
					if($this.opts.nav.next) {
						next_html +=' <a href="#" class="page disabled '+$this.opts.nav.classNext+'">'+$this.opts.nav.next+'</a> ';					
					}
					if($this.opts.nav.last) {
						next_html +=' <a href="#" class="page disabled '+$this.opts.nav.classNext+'">'+$this.opts.nav.last+'</a> ';					
					}
				}			
			}
			
			html.pages=previous_html+html.link+next_html;
			
			return html;
		}
	}
	
	function makeCarnetPages () {
		if(carnet_keys_actu) {
			
			page_actu = parseInt(page_actu);
			
			var carnet = carnet_keys[carnet_keys_actu].keys;
			var length = carnet.length;
			var html = {
					'total':length+'',
					'del_check':'',
					'test' : (length>0) ? 1 : 0
				};
			html.del_check = '<input type="checkbox" name="check_all" onclick="javascript:idfr.map.checkDeleteSelected(this);" />&nbsp;&nbsp;&nbsp;&nbsp;<a href="javascript:idfr.map.delCarnet();">Supprimer la s&eacute;lection</a>&nbsp;';
			
			return html;
		}
	}
	
	/*#####################################################
	# sorting method
	#####################################################*/
	function sorting(field, order, type) {
		
			
			type = (type) ? type : 'string';
		/*
			
			var tmp = new Array();
			var c = 0;
			for(var x in datas) {
				tmp[c] = datas[x];
				c++;
			}	*/
			
			var tmp = new Array();
			var id='';
			var listing = listing_keys[listing_keys_actu].keys;
			
			for(var w in listing) {
				id = listing[w];
				tmp.push(listing_values[id]);			
			}			
	
			var sorting_data = function(a,b) {					
				var s = '';
				
				if(type == 'int') {
					a[field] = parseInt(a[field]);
					b[field] = parseInt(b[field]);
				}
				else if(type == 'float') {
					a[field] = parseFloat(a[field]);
					b[field] = parseFloat(b[field]);
				}
				
				if(isNaN(a[field]) && isNaN(b[field]) && (type == 'int' || type == 'float')) {
					s = 0;
				}
				else if((isNaN(b[field]) || b[field]=='') && (type == 'int' || type == 'float')) {
					s = -1;					
				}
				else if((isNaN(a[field]) || a[field]=='') && (type == 'int' || type == 'float')) {
					s = 1;
				}
				else if(order.toLowerCase() == 'asc'){
					s = (a[field] == b[field]) ? 0 : ((a[field] < b[field]) ? -1 : 1);
				}
				else {
					s = (a[field] == b[field]) ? 0 : ((a[field] < b[field]) ? 1 : -1);
				}				
				//console.log(a[field]+' == '+b[field]+' -> '+s);
				
				return s;
			}	
		
			tmp = tmp.sort(sorting_data);
			
			/*			
			c = 0;
			for(var x in datas) {
				datas[x] = tmp[c];
				c++;
			}		*/
			var tmp2 = new Array();
			for(var z in tmp) {
				tmp2.push(tmp[z].id);
			}
			listing_keys[listing_keys_actu].keys = tmp2;		
	}
	
	/*#####################################################
	# end of private functions
	#####################################################*/
	
	return {
		
		/*#####################################################
		# var init
		#####################################################*/
		//'zoom_scale' : 2.3,
		'version' : '1.1',
		
		'opts' : {
			'map' : '#map',
			'search' : '#search',
			'carnet' : '#carnet_listing',
			'tip' : '',
			'listing' : '',
			'detail' : '',
			'roadmap' : '',
			
			'zoom' : {
				'level':{
					1: {'x':3,'y':2,'factor':4},
					2: {'x':6,'y':4,'factor':2},
					3: {'x':12,'y':8,'factor':1}
				},
				'init': 1,
				'mousewheel':false
			},
			'layer' : {
				'route' : {'url':'routes.png','elem':'road','split':false,'hidden':false},
				'ville' : {'url':'ville.png','elem':'town','split':false,'hidden':false}
			},
			
			'tip_flag' : true,
			'result_by_page': 5,
			
			'path' : {
				'image' : './img/map/'
			},
			'nav' : {
				'previous' : '&lt;',
				'next' : '&gt;',
				'first' : '&lt;&lt;',
				'last' :'&gt;&gt;',
				'type' : 'linear',
				'view' : 'hide'
			},
			'message': {			
				'listing_empty':'No result for this search',
				'carnet_empty':'No result of the carnet'		
			}
		},
		
		/*#####################################################
		# Init method
		#####################################################*/
		init : function (options) {
			
			$.extend(this.opts,options);
			
			$this = this; // make a scope of this
			
			if($(this.opts.map)) {
				
				// init ajax*
				/*
				$.ajaxSetup({
					url: this.opts.path.proxy+'proxy.php',
					type: "POST",
					cache: false,
					scriptCharset: this.opts.ajax.charset,
					dataType : this.opts.ajax.type
				});*/
				
				//make popup_flag
				
				// make blocs
				var shortsel = this.opts.map.substring(1);
				shortsel = (this.opts.map.match(/^\#/g)) ? 'id="'+shortsel : 'class="'+shortsel;
				var map = $(this.opts.map+' div').before('<div '+shortsel+'_content" style="cursor:move"></div>').parent('div').css('overflow','hidden');
				
				pos.left = 0;
				pos.top = 0;
				// init zoom level
				this.zoom(this.opts.zoom.init);
				
				var mapping = $($this.opts.map+'_content');
				// init drag / scrolling
				map.mousedown(function(e){
					
					var left=map.scrollLeft();
					var top=map.scrollTop();
					var origineX = e.pageX+left;
					var origineY = e.pageY+top;
					$(this).bind('mousemove',function(e){
					    map.scrollLeft(origineX-e.pageX);
					    map.scrollTop(origineY-e.pageY);
					    $($this.opts.tip).hide();
					
					    scrolls['x']=parseInt(map.scrollLeft())/( parseInt($($this.opts.map+'_content').width()) - parseInt($($this.opts.map).width()) );
					    scrolls['y']=parseInt(map.scrollTop())/( parseInt($($this.opts.map+'_content').height()) - parseInt($($this.opts.map).height()) );
		
					    pos.left = ($($this.opts.map).scrollLeft()+(200))/$this.opts.zoom.level[zoom_actu].factor;
						pos.top = ($($this.opts.map).scrollTop()+(200))/$this.opts.zoom.level[zoom_actu].factor;	
					    
					    viewPort();
					}); 
					
					$(this).bind('mouseup',function(e){
					    $(this).unbind('mouseup'); 
					    $(this).unbind('mousemove');   
					    $(this).unbind('mouseleave');
					}).bind('mouseleave',function(e){
					    $(this).unbind('mouseup');
					    $(this).unbind('mousemove');
					    $(this).unbind('mouseleave');
					});
				
				});
				
				if(this.opts.zoom.mousewheel == true) {
					map.bind('mousewheel', function(event, delta) {
	            		var dir = delta > 0 ? 'up' : 'down';
	            		
	            		if(dir == 'up') {
	            			idfr.map.zoom('+1',function(old,level){
					
								$('#zoom #level').removeClass('level'+old).addClass('level'+level);				
								setTimeout(idfr.main.infobulle,250);
							});
	            		}
	            		else {
	            			idfr.map.zoom('-1',function(old,level){
					
								$('#zoom #level').removeClass('level'+old).addClass('level'+level);
								setTimeout(idfr.main.infobulle,250);
							});
	            		}
	                	
	            		return false;
	        		});
	        	}

				
				// init tip on flag
				if(this.opts.tip_flag == true) {
				
					$('.idfrmap_flag').live('mouseover',function(e){
				
						//$this.viewPictoPopup(e.data.picto_id);
					
					}).live("mouseout", function(e){
		
						//sto_hidelayer = setTimeout("$('#picto_popup').hide();", 450);
					
					});
				
					$(this.opts.map+' *').css('-Moz-User-Select','none');
				}
				
			}
			else {
				this.error('Config error !!!');
			}
			
			
		},
		
		/*#####################################################
		# Zoom method
		#####################################################*/
		zoom : function (level ,callback) {			
			//this.makeLocation('zoom',level);
			if(typeof level == 'string' && level.match(/[^+|^-]/)) {
				
				eval('level = zoom_actu'+level);
			}
			
			// zoom limiter
			if(level <= 0 || isNaN(level)){
				
				level = 1;
			}
			else if(!this.opts.zoom.level[level]){
				
				var max = 0;
				for(var x in this.opts.zoom.level){max++;}
				level = max;
			}
			
			//prevent double zooming
			if(level != zoom_actu)
			{
				// blocs reset
				var mapping = $(this.opts.map+'_content');  
				mapping.html('');
				
				//layer zooming
				var c='';
				for(var x in this.opts.layer){
					
					c = (this.opts.layer[x].classe) ? this.opts.layer[x].classe : this.opts.layer[x].elem;					
					$('#'+this.opts.layer[x].elem).removeClass(c + zoom_actu).addClass(c + level);  
				};
				
				// background mapping
				for (var y = 1;y <= this.opts.zoom.level[level].y;y++){
					
					for (var x = 1;x <= this.opts.zoom.level[level].x;x++){
						
						var elem = document.createElement("div");        
						$(elem).attr('id','map'+y+'_'+x).addClass('idfrmap_zoom'+level).appendTo(mapping);
					}
				}
				
				// reset width container of blocs
				var width = parseInt(mapping.children('div').eq(0).css('width'));
				var height = parseInt(mapping.children('div').eq(0).css('height'));
				mapping.width(width*this.opts.zoom.level[level].x);
				mapping.height(height*this.opts.zoom.level[level].y);
				
				blocs['width'] = width;
				blocs['height'] = height;
				
				if(callback){callback(zoom_actu,level);}
				
				
				var left = parseInt($(this.opts.map).width()); //-((level-1)*10);
				var top  = parseInt($(this.opts.map).height()); //-((level-1)*10);
				
				if(isNaN(scrolls['x']) || scrolls['x']<=0){scrolls['x']=0.5};
				if(isNaN(scrolls['y']) || scrolls['y']<=0){scrolls['y']=0.5};
				
				if (pos.left > 0) {
					left = (pos.left*$this.opts.zoom.level[level].factor)-200;
					top = (pos.top*$this.opts.zoom.level[level].factor)-200;
				}
				else {
					left = (220*$this.opts.zoom.level[level].factor)-200;
					top = (260*$this.opts.zoom.level[level].factor)-200;
				}
				
				$(this.opts.map).scrollLeft(left);
				$(this.opts.map).scrollTop(top);
				
				zoom_actu = level;
				viewports['x'] = '-1';
				viewports['y'] = '-1';
				
				viewPort();
				this.viewPicto(zoom_actu);
			}
		},
		
		/*#####################################################
		# layerHide method
		#####################################################*/
		layerHide : function (elem, bol ,callback) {
		
			this.makeLocation('layerHide',elem+'-'+bol);
			if(bol == true){$(this.opts.layer[elem].elem).css('display','none');}
			else         {$(this.opts.layer[elem].elem).css('display','block');}
			
			if(callback){callback();}
		},
		
		/*#####################################################
		# layerToggle method
		#####################################################*/
		layerToggle : function (elem ,callback) {  
		
			this.makeLocation('layerToggle',elem);
			var toggle = $(this.opts.layer[elem].elem);
			if(toggle.css('display') == 'block'){toggle.css('display','none');}
			else                                {toggle.css('display','block');}
			
			if(callback){callback();}
		},
		
		/*#####################################################
		# Search method
		#####################################################*/
		search : function (idform, action, subType ,callback) {
			
			page_actu = 1; // reset page;
			/*if(typeof idform == 'string') {
				var qs = $(idform).serializeArray();
				
				var keys = '';
				jQuery.each(qs, function(i, field){
					var name = field.name.replace(/\[\]/g,'');
					if(field.value){keys = keys + name + field.value;}
				});
			}
			else if(typeof idform == 'object') {
				
				var keys = '';
				var qs = new Array();
				for(var x in idform) {
					keys = keys + x + idform[x];
					qs.push({'name':x,'value':idform[x]});
				}
			}*/
			var subTypeTmp = subType.replace('\'','');
				subTypeTmp = subTypeTmp.replace(' ','_');
			var keys = idform+"_"+subTypeTmp;
			
			//if(!listing_keys[keys]) {
				
				var qs = new Array();
				
				qs.push({'name':'action','value':'getListing'});
				qs.push({'name':'offer_type','value':idform});
				qs.push({'name':'offer_sub_type','value':subType});
				
				this.query(qs,function(json){
				
					listing_keys[keys]={
						'keys':new Array(),
						'tpl_id':json.tpl_id
					};
					
					var idz = '';
					//for(var x in json.data){//bug on IE,the totle show more 1
					for(var x=0; x<(json.data).length; x++){
						
						idz = json.data[x].id;
						listing_values[idz]=json.data[x];
						listing_keys[keys].keys.push(idz);
					}
					
					for(var id in json.tpl){
						
						$this.templates[id]=json.tpl[id];
					}
					
					$this.viewListing(keys);
					$this.viewPicto(zoom_actu);
				});
			/*}
			else {
				this.viewListing(keys);
				this.viewPicto(zoom_actu);
			}*/		
			if(callback){setTimeout(callback,1000);}
		},
		/*#####################################################
		# initSelect method
		#####################################################*/
		initSubTypeSelect : function (type) {
			
			var qs = {action:'getSubType',offer_type:type};
			
			this.query(qs,function(json){
				var id_type = 0;
				var name_type = '';
				var str_select = '<div id="heb_type_select_title">Choisissez un type d\'h&eacute;bergement</div><br class="both" /><select onchange="idfr.map.ChangeSubTypeSelect(\''+type+'\',this.value);">';
				for(var x=0; x<(json.data).length; x++){
					
					id_type = json.data[x].id_type;
					value_type = value_type_tmp = json.data[x].value_type;
					label_type = label_type_tmp = json.data[x].label_type;
					if(value_type == 'All') value_type = '';
					str_select += '<option value="'+value_type+'">'+label_type+'</option>';
				}
				str_select += '</select>';
				$('#heb_type_select').html(str_select);
			});
		},
		ChangeSubTypeSelect : function (type,sub_type) {
			
			this.search(type,"",sub_type,function(){})
		},
		/*#####################################################
		# viewPicto method
		#####################################################*/
		viewPicto : function (zoom_level,callback) {
			
			var mapping = $(this.opts.map+'_content');		
			
			if(listing_keys_actu && listing_keys && mapping){
				
				var path = this.opts.path.image;
				
				var listing = listing_keys[listing_keys_actu].keys;
				var length = listing.length;		
				
				$('.idfrmap_flag').remove();
				var x='';
				for(var y in listing) {
					x = listing[y];
					if(listing_values[x]!=null && listing_values[x].x && listing_values[x].y) {
						var xx = parseInt(listing_values[x].x)* this.opts.zoom.level[zoom_level].factor;
						var yy = parseInt(listing_values[x].y)* this.opts.zoom.level[zoom_level].factor;
						var icon = listing_values[x].icon+'_'+zoom_actu;
						var picto = document.createElement('div');
						$(picto).attr('id','picto_'+x)
								.addClass('idfrmap_flag '+icon+' idfrmap_flag_zoom_'+zoom_level)
								.appendTo(mapping)
								.css({
									'top':(yy - $(picto).width()/2),
									'left':(xx - $(picto).height()/2)
								});	
					}				
				}	

				$(this.opts.listing).trigger('pictoReady');
			}
		},
		/*#####################################################
		# viewPictoPopup method
		#####################################################*/
		viewPictoPopup : function (picto_id, callback) {
			
			var picto_popup = $('#picto_popup');
			var picto_popup_left = parseInt($('#picto_'+picto_id).css('left') + 10);
			var picto_popup_top = parseInt($('#picto_'+picto_id).css('top') + 20);
			picto_popup.show().css({'top':picto_popup_top,'left':picto_popup_left});
			
			var titre = listing_values[picto_id].titre;
			var desc = listing_values[picto_id].desc;
			var html = {
					'id':picto_id,
					'titre':titre,
					'desc': desc
				};
			
			var view = this.makeView(html,'listing_popup');
			picto_popup.html(view);
		},
		
		/*#####################################################
		# viewListing method
		#####################################################*/
		viewListing : function (id_listing,callback) {
			
			$('#carnet_listing').hide();
			if(this.opts.listing){
				
				$this.makeLocation('viewPage',page_actu);
				
				var view = '';
				var listing = listing_keys[id_listing].keys;
				var items = 0;
				listing_keys_actu = id_listing;
				
				var x = (page_actu - 1) * this.opts.result_by_page;
				for(x;x < listing.length;x++) {
				
					items++;
					if(items <= this.opts.result_by_page){
						
						if(typeof(listing_values[(listing[x])])== 'object') {
							listing_values[(listing[x])].tpl_id = listing_keys[id_listing].tpl_id;
							view = view + this.makeView(listing_values[(listing[x])]);
						}
					}
				}
				
				if(!view) {
					view = this.opts.message.listing_empty;
				}
				var rpl = makePages();
				$.extend(rpl,{'listing': view});
				
				var view = this.makeView(rpl,'listing');
				
				if(callback){callback(view);}
				
				
				$(this.opts.listing).html(view);
	
				// make page clickable				
				$(this.opts.listing + ' a.page').each(function(){
				
					$(this).click(function(e){
						
					    var page = $(this).attr('href').split(/#viewPage\-/g);
					    e.preventDefault();
					    if(page[1]) {
							$this.viewPage(page[1]);
							$($this.opts.listing).trigger('changepage');
						}
					});
				});

				$(this.opts.listing).trigger('changepage');
			}
			else {
				
				idfr.error('viewListing : listing container do not exists');
				return false;
			}
		},
		
		/*#####################################################
		# viewPage method
		#####################################################*/
		viewPage : function (nb ,callback) {
		
			if(listing_keys_actu && listing_keys) {
				
				page_actu = nb;
				this.viewListing(listing_keys_actu);
			}
		},
		
		/*#####################################################
		# register events
		#####################################################*/
		registerEvent : function (events ,callback) {
		
			$(this.opts.listing).bind(events,callback);
		},
		
		/*#####################################################
		# getDetail method
		#####################################################*/
		getDetail : function (id,callback) {
		
			
			if(!detail_values[id]) {
				
				this.query({'id':id,'action':'getDetail'},function(json){
				
					detail_values[id] = json.data;
					
					for(var key in json.tpl){
						
						$this.templates[key] = json.tpl[key];
					}
					
					detail_values[id].tpl_id = json.tpl_id;					
					
					$this.viewDetail(json.tpl_id,id);
				});
			}
			else {
				
				this.viewDetail(detail_values[id].tpl_id,id);
			}
			
			if(callback){callback();}
		},
		
		/*#####################################################
		# setTooltip method
		#####################################################*/
		setTooltip : function (id,tpl) {	
				
			var view=this.makeView(listing_values[id], tpl);
			return view;		
		},
		
		/*#####################################################
		# prev / next -> offer
		#####################################################*/
		prevOfferNext : function(id) {			
				
			var r = {};	
			var stop = false;		
			
			var listing = listing_keys[listing_keys_actu].keys;
			
			for(var y in listing) {			
				
				r.next = listing[y];
				if(stop == true) {
					break;
				}
				if(id==listing[y]) {
					stop = true;
				}
				else {
					r.prev = listing[y];
				}
			}

			if(r.next == id) {
				r.next='';
			}
			
			return r;
		},
		
		prevCarnetNext : function(id) {			
				
			var r = {};	
			var stop = false;
			
			if (carnet_keys_actu) {
				var carnet = carnet_keys[carnet_keys_actu].keys;
				
				for(var y in carnet) {			
					
					r.next = carnet[y];
					if(stop == true) {
						break;
					}
					if(id==carnet[y]) {
						stop = true;
					}
					else {
						r.prev = carnet[y];
					}
				}
	
				if(r.next == id) {
					r.next='';
				}
			}
			
			return r;
		},
		/*#####################################################
		# viewDetail method
		#####################################################*/
		viewDetail : function (id_tpl,id_detail,callback) {

			if(this.opts.detail){
				
				// passed : id template /  detail value of right detail				
				var view=this.makeView(detail_values[id_detail],id_tpl);
				if(callback){callback(view);}			
				
				$(this.opts.detail).html(view);
			}
			else {
				
				this.error('viewDetail : detail container do not exists');
				return false;
			}
		},	
		
		/*#####################################################
		# sorting public method
		#####################################################*/
		sorting : function(key,type,dir,callback) {
		
			dir = (dir) ? dir : 'asc';
			sorting(key, dir, type);
			this.viewListing(listing_keys_actu);	
			if(typeof callback == 'function'){
				callback();
			}
		},
		/*#####################################################
		# carnet method
		#####################################################*/
		ajoutCarnet : function (index) {
			
			if(index == 'sejours'){
				var offre_id = $("#offre_id").html();
				var offre_identifier = $("#offre_identifier").html();
				var offre_titre = $("#offre_titre").html();
				var offre_resa = $("#offre_resa").html();
				var offre_lieu = $("#offre_lieu").html();
				var offre_zone = $("#offre_zone").html();
				var offre_photo = $("#offre_photo").html();
				var offre_etoile = $("#offre_etoile").html();
				var offre_price = $("#offre_price").html();
				var offre_confort = $("#offre_confort").html();
				var offre_x = $("#offre_coordX").html();
				var offre_y = $("#offre_coordY").html();
				
				var file_path = "module/carto/proxy.php";
				
				var view_link = "/module/carto/index.php?display=carnet";
			}
			else{
				var offre_id = listing_values[index].id_offre;
				var offre_identifier = listing_values[index].identifier;
				var offre_titre = listing_values[index].titre;
				var offre_resa = listing_values[index].resa;
				var offre_lieu = listing_values[index].lieu;
				var offre_zone = listing_values[index].zone;
				var offre_photo = listing_values[index].photo;
				var offre_etoile = listing_values[index].etoile;
				var offre_price = listing_values[index].price;
				var offre_confort = listing_values[index].confort;
				var offre_x = listing_values[index].x;
				var offre_y = listing_values[index].y;
				
				var file_path = "./proxy.php";
				
				var view_link = "javascript:idfr.map.getCarnet();";
			}
			
			var carnet_data = {
					index:index,
					id:offre_id,
					identifier:offre_identifier,
					titre:offre_titre,
					resa:offre_resa,
					lieu:offre_lieu,
					zone:offre_zone,
					photo:offre_photo,
					etoile:offre_etoile,
					price:offre_price,
					confort:offre_confort,
					coordX:offre_x,
					coordY:offre_y,
					action:'ajoutCarnet'
				};
			
			$.post(file_path, carnet_data, function(itemid){
				
				if(itemid > 0){
					$(".widget_carnet_content_ajout").html("<p>Vous avez ajout&eacute; cette offre &agrave; votre carnet :</p><p><strong>"+offre_titre+"<img src=\"/module/carto/img/empty.gif\" alt=\""+offre_etoile+"etoiles\" class=\"etoile"+offre_etoile+"\" /></strong></p>");
				}
				else{
					$(".widget_carnet_content_ajout").html("<p>Vous avez d&eacute;j&agrave; ajout&eacute; cette offre &agrave; votre carnet :</p><p><strong>"+offre_titre+"<img src=\"/module/carto/img/empty.gif\" alt=\""+offre_etoile+"etoiles\" class=\"etoile"+offre_etoile+"\" /></strong></p>");
				}
				
				$(".to_carnet_list_link").get(0).href = view_link;
				$(".to_carnet_list_img").get(0).href = view_link;
				
				$("#carnet").css("left",parseInt($(document).scrollLeft()+280)+"px");
				$("#carnet").css("top",parseInt($(document).scrollTop()+240)+"px");
				
				$("#carnet").show();
			});
			carnet_data = {};
		},
		
		getCarnet : function (callback) {
			
			var qs = {action:'getCarnet'};
			
			var keys = 'carnet';
			
			this.query(qs,function(json){
				
				carnet_keys[keys]={
					'keys':new Array(),
					'tpl_id':json.tpl_id
				};
				var idz = '';

//				for(var x in json.data){//bug on IE,the totle show more 1
				for(x=0; x<(json.data).length; x++){
					idz = json.data[x].id;
					carnet_values[idz]=json.data[x];
					carnet_keys[keys].keys.push(idz);
				}
				
				for(var id in json.tpl){
					
					$this.templates[id]=json.tpl[id];
				}
				$this.viewCarnet(keys);
			});
			
			if(callback){callback();}
		},
		viewCarnet : function (id_carnet,callback) {
			
			if(this.opts.carnet){
				
				var view = '';
				var carnet = carnet_keys[id_carnet].keys;
				var items = 0;
				carnet_keys_actu = id_carnet;
				
				var x = 0;
				for(x;x < carnet.length;x++) {
					
					if(typeof(carnet_values[(carnet[x])])== 'object') {
						
						carnet_values[(carnet[x])].tpl_id = carnet_keys[id_carnet].tpl_id;
						view = view + this.makeView(carnet_values[(carnet[x])]);
					}
				}
				
				if(!view) {
					
					view = this.opts.message.carnet_empty;
				}
				
				var rpl = makeCarnetPages();
				$.extend(rpl,{'carnet': view});
				
				var view = this.makeView(rpl,'carnet');
				
				if(callback){callback(view);}
				
				
				$(this.opts.carnet).html(view);
				/*
				// make page clickable				
				$(this.opts.carnet + ' a.page').each(function(){
				
					$(this).click(function(e){
						
					    var page = $(this).attr('href').split(/#viewCarnetPage\-/g);
					    e.preventDefault();
					    if(page[1]) {
							$this.viewCarnetPage(page[1]);
							$($this.opts.carnet).trigger('changepage');
						}
					});
				});

				$(this.opts.carnet).trigger('changepage');
				*/
				$('#carnet_listing').show();
				$('#search').removeClass('hide');
				$('#map_workspace,#carto_footer,#listing,#detail').hide();
				//ouvreFermeCarto();
				
				this.sortCarnet();
			}
		},
		
		printCarnet : function () {
			
			//window.open('print.php?action=printCarnet', '_blank');
		},
		
		delCarnet : function () {
			
			var offre_id_str = "";
			var offre_id = 0;
			$(".checkbox_del:checked").each(function(){
				
				offre_id = carnet_values[$(this).val()].identifier;
				offre_id_str += ",#**#"+offre_id+"#**#";
			});							
			
			var carnet_data = {
					offre_id_str:offre_id_str,
					action:'delCarnet'
				};
			
			$.post("./proxy.php", carnet_data, function(){
				$this.getCarnet();
			});
			
			$('#carnet_listing').show();
			$('#search').removeClass('hide');
			$('#map_workspace,#carto_footer,#listing,#detail').hide();
		},
		
		sortCarnet : function () {
			$(".drag_carnet").click(function() {
				$(this).css("border','1px");
			});
			$("#carnet_listing").sortable({
		        connectWith: '#carnet_listing',
		        handle: '.drag_carnet',
		        opacity: 0.6,
		        axis: 'y',
		        cursor: 'pointer',
		        items: '.block',
		        placeholder: 'ui-state-highlight',
		        //revert: true ,
		        update: function (event, ui) {
		            var sortItem = $("#carnet_listing").sortable('toArray').join(',');
		            $.post("./proxy.php", {
		            	action: 'sortCarnet',
		                sortItem: sortItem
		            });
		        }

		    }).disableSelection();
		},
		
		checkDeleteSelected : function (el){
			$(".checkbox_del").attr("checked",el.checked);
		}
	}
};
