﻿///<reference path="jquery-1.4.1-vsdoc.js"/>

var Teasers = function (items, options) {
	var _this = {
		settings: null,
		container: null,
		activeIndex: 0,
		scrollSpeed: 50,
		init: function () {
			_this.settings = jQuery.extend({
				handler: "#Teaser .body"
			}, options);


			_this.container = $(_this.settings.handler);
			_this.navigationHandler();
		},
		navigationHandler: function () {
			_this.container.find(".slider li a").click(function () {
				if ($(this).parent().is(".prev")) { // clicked previous
					if (_this.activeIndex > 0) {
						_this.navigate(_this.activeIndex - 1);
					}
				} else if ($(this).parent().is(".next")) { // clicked next
					if (_this.activeIndex < items.length - 1) {
						_this.navigate(_this.activeIndex + 1);
					}
				} else { // clicked normal
					_this.navigate($(this).parent().index() - 1);
				}
				return false;
			});
		},
		navigate: function (newIndex) {
			var movePixels;
			if (newIndex > _this.activeIndex) { // move forward
				movePixels = -1000;
			} else if (newIndex < _this.activeIndex) { // move backward
				movePixels = 1000;
			}

			if (movePixels) {
				$(".slider li img", _this.container).attr("src", function (index, attr) {
					if ($(this).parent().parent().index() == (newIndex + 1)) {
						return attr.replace("/inactive", "/active");
					} else {
						return attr.replace("/active", "/inactive");
					}
				});

				$(".image", _this.container).stop().animate({ left: movePixels }, _this.settings.scrollSpeed, "swing", function () {
					$(".image", _this.container).css({
						"background-image": "url(" + items[newIndex].Image + ")",
						"left": movePixels * -1
					});
					$(".content", _this.container).css({
						"width": items[newIndex].ContextWidth,
						"top": items[newIndex].PositionTop,
						"left": items[newIndex].PositionLeft
					});
					$("h1", _this.container).html(items[newIndex].Header);
					if (typeof (Cufon) == "function") {
						Cufon.refresh();
					}
					$(".itembody", _this.container).html(items[newIndex].Body).css("width", items[newIndex].TextBodyWidth);
					$("a.arrow-red-right-10px", _this.container).attr("href", items[newIndex].Url).text(items[newIndex].LinkText);

					$(".image", _this.container).animate({ left: 0 }, _this.settings.scrollSpeed, "swing", function () { });
				});

				_this.activeIndex = newIndex;
			}


		}


	};

	_this.init();
};

var stripTags = function (input) {
	return input.replace(/<\/?[^>]+>/gi, '');
};

