(
	function() {
		var Global = this;

		var Animation = YAHOO.util.Anim;
		var Connect = YAHOO.util.Connect;
		var Dom = YAHOO.util.Dom;
		var Event = YAHOO.util.Event;
		var isIE = YAHOO.env.ua.ie;
		var JSON = YAHOO.lang.JSON;
		var Map = Forever.widget.Map;
		var Marker = google.maps.Marker;
		var Point = google.maps.LatLng;

		/**
		 * Logs searches
		 * @object logger
		 */
		var logger = {

			/**
			 * URI for saving stats
			 * @var uri
			 */
			uri: document.location.href,

			/**
			 * @method log
			 * @param data object
			 */
			log: function(data) {
				if(!Connect || !JSON) return;
				var queryString = "dist_id="+data.dist_id+"&medium="+data.medium;
				try {
					Connect.asyncRequest(
						'POST'
						,this.uri
						,{}
						,queryString
					);
				} catch(e) {
					// suppress error
				}
			}
		};

		/**
		 * Hide "javascript is needed" messages
		 */
		var hideNoJsMsg = function() {
			var noJs = Dom.getElementsByClassName("no-javascript");
			for(i = 0, l = noJs.length; i < l; i++) {
				noJs[i].parentNode.removeChild(noJs[i]);
			}
		};

		var init = function() {

			var address = Dom.get("address").value;

			if(address == "") {
				// since it's the only input field on the page, it should be focused
				Dom.get("address").focus();
			}

			var container = Dom.get("map");
			var country = document.getElementsByName("country");
			var form = Dom.getAncestorByTagName(Dom.get("address"), "form");
			var code = "";

			var map = new Map(container);
			map.setCenter(new Point(64.05297838071347, 15.29296875), 4);

			map.getMap().addControl(new GSmallZoomControl());

			form.reset();

			for(var i = 0; i < country.length; i++) {
				if(country[i].checked) {
					code = country[i].value;
					country = Global[country[i].value];
					break;
				}
			}

			country = typeof(country) == "string" ? country : "";

			if(country && address) {

				/**
				 * Search term gave no results from google maps
				 */
				map.noneEvent.subscribe(
					function(e) {
						var foundNoone;
						var language = location.href.split('/')[3];
						switch(language) {
							case 'da':
								foundNoone = "Ingen søgeresultater";
								break;
							case 'fi':
								foundNoone = "Ei löydy";
								break;
							case 'no':
								foundNoone = "Fant ingen";
								break;
							case 'sv':
								foundNoone = "Hittade ingen";
								break;
							case 'en':
							default:
								foundNoone = "Found none";
								break;
						}
						var p = document.createElement("p");
						p.setAttribute('id', 'foundNoone');
						p.innerHTML = foundNoone + ".";
						form.appendChild(p);
					}
				);

				/**
				 * Single distributor found
				 */
				map.singleEvent.subscribe(
					function(placemark) {
						if(placemark.AddressDetails.Country && typeof placemark.AddressDetails.Country == "object" && placemark.AddressDetails.Country.CountryNameCode != this.code) {
							return map.noneEvent.fire();
						}
						// bug fix, makes the map get a hit on "Djurgården", since that placemark object looks different than most others with an AddressDetails.AddressLine property instead of Country
						var country = typeof placemark.AddressDetails.Country == "object" ? placemark.AddressDetails.Country.CountryNameCode : code;
						this.getDistributorsByPosition(
							new Point(placemark.Point.coordinates[1], placemark.Point.coordinates[0]),
							country
						);
					}
				);

				/**
				 * More than one distributor found
				 */
				map.multipleEvent.subscribe(
					function(placemarks) {
						var multiple = Dom.getAncestorByClassName(this, "multiple");
						var addressField = Dom.get("address");
						if(placemarks.length == 2) {
							// prevents infinite loop when the soon to be proposed adresses look the same, for example "Kolmården"
							if(placemarks[0].Point.address == placemarks[1].Point.address) {
								return map.singleEvent.fire(placemarks[0]);
							}
						}

						for(var i = 0; i < placemarks.length; i++) {
							var placemark = placemarks[i];
							var link = document.createElement("a");

							var address = placemark.address;
							var details = placemark.AddressDetails;
							// bugfix, some placemark objects returned from google does not follow the blueprint very well
							var country = typeof details.Country == "object" ? details.Country.CountryName : null;

							link.innerHTML = address;

							address = address.replace(country, "");
							address = address.replace(/[, ]+/g, " ");
							address = address.replace(/(^ +| +$)/, "");

							Event.on(
								link
								,"click"
								,function(type, args) {
									this.value = args;
									Dom.getAncestorByTagName(this, "form").submit();
								}
								,address
								,addressField
							);

							link.href = '#';
							this.appendChild(document.createElement("br"));
							this.appendChild(link);
						}

						Dom.setStyle(multiple, "visibility", "hidden");
						Dom.setStyle(multiple, "display", "block");

						var region = Dom.getRegion(multiple);

						var animation = new Animation(multiple, { height: { from: 0, to: region.bottom - region.top } }).animate();

						setTimeout(
							function() {
								Dom.setStyle(multiple, "visibility", "visible");
							}
							,1
						);
					}
					,null
					,Dom.get("multiple")
				);

				/**
				 * Insert distributors as markers
				 */
				map.distributorEvent.subscribe(
					function(result) {
						if(result.status) {
							var distributors = Dom.get("distributors"), list = result.distributors, container = Dom.getAncestorByClassName(distributors, "list");

							for(var i = 0; i < list.length;) {
								var point = new Point(list[i].lat, list[i].lng);
								var marker = new Marker(point);
								do {
									point = next || point;
									var contact = document.createElement('div');
									contact.setAttribute('class', 'contact');
									if(list[i].name) {
										var name = document.createElement('p');
										name.setAttribute('class', 'name');
										name.innerHTML = list[i].name;
										contact.appendChild(name);
									}
									var web = document.createElement('p');
									contact.setAttribute('class', 'name');
									var webLink = document.createElement('a');
									webLink.setAttribute('target', '_blank');
									webLink.setAttribute('href', list[i].domain);
									webLink.innerHTML = list[i].organization ? list[i].organization : list[i].name;
									web.appendChild(webLink);
									web.innerHTML = "Web: " + web.innerHTML;
									contact.appendChild(web);
									Event.on(
										web.getElementsByTagName('a')[0]
		                                ,'click'
		                                ,function(ev, args) {
											logger.log(args);
										}
										,{ dist_id: list[i].dist_id, medium:'web' }
									);
									if(list[i].phone) {
										var phone = document.createElement('p');
										phone.setAttribute('class', 'phone');
										phone.innerHTML = "Tel: " + list[i].phone;
										contact.appendChild(phone);
									}
									if(list[i].email) {
										var email = document.createElement('p');
										email.setAttribute('class', 'email');
										var emailLink = document.createElement('a');
										emailLink.setAttribute('href', 'mailto:' + list[i].email);
										emailLink.innerHTML = list[i].email;
										email.appendChild(emailLink);
										email.innerHTML = "E-mail: " + email.innerHTML;
										contact.appendChild(email);
										Event.on(email.getElementsByTagName('a')[0], 'click', function(ev, args) {
											logger.log(args);
										}, {
											dist_id:list[i].dist_id,
											medium:'email'
										});
									}
									;

									// list item
							var distributor = document.createElement("div");
							var link = document.createElement("a");
							var description = document.createElement("div");

							link.innerHTML = list[i].name;
							link.href = "#";

							Event.on(link, "click", function(type, args) {
								this.openInfoWindowHtml(args.text);
								Event.stopEvent(type);
							}, {
								map:this,
								text:contact
							}, marker);

							var descriptionString = "";

							if(list[i].address != "") {
								descriptionString = list[i].address;
							}
							if(list[i].zipcode != "") {
								if(list[i].address != "") {
									descriptionString += ", ";
								}
								descriptionString += list[i].zipcode;
								if(list[i].city != "") {
									descriptionString += " " + list[i].city;
								}
							} else if(list[i].city != "") {
								if(list[i].address != "") {
									descriptionString += " ";
								}
								descriptionString += list[i].city;
							}

							description.innerHTML = descriptionString;
							description.className = "description";

							distributor.appendChild(link);
							distributor.appendChild(description);

							distributors.appendChild(distributor);

							if(++i >= list.length) {
								break;
							}
							var next = new Point(list[i].lat, list[i].lng);
						} while(point.equals(next));
						this.addMarker(marker);
						marker.bindInfoWindowHtml(contact);
					}

					this.autoZoom();

					Dom.setStyle(container, "visibility", "hidden");
					Dom.setStyle(container, "display", "block");

					var region = Dom.getRegion(container);

					var animation = new Animation(container, {
						height:{
							from:0,
							to:region.bottom - region.top
						}
					}).animate();

					setTimeout(function() {
						Dom.setStyle(container, "visibility", "visible");
					}, 1);
				}
			});
				map.code = code;
				// address must be entered before country, in order to make searches for postal codes accurate
				map.search(address+" "+country);
			}
		};

		Event.on(window, "load", hideNoJsMsg);
		Event.on(window, "load", init);
	}
)();
