function State(name) {
	this._name = name;
	this._x = 0;
	this._y = 0;
	
	this._load = function() {
		var position = $.cookie(this._name);
		
		if (position === null) {
			this._setDefault();
			return;
		}
			
		position = position.split("|");
		
		this._x = position[0];
		this._y = position[1];

		this.setPosition();
	};
	
	this.setPosition = function() {

		if ($('#' + this._name) != null) {
			try {
				$('#' + this._name).css('top', this.y() + "px");
				$('#' + this._name).css('left', this.x() + "px");
			} 
			catch(error) {
				// IE Hack
			};
		}	
	}
	
	this._save = function() {
		$.cookie(this._name, this.x() + "|" + this.y(), { expires: 365 });
	};
	
	this.set = function(x, y) {
		this._x = x;
		this._y = y;
		this._save();
	};
	
	this.x = function() {
		return this._x; 
	};
	
	this.y = function() {
		return this._y;
	};
	
	this._setDefault = function() {
		this._x = $('#' + this._name).position.left;
		this._y = $('#' + this._name).position.top;
	};
	
	this._load();
};


var Clip = {};

Clip.logo = new State("logo");
Clip.claim = new State("claim");
Clip.decor = new State("decor");

var Config = {
	markerTemplate: "<h2 style='display: inline;'>${name},</h2> <p style='display: inline;'>${address}, ${zipcode} ${city}</p><p id='comment-${formid}'>${comments}</p><br/><form name='${formid}' id='${formid}'><b>Neuer Kommentar:</b><br/><p style='padding-bottom: 5px;'><textarea class='place-comment' name='comment'></textarea></p><p><input type='hidden' name='id' value='${placeid}'/><input type='button' value='Kommentar abschicken' onclick='Comment.submit(\"${formid}\");'/></p></form>",
	commentTemplate: "<p><small>${date}</small><br/>${comment}</p>",
	contentPositionUp: "0px",
	contentPositionDown: "-450px",
	nzzPositionUp: ["0px", "-15px"],
	nzzPositionDown: ["-415px", '-300px'],
	defaultInfoContent: "<p><b>Bist Du die Wirtin, der Beizer? Hier kannst Deinen Betrieb vorstellen!</b><br/><br/>Schick uns ein Foto und einen kurzen Beschrieb der Beiz<br/>(&Ouml;ffnungszeiten, Menu, Spezielles, Homepage, Email, etc) an: <br/><br/> zigibeiz &Auml;T zigibeiz PUNKT ch <br/><br/>Wir werdens hier aufschalten.</p>"
};

var Map = {
	isInitialized: false,
	map: null,
	placeDescriptions: { },
	
	_init: function() {
	
		if (GBrowserIsCompatible()) {
	
			jQuery(window).unload(GUnload);
			
			
			this.map = new google.maps.Map(jQuery('#google-search-map').get()[0]);
			this.map.enableContinuousZoom();
			this.map.enableScrollWheelZoom();
			this.map.addControl(new GLargeMapControl());
			this.map.addControl(new GMenuMapTypeControl());
			this.map.setCenter(new GLatLng(47.215837,7.981567), 8);
				
//			GEvent.addListener(this.map, "moveend", function() { 
//				//Map._reload(); 
//			}); 

			this.isInitialized = true;
		}
	}, 

	_reload: function() {
			    
		 jQuery('form.search-form input[name=latitude_min]').val(
				 this.map.getBounds().getSouthWest().lat());
		 jQuery('form.search-form input[name=latitude_max]').val(
				 this.map.getBounds().getNorthEast().lat());
		 jQuery('form.search-form input[name=longitude_min]').val(
				 this.map.getBounds().getSouthWest().lng());
		 jQuery('form.search-form input[name=longitude_max]').val(
				 this. map.getBounds().getNorthEast().lng());
			
		 Server.reloadPlaces("", '/places/get');

	}, 

	loadMarkers: function (places) {
		
		if (!this.isInitialized)
			this._init();
		
		this.map.clearOverlays();	
		this.placeDescriptions = { };
		
		for(i = 0; i < places.length; i++) {
			var place = places[i];
			if (place.lon != "" && place.lat != ""
				 	&& place.lon != "0.0" && place.lat != "0.0") {
				
				this.addMarker(place);
			}
		};
	},
	
	addMarker: function(place) {
		
		
		var point = new GLatLng(place.lat, place.lon);

		this.placeDescriptions[place.id] = this._getMarkerContent(place);
		
		var marker = this._createMarker(point, place.id); 
		this.map.addOverlay(marker);
		
		if (place.highlighted == true) {
			//marker.openInfoWindowHtml(Map.placeDescriptions[place.id].content);
			var comments = new GInfoWindowTab('Kommentare', Map.placeDescriptions[place.id].content);
	    	var info = new GInfoWindowTab('Infos', Map.placeDescriptions[place.id].info);
	    	marker.openInfoWindowTabsHtml([comments, info]);
		}	
	}, 
	
	_createMarker: function (point, idOfInfoElement) {
//	    var marker = new GMarker(point);
//	    
//	    GEvent.addListener(marker, "click", function() {  
//		    marker.openInfoWindowHtml(Map.placeDescriptions[idOfInfoElement].content);
//		});
//	    
//	    return marker;
		
		var marker = new GMarker(point);
        GEvent.addListener(marker, "click", function() {
    		var comments = new GInfoWindowTab('Kommentare', Map.placeDescriptions[idOfInfoElement].content);
        	var info = new GInfoWindowTab('Infos', Map.placeDescriptions[idOfInfoElement].info);
        	marker.openInfoWindowTabsHtml([comments, info]);
        });
        return marker;

	},

	
	_getMarkerContent: function(place) {
		var formid = "form-" + Math.floor(Math.random()*1001);
		var marker = {};
		marker.content = Config.markerTemplate.replace("${name}", place.name)
		 		.replace(/\${comments}/g, this._getCommentsContent(place.comments))
		 		.replace(/\${placeid}/g, place.id)
		 		.replace(/\${address}/g, place.address)
		 		.replace(/\${zipcode}/g, place.zipcode)
		 		.replace(/\${city}/g, place.city)
		 		.replace(/\${formid}/g, formid);
				//.replace(/\${address}/g, place.address);
		marker.id = formid;
		marker.info = Config.defaultInfoContent.replace("${name}", place.name);
		return marker;
	},
	
	_getCommentsContent: function(comments) {
		var strComments = "";
		
		for(var i = 0; i < comments.length; i++) {
			var comment = comments[i];
			var strComment = Config.commentTemplate.replace("${date}", comment.date)
	 				.replace(/\${comment}/g, comment.comment.replace(/\n/g, "<br/>"));
			strComments += strComment;
		}
		
		return strComments;
	}
};

