function happinessMaps(mapOptions){
	this.map=new google.maps.Map(document.getElementById("gmaps_canvas"),
			mapOptions);
};

function init(){
	happinessMaps.prototype={
		geocoder : new google.maps.Geocoder(),
		markers:[],
		bounds:null,
		site:'',
		shadowImage:function(){
			return new google.maps.MarkerImage(this.site+'/images/marker-shadow.png', new google.maps.Size(59,32), null,new google.maps.Point(10,32));
		},
		/**
		 * Adds markers and changes map for given locations 
		 */
		addLocations:function(locations){
			for ( var i in locations) {
				var postLocation=new google.maps.LatLng(locations[i].lat,locations[i].lng);
				if(this.bounds==null)
					this.bounds=new google.maps.LatLngBounds(postLocation,postLocation);
				else
					this.bounds.extend(postLocation);
				var marker = new google.maps.Marker({
					map : this.map,
					position : postLocation,
					title : locations[i].title,
					icon:new google.maps.MarkerImage(this.site+'/images/marker-'+locations[i].type.toLowerCase()+'.png', new google.maps.Size(15,30)),
					shadow:this.shadowImage()
				});
				this.markers.push(marker);
				if(locations[i].link){
					data.attachLink(marker, locations[i].link);
				}
			}
			if(this.bounds==null)
				this.bounds=new google.maps.LatLngBounds(new google.maps.LatLng(59, 25), new google.maps.LatLng(59, 25));
			this.resetView();
		},
		showItem: function(item){
			if(!$(item).attr('data-lat') || !$(item).attr('data-lng')) {
		        return;
		    }
			this.resetView(new google.maps.LatLng($(item).attr('data-lat'), $(item).attr('data-lng')));
			this.map.setZoom(11);
		},
		resetView: function(latlng){
			if(latlng==null)
				latlng=this.bounds;
			else
				latlng=new google.maps.LatLngBounds(latlng,latlng);
			this.map.fitBounds(latlng);
			if(this.map.getZoom()>7)
				this.map.setZoom(7);
		},
		updateAjax: function (id, postsData){
			var locations=new Array();
			jQuery(postsData).find('#'+id+" .postlist .post").each(function(){
				if(this.getAttribute('data-lat')!=0)
					locations.push({lat:this.getAttribute('data-lat'), lng:this.getAttribute('data-lng'), title:jQuery(this).find('p').text(), type:jQuery(this).hasClass('need')?'need':'offer'});
			});
			$('#'+id+" .postlist .post").hover(function (){$(this).addClass('active');data.showItem(this);},function(){$(this).removeClass('active');data.resetView();});
			data.clearMarkers();
			data.addLocations(locations);
		},
		registerLocation: function (loc,updateId, updateName){
			this.updateId=updateId;
			this.updateName=updateName;
			
			var latlng=new google.maps.LatLng(loc.lat,loc.lng);
			markerOpts={
				map : this.map,
				position : latlng,
				title : loc.title,
				draggable: true
			};
			if(loc.type){
				markerOpts['icon']=new google.maps.MarkerImage(this.site+'/images/marker-'+loc.type.toLowerCase()+'.png', new google.maps.Size(15,30));
				markerOpts['shadow']=this.shadowImage();
			}
			this.marker = new google.maps.Marker(markerOpts);
			this.map.setCenter(latlng);
			var self=this;
			google.maps.event.addListener(this.marker,'dragend',function(mouseEvent){
				self.setLocation(mouseEvent.latLng);
			});
		},
		setLocation: function (latlng) {
			var self=this;
			this.geocoder.geocode({'latLng':latlng},function(results, status){
				if (status == google.maps.GeocoderStatus.OK) {
					$(results).each(function(){
						//Hack to get LatLng object into JSON format
						this.geometry.location={lat:this.geometry.location.lat(),lng:this.geometry.location.lng()};
					});
					$.ajax({
						type:'post',
						url: locationParserUrl,
						data:{'results':JSON.stringify(results)},
						'success':function(data){
							$('#'+self.updateName).val(data.name);
							if(data.id){
								$('#'+self.updateId).val(data.id);
							}
							else{
								$('#'+self.updateId).val(JSON.stringify(data.result));
							}
						}
					});
				}
			});
		},
		searchLocation: function (name) {
			var self=this;
			this.geocoder.geocode({
				'address' : name
			},
				function(results, status) {
					if (status == google.maps.GeocoderStatus.OK) {
						var r = results[0];
						self.marker.setPosition(r.geometry.location);
						self.map.fitBounds(self.map.getBounds().extend(
								r.geometry.location));
						//Hack to get LatLng object into JSON format
						r.geometry.location={lat:r.geometry.location.lat(),lng:r.geometry.location.lng()};
						
						$('#'+self.updateId).val(JSON.stringify(r));
					}
			});
		},
		clearMarkers: function(){
			while(this.markers.length>0) {
				this.markers.pop().setMap(null);
			}
		},
		attachLink: function(marker, link) {
			google.maps.event.addListener(marker, "click", function() {
		        document.location = link;
		    });
	    }
	};
}

var data;
function map_initialize(draggable) {
	var latlng = new google.maps.LatLng(59, 25);
	var mapOptions = {
		zoom : 7,
		maxZoom: 11,
		center : latlng,
		mapTypeId : google.maps.MapTypeId.ROADMAP,
		draggable : draggable!=null && draggable
	};
	init();
	data=new happinessMaps(mapOptions);
	
	$('.postlist>.post').hover(function (){$(this).addClass('active');data.showItem(this);},function(){$(this).removeClass('active');data.resetView();});

}

