//namespace definition
var Lsi = Lsi || {};

Lsi.SearchMap = function(config) {

	var defaults = {
		apiEndPoint  : null,
		id           : "lsi-map-content",
		address      : null,
		icon         : "http://icons.lsi.im/markers/purple.png"

	};

	$.extend(this, defaults, config);

};

Lsi.SearchMap.prototype = {

	apiKey         : "",
	apiEndPoint    : "",
	ads            : null,
	proj900913     : new OpenLayers.Projection("EPSG:900913"),
	proj4326       : new OpenLayers.Projection("EPSG:4326"),
	features       : null,
	ids            : null,
	currentIdIndex : null,
	currentAd      : null,
	basePath       : null,
	cutText        : 100,
	tabs           : ["title-ads", "title-grid"],
	

	init : function() {
		var me = this;
		
		//config map
		var options = {
			projection        : this.proj900913,
			displayProjection : this.proj4326,
			units             : "m",
			numZoomLevels     : 18
		};
		
		this.basePath = "#LsiSearchMap"+this.uniqId;

		var map = new OpenLayers.Map(this.id, options);
		
		var gmap = new OpenLayers.Layer.Google("Defaut"
		  // ROADMAP, the default
		);

		map.addLayers([gmap]);

		this.olMap = map;
			
		this.ads = new Lsi.SearchAds({
			apiKey      : this.apiKey,
			apiEndPoint : this.apiEndPoint
		});
		
		this.bindEvents();
		
		this.refreshMap();
		
	},
	
	bindEvents : function() {
		var me = this;
		var tabs = ['grid', 'ads'];
		var i;
		// bind onSubmit event
		$(this.basePath + " .grid form").submit({me:me},this.refreshMap);
		
		
		for (i = 0; i < tabs.length; i++) {
			$(this.basePath + " .title-"+tabs[i]).click(
					{me:me, tab:tabs[i]},
					function(event){
						$(me.basePath + ' .tab').hide();
						$(me.basePath + " .tab-"+event.data.tab).show();

					});
		}
		
		$(this.basePath + " .navigation .prevAd").click({me:me, mode:"prev"},this.switchAd);
		$(this.basePath + " .navigation .nextAd").click({me:me, mode:"next"},this.switchAd);
		
		$(this.basePath + " .actions .zoom").click({me:me},this.zoomAd);
		
		$(this.basePath + " .actions .adDetail").click({me:me},this.redirectAd);
		
		$(this.basePath + " .titles .title").click({me:me},function(event){
			me.addCurrentTabClass(event.target);
		});
		
		$(this.basePath).delegate(" .showAdDetail","click",{me:me},this.redirectAd);
		
	},

	refreshMap : function(event) {
		var params = {};
		var me;
		
		if (event == undefined) {
			me = this;
		} else {
			me = event.data.me
		}
		
		$.extend(params, {
				fields : 'll'
			}, 
			me.getFormArgs());
				
		me.ads.get(params, 
			me.createMarkers, 
			me);
			
		return false;
		
		
	},



	createMarkers : function(data) {
		
		if (data.error) {
			Lsi.Alert.show(data.error.message);
			return;
		}
			
		if (data.results.length == 0) {
			Lsi.Alert.show("Votre recherche n'a retourné aucun résultat",
				{
					duration : 2000
				});
			return;
		}
		
		var i, ad, point;
		var adsLayer = this.getAdsLayer();

		var features = [];
		var bounds = new OpenLayers.Bounds();
		
		
		for (i = 0; i < data.results.length; i++) {
			
			ad = data.results[i];
			
			
			
			if (ad.lat == 0 && ad.lng == 0)
				continue;
			
			point = new OpenLayers.Geometry.Point(ad.lng, ad.lat);
			
			features.push(new OpenLayers.Feature.Vector(
				point.transform(this.proj4326, this.proj900913),
				{ids : [ad.id]}
			));
				
			bounds.extend(point);
			
		}
		
		adsLayer.removeFeatures(adsLayer.features);
		adsLayer.addFeatures(features);
		
		this.olMap.zoomToExtent(bounds);
		

	},
	
	
	
	getFormArgs : function(){
		
		var params;
		var formId = this.basePath+" form ";
		var type = "";
		
		$.each($(formId+'input[name="multiselect_sg_select_types'+this.uniqId+'"]:checked'),
			function(index, value){
				type = type + ',' + $(value).val();
			});
		
		params = {
			localization : $(formId+'input[name="lsi_s_localization"]').val(), 
			transaction  : $(formId+'input[name="lsi_s_transaction"]:checked').val(),
			type         : type, 
			'extends'    : $(formId+'input[name="lsi_s_extends[]"]:checked').val(), 
			min_price    : $(formId+'input[name="lsi_s_min_price"]').val(), 
			max_price    : $(formId+'input[name="lsi_s_max_price"]').val(),
			max_surface  : $(formId+'input[name="lsi_s_max_surface"]').val(),
			min_surface  : $(formId+'input[name="lsi_s_min_surface"]').val(),
			rooms        : $(formId+'input[name="lsi_s_rooms"]').val(),
			is_new       : $(formId+'input[name="lsi_s_is_new"]').val()
			
		};
		
		return params;
		
	},
	
	showAdsDetail : function(ids){
		
		this.ids = ids;
		this.currentIdIndex = 0;
			
		this.ads.getOne(ids[0], 
			function(){
				
				var ad = arguments[0];
				
				$(this.basePath+" .ads").html(this.getHtmlAd(ad));
				
				$(this.basePath+" .navigation .numAds").html(
					eval(this.currentIdIndex + 1) + "/" + this.ids.length);
				
				this.currentAd = ad;
				this.getAdDetail(ids[0]);
			}, 
			this);
		
		
		
		$(this.basePath + ' .tab').hide();
		$(this.basePath + " .tab-ads").show();
		$(this.basePath + " .titles .title-ads").show();
		this.addCurrentTabClass("title-ads");
		
	},
	
	getAdDetail : function(adId) {
		
		
		
		$.ajax({
			url      : "/ajax/ad/ad-detail/"+adId,
			context  : this,
			success  : function(data, textStatus, jqXHR){

				$(this.basePath + ' .adDetailContent').html(data);
			
			},
			error    : function(jqXHR, textStatus, errorThrown){
				
				
			}
		});
		
	},
	
	addCurrentTabClass : function(tab){
		
		var currentTab;
		
		if (typeof tab == "object") {
			currentTab = $(tab);
		} else {
			currentTab = $(this.basePath + " .titles ."+tab);
		}
		
		for (var i = 0; i<this.tabs.length; i++) {
			$(this.basePath + " .titles ."+this.tabs[i]).removeClass("currentTab");
		}
		
		currentTab.addClass("currentTab");
		
	},
	
	limitText : function(text, limit) {
		
		var i;
		var textTab = text.split(" ");
			
		var returnText = "";
		
		for(i=0;i<textTab.length;i++) {

			returnText = returnText + ' ' + textTab[i];

			if(returnText.length > limit)
				break;
		}
		
		return returnText;
		
	},
	
	getHtmlAd : function(ad){
		var html = $(this.basePath+" .adTpl").html();
		var i;
		
		var text = ad.text;
		var endText = '... <span class="showAdDetail" data="'+ ad.id +'">plus d\'info</a>';
		
		if (this.cutText > 0)
			text = this.limitText(text, this.cutText);
		
		text = text + endText;
		
		var shortdesc = "";
		
		if (ad.nb_rooms > 0)
			shortdesc += ad.nb_rooms + " pièces";
		
		if (ad.surface > 0) {
			
			if (shortdesc != "")
				shortdesc += " - ";
			
			shortdesc += ad.surface + " m²";
		}
		
		
		var values = {
			"price"       : ad.price,
			"zipcode"     : ad.localization.zip_code,
			"city"        : ad.localization.city,
			"description" : text,
			"type"        : ad.type.name,
			"shortdesc"   : shortdesc
		};
		
		if (ad.photos.length > 0) {
			
			var url = ad.photos[0].url;
			
			values['photo'] = '<img src="'+url+'" />';
		} else {
			values['photo'] = "";
		}
		
		
		//yes, i use for..in.. but normally it's OK
		for (i in values)
			html = html.replace("{"+i+"}", values[i]);
		
		return html;
	
	},
	
	switchAd : function(event){
		
		var mode = event.data.mode;
		var me = event.data.me;
		
		
		if(mode == "prev" && me.currentIdIndex == 0)
			return;
		
		if(mode == "next" && me.currentIdIndex == eval(me.ids.length - 1))
			return;
		
		if(mode == "prev")
			me.currentIdIndex--;
		
		if(mode == "next")
			me.currentIdIndex++;
		
		me.ads.getOne(me.ids[me.currentIdIndex], 
			function(){
				
				var ad = arguments[0];
				
				$(this.basePath+" .ads").html(this.getHtmlAd(ad));
				
				$(this.basePath+" .navigation .numAds").html(
					eval(this.currentIdIndex + 1) + "/" + this.ids.length);
				
				this.currentAd = ad;
			}, 
			me);
	},
	
	zoomAd : function(event) {
		
		var me = event.data.me;
		
		if (me.currentAd == null)
			return;
		
		var ad = me.currentAd;
		var loc = ad.localization;
		
		var pos = new OpenLayers.LonLat(loc.lng, loc.lat);
		
		pos.transform(me.proj4326, me.proj900913);
		
		me.olMap.setCenter(pos, 12);
		
	},
	
	redirectAd : function(event) {
		
		var me = event.data.me;
				
		if (me.currentAd == null)
			return;
		
		var ad = me.currentAd;
		
		var location = '/redirect/ad/' + ad.id;
		
		window.open(location);
		
	},

	getAdsLayer : function() {
		
		var me = this;

		if (!this.adsLayer) {
			var strategy, clusters;

			var style = new OpenLayers.Style({

					externalGraphic : "${marker}",

					label           : "${nbOffres}",

					fontColor       : "${labelColor}",
					fontSize        : "11px",
					fontFamily      : "Arial",
					fontWeight      : "bold",
					labelAlign      : "cb",
					cursor          : "pointer",
					
					graphicHeight   : this.iconWidth,
					graphicWidth    : this.iconHeight,
					
					graphicZIndex   : "${zIndex}"
					
				}, {
					context: {

						marker : me.icon,

						labelColor : function(feature) {
							return "white";
						},

						nbOffres : function(feature) {
							if(!feature.cluster) return "";
							var total = 0, i, cnt = feature.attributes.count;
							for (i = 0; i < cnt; i++) {
								total += feature.cluster[i].attributes.ids.length;
							}

							return total;
						},

						width: function(feature) {
							return (feature.cluster) ? 2 : 1;
						},
						
						/*radius: function(feature) {
							var base = 13;
							if(!feature.cluster) {
								return base;
							}
							var cnt = feature.attributes.count;
							if (cnt === 1)
								return base;
							return Math.min(cnt, 4) + base;
						},*/
						/*radius : 13,*/
						
						
						zIndex : function(feature) {
							if (!feature.cluster)
								return 11;
							return 11 + feature.attributes.count;
						}

					}
				});

			strategy = new OpenLayers.Strategy.Cluster({
					distance : 25,
					treshold : 1
				});

			clusters = new OpenLayers.Layer.Vector("Clusters", {
					strategies      : [strategy],
					rendererOptions : {zIndexing: true},
					styleMap        : new OpenLayers.StyleMap({
							"default": style,
							"select": {
								fillColor: "#8aeeef",
								strokeColor: "#32a8a9"
							}
						})
				});


			var select = new OpenLayers.Control.SelectFeature(
				clusters, {});
			var me = this;
			this.olMap.addControl(select);
			select.activate();
			clusters.events.on({"featureselected": function(f) {
						window.f = f;
						var i, ids;
						ids = [];
						for (i = 0; i < f.feature.cluster.length; i++)
							ids.push(f.feature.cluster[i].data.ids[0]);


						this.showAdsDetail(ids);


					},
					scope:this

				});

			this.olMap.addLayer(clusters);

			this.adsLayer = clusters;

		}

		return this.adsLayer;

	}

};