var Server = {
	addPlace: function(data, action) {
		this._request(data, action, 'html', function(result) {
			  jQuery('#cont').html(result);
		  });
	},
	
	addComment: function(data, action, callback) {
		this._request(data, action, 'json', function(result) {
			Map.addMarker(result);
		});
	},
	
	reloadPlaces: function(data, action) {
		this._request(data, action, 'json', function(result) {
			Map.loadMarkers(result);
		});
	},
	
	_request: function(data, action, datatype, callback) {
		jQuery.ajax({
			  type: "POST",
			  data: data,
			  url: action,
			  timeout: 45000,
			  dataType: datatype,
			  error: function() {
			    console.log("Failed to submit - ");
			  },
			  success: callback
		});
	}
};

var Comment = {
	submit: function(formid) {	
		Server.addComment($(document.forms[formid]).serialize(), '/places/detail');
	}	
};

var Content = {
	_isVisible: false,
	
	toggle: function() {
		if (Content._isVisible) {
			Content.hide();
		}
		else {
			Content.show();
		}
	} ,

	show: function() {
		if (Content._isVisible) {
			return;
		}
		
		this._moveTo(Config.contentPositionUp, function() {
			Content._isVisible = true;
		});
	},

	hide: function() {
		if (!Content._isVisible) {
			return;
		}
		
		this._moveTo(Config.contentPositionDown, function() {
			Content._isVisible = false;
		});
	},
	
	_moveTo: function(verticalPosition, callBackFunction) {
		$('#content').animate({
			bottom: verticalPosition
		}, 500, callBackFunction)
	},
	
	load: function(e) {
		e.stopPropagation();
		e.preventDefault();
		$(this).blur();

		$('#cont').load( $(this).attr('href') );

		Content.show();
	}
};




var NZZ = {
	_isVisible: true,
	
	toggle: function() {
		if (NZZ._isVisible) {
			NZZ.hide();
		}
		else {
			NZZ.show();
		}
	} ,

	show: function() {
		if (NZZ._isVisible) {
			return;
		}
		
		this._moveTo(Config.nzzPositionUp, function() {
			NZZ._isVisible = true;
		});
	},

	hide: function() {
		if (!NZZ._isVisible) {
			return;
		}
		
		this._moveTo(Config.nzzPositionDown, function() {
			NZZ._isVisible = false;
		});
	},
	
	_moveTo: function(position, callBackFunction) {
		$('#nzz').animate({
			bottom: position[0],
			right: position[1]
		}, 500, callBackFunction)
	},
	
	load: function(e) {
		e.stopPropagation();
		e.preventDefault();
		$(this).blur();

		$('#cont').load( $(this).attr('href') );

		NZZ.show();
	}
};