var Maps = function (mapId, pageId) {
	var _this = {
		mapElement: null,
		gMap: null,
		gIcon: null,
		currentPoints: null,
		currentMarkers: null,
		currentInfoBox: null,
		listContainer: null,
		minimumZoom: 5,
		init: function () {
			if (typeof (google.maps.Map) !== "function") {
				alert("Google Maps API is not loaded");
				return;
			}

			_this.mapElement = document.getElementById(mapId);
			_this.listContainer = $("#localDistributors .list");

			_this.initMap();
			_this.initMarkers();
			_this.initEvents();
		},
		initMap: function () {
			var options = {
				center: new google.maps.LatLng(61.5, 17),
				zoom: 5,
				mapTypeControl: true,
				navigationControl: true,
				mapTypeId: google.maps.MapTypeId.HYBRID
			};
			_this.gMap = new google.maps.Map(_this.mapElement, options);

			_this.gIcon = new google.maps.MarkerImage("/Assets/Images/map-marker.png",
                                                      new google.maps.Size(34, 33),
                                                      new google.maps.Point(0, 0),
                                                      new google.maps.Point(16, 16));
		},
		initMarkers: function () {
			_this.loadDistributors(pageId);
		},
		initEvents: function () {
			$(".CountryDropDown").change(function () {
				_this.loadDistributors($(this).val());
			});
		},
		loadDistributors: function (rootId) {
			var data = {};
			if (rootId) {
				data.rootId = rootId;
			}

			if (_this.currentInfoBox != null) {
				_this.currentInfoBox.setMap(null);
				_this.currentInfoBox = null;
			}

			$.getJSON("/Assets/Services/Distributors.svc/Load", data, function (result) {
				_this.listContainer.empty();
				_this.clearOverlays();
				_this.currentPoints = [];
				_this.currentMarkers = [];

				$.each(result, function () {
					_this.addListItem(this);
					_this.addMarker(this);
				});

				$("#DistributorsPage #localDistributors .list").jScrollPane({ dragMaxHeight: 70, dragMinHeight: 30 });
				Cufon.refresh();

				_this.setCenter();
			});
		},
		addListItem: function (distributor) {
			var html = "" +
                         "<h3>" + distributor.Title + "</h3>" +
                         "<p>" +
						distributor.Body +
                         "<a href=\"" + distributor.Url + "\" rel=\"external\">" + TRANSLATE_READMORE + "</a><br />" +
                         "</p>";

			_this.listContainer.append(html).fadeIn();
		},
		addMarker: function (distributor) {
			var html = "" +
                         "<h3>" + stripTags(distributor.Title) + "</h3>" +
                         "<p>" +
                         distributor.Body + "<br/>" +
                         "<a href=\"" + distributor.Url + "\" rel=\"external\">" + TRANSLATE_READMORE + "</a><br />" +
                         "</p>";

			var latLng = new google.maps.LatLng(parseFloat(distributor.Latitude), parseFloat(distributor.Longitude));

			var marker = new google.maps.Marker({
				position: latLng,
				map: _this.gMap,
				title: distributor.Title,
				icon: _this.gIcon
			});

			google.maps.event.addListener(marker, "click", function (e) {
				if (_this.currentInfoBox != null) {
					_this.currentInfoBox.setMap(null);
				}

				_this.currentInfoBox = new InfoBox({ latlng: marker.getPosition(), map: _this.gMap, html: html });
			});

			_this.currentMarkers.push(marker);
			_this.currentPoints.push(latLng);
		},
		setCenter: function () {
			if (_this.currentPoints.length > 0) {
				var latlngbounds = new google.maps.LatLngBounds();
				for (var i = 0; i < _this.currentPoints.length; i++) {
					latlngbounds.extend(_this.currentPoints[i]);
				}

				_this.gMap.fitBounds(latlngbounds);
				_this.gMap.panToBounds(latlngbounds);

				if (_this.gMap.getZoom() > _this.minimumZoom) {
					_this.gMap.setZoom(_this.minimumZoom);
				}
			}
			else {
				_this.gMap.setCenter(new GLatLng(61.5, 17));
				_this.gMap.setZoom(5);
			}
		},
		clearOverlays: function () {
			if (_this.currentMarkers) {
				for (var i in _this.currentMarkers) {
					_this.currentMarkers[i].setMap(null);
				}
				_this.currentMarkers = [];
			}

		}
	};

	_this.init();

	return _this;
};

if (typeof (google) === "object") {
	/* An InfoBox is like an info window, but it displays
	* under the marker, opens quicker, and has flexible styling.
	* @param {GLatLng} latlng Point to place bar at
	* @param {Map} map The map on which to display this InfoBox.
	* @param {Object} opts Passes configuration options - content,
	*   offsetVertical, offsetHorizontal, className, height, width
	*/
	var InfoBox = function (opts) {
		google.maps.OverlayView.call(this);
		this.latlng_ = opts.latlng;
		this.map_ = opts.map;
		this.html = opts.html;
		this.offsetVertical_ = -195;
		this.offsetHorizontal_ = -50;
		this.height_ = 184;
		this.width_ = 300;

		var me = this;
		this.boundsChangedListener_ =
        google.maps.event.addListener(this.map_, "bounds_changed", function () {
			return me.panMap.apply(me);
        });

		// Once the properties of this OverlayView are initialized, set its map so
		// that we can display it.  This will trigger calls to panes_changed and
		// draw.
		this.setMap(this.map_);
	};

	/* InfoBox extends GOverlay class from the Google Maps API */
	InfoBox.prototype = new google.maps.OverlayView();

	/* Creates the DIV representing this InfoBox
	*/
	InfoBox.prototype.remove = function () {
		if (this.div_) {
			this.div_.parentNode.removeChild(this.div_);
			this.div_ = null;
		}
	};

	/* Redraw the Bar based on the current projection and zoom level
	*/
	InfoBox.prototype.draw = function () {
		// Creates the element if it doesn't exist already.
		this.createElement();
		if (!this.div_) return;

		// Calculate the DIV coordinates of two opposite corners of our bounds to
		// get the size and position of our Bar
		var pixPosition = this.getProjection().fromLatLngToDivPixel(this.latlng_);
		if (!pixPosition) return;

		// Now position our DIV based on the DIV coordinates of our bounds
		this.div_.style.width = this.width_ + "px";
		this.div_.style.left = (pixPosition.x + this.offsetHorizontal_) + "px";
		this.div_.style.height = this.height_ + "px";
		this.div_.style.top = (pixPosition.y + this.offsetVertical_) + "px";
		this.div_.style.display = 'block';
	};

	/* Creates the DIV representing this InfoBox in the floatPane.  If the panes
	* object, retrieved by calling getPanes, is null, remove the element from the
	* DOM.  If the div exists, but its parent is not the floatPane, move the div
	* to the new pane.
	* Called from within draw.  Alternatively, this can be called specifically on
	* a panes_changed event.
	*/
	InfoBox.prototype.createElement = function () {
		var panes = this.getPanes();
		var div = this.div_;
		if (!div) {
			// This does not handle changing panes.  You can set the map to be null and
			// then reset the map to move the div.
			div = this.div_ = document.createElement("div");
			div.className = "infoBox";
			div.style.width = this.width_ + "px";
			div.style.height = this.height_ + "px";

			var contentDiv = document.createElement("div");
			contentDiv.innerHTML = this.html;
			contentDiv.className = "content";

			var topDiv = document.createElement("div");
			topDiv.className = "close";
			var closeImg = document.createElement("img");
			closeImg.src = "/Assets/Images/close.png";
			topDiv.appendChild(closeImg);

			var removeInfoBox = function (ib) {
				return function () {
					ib.setMap(null);
					if (mainMap) {
						mainMap.setCenter();
					}
				};
			};

			google.maps.event.addDomListener(closeImg, 'click', removeInfoBox(this));

			div.appendChild(topDiv);
			div.appendChild(contentDiv);
			div.style.display = 'none';
			panes.floatPane.appendChild(div);

			this.panMap();
		} else if (div.parentNode != panes.floatPane) {
			// The panes have changed.  Move the div.
			div.parentNode.removeChild(div);
			panes.floatPane.appendChild(div);
		} else {
			// The panes have not changed, so no need to create or move the div.
		}
	};

	/* Pan the map to fit the InfoBox.
	*/
	InfoBox.prototype.panMap = function () {
		// if we go beyond map, pan map
		var map = this.map_;
		var bounds = map.getBounds();
		if (!bounds) return;

		// The position of the infowindow
		var position = this.latlng_;

		// The dimension of the infowindow
		var iwWidth = this.width_;
		var iwHeight = this.height_;

		// The offset position of the infowindow
		var iwOffsetX = this.offsetHorizontal_;
		var iwOffsetY = this.offsetVertical_;

		// Padding on the infowindow
		var padX = 40;
		var padY = 40;

		// The degrees per pixel
		var mapDiv = map.getDiv();
		var mapWidth = mapDiv.offsetWidth;
		var mapHeight = mapDiv.offsetHeight;
		var boundsSpan = bounds.toSpan();
		var longSpan = boundsSpan.lng();
		var latSpan = boundsSpan.lat();
		var degPixelX = longSpan / mapWidth;
		var degPixelY = latSpan / mapHeight;

		// The bounds of the map
		var mapWestLng = bounds.getSouthWest().lng();
		var mapEastLng = bounds.getNorthEast().lng();
		var mapNorthLat = bounds.getNorthEast().lat();
		var mapSouthLat = bounds.getSouthWest().lat();

		// The bounds of the infowindow
		var iwWestLng = position.lng() + (iwOffsetX - padX) * degPixelX;
		var iwEastLng = position.lng() + (iwOffsetX + iwWidth + padX) * degPixelX;
		var iwNorthLat = position.lat() - (iwOffsetY - padY) * degPixelY;
		var iwSouthLat = position.lat() - (iwOffsetY + iwHeight + padY) * degPixelY;

		// calculate center shift
		var shiftLng =
          (iwWestLng < mapWestLng ? mapWestLng - iwWestLng : 0) +
          (iwEastLng > mapEastLng ? mapEastLng - iwEastLng : 0);
		var shiftLat =
          (iwNorthLat > mapNorthLat ? mapNorthLat - iwNorthLat : 0) +
          (iwSouthLat < mapSouthLat ? mapSouthLat - iwSouthLat : 0);

		// The center of the map
		var center = map.getCenter();

		// The new map center
		var centerX = center.lng() - shiftLng;
		var centerY = center.lat() - shiftLat;

		// center the map to the new shifted center
		map.setCenter(new google.maps.LatLng(centerY, centerX));

		// Remove the listener after panning is complete.
		google.maps.event.removeListener(this.boundsChangedListener_);
		this.boundsChangedListener_ = null;
	};

}
