if (typeof Wel == 'undefined') {
	Wel = {};
}

Wel.Maps = function() {}
Wel.Maps.prototype.Init = function(options) {
	this.options            = options;
	this.fromStreetViewMode = false;
	this.markers            = [];
	if (!options['container'] || !options['latitude'] || !options['longitude'])
		return;
	
	options['zoom'] = options['zoom'] || 8;
	
	this.map        = new google.maps.Map(document.getElementById(options['container']), {
		zoom: options['zoom'],
		center: new google.maps.LatLng(options['latitude'], options['longitude']),
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		disableDefaultUI: true
	});
	
	this._setupControls();
}
Wel.Maps.prototype._handleControlClick = function(element) {
	$('.control').removeClass('active');
	$(element).addClass('active');

	if (this.fromStreetViewMode) {
		this.fromStreetViewMode = false;
		$('#streetView').remove();
	}
}
Wel.Maps.prototype._setupControls = function() {
	var me       = this;
	var controls = $('<div></div>');
	controls.addClass('controls');
	controls.css({
		position: 'absolute',
		top: '0',
		right: '0',
		padding: '5px',
		zIndex: 5
	});
	
	var roadmap = $('<div></div>');
	roadmap.addClass('control');
	roadmap.addClass('active');
	roadmap.html('<p>KARTVY</p>');
	roadmap.click(function() {
		me._handleControlClick(this);
		
		me.map.setMapTypeId(google.maps.MapTypeId.ROADMAP);
	});
	controls.append(roadmap);
	
	var satellite = $('<div></div>');
	satellite.addClass('control');
	satellite.html('<p>SATELLIT</p>');
	satellite.click(function() {
		me._handleControlClick(this);
		
		me.map.setMapTypeId(google.maps.MapTypeId.SATELLITE);
	});
	controls.append(satellite);
	
	$('#' + me.options['container']).parent().append(controls);
}
Wel.Maps.prototype.StreetViewAvailable = function(lat, lng) {
	var me      = this;
	var service = new google.maps.StreetViewService();
	service.getPanoramaByLocation(new google.maps.LatLng(lat, lng), 50, function(data, status) {
		if (status == google.maps.StreetViewStatus.OK)
			me.AppendStreetView(lat, lng);
	});
}
Wel.Maps.prototype.AppendStreetView = function(lat, lng) {
	var me         = this;
	var streetview = $('<div></div>');
	streetview.addClass('control');
	streetview.html('<p>GATUVY</p>');
	streetview.click(function() {
		me._handleControlClick(this);
		
		var sw = $('<div></div>');
		sw.attr('id', 'streetView');
		sw.css({
			position: 'absolute',
			top: '0',
			left: '0',
			margin: '0',
			width: $('#' + me.options['container']).width() + 'px',
			height: $('#' + me.options['container']).height() + 'px',
			zIndex: 3
		});
		$('#' + me.options['container']).parent().append(sw);
		
		
		var panorama = new google.maps.StreetViewPanorama(document.getElementById('streetView'), {
			position: new google.maps.LatLng(lat, lng)
		});
		me.map.setStreetView(panorama);
		
		me.fromStreetViewMode = true;
	});
	$('.controls').append(streetview);
}
Wel.Maps.prototype.AddMarkers = function(list) {
	var me    = this;
	var icon  = new google.maps.MarkerImage(
		'/img/mapimgs/pin.png',
		new google.maps.Size(20, 20),
		new google.maps.Point(0, 0),
		new google.maps.Point(12, 12)
	);
	
	for (marker in list) {
		var m = new google.maps.Marker({
			position: new google.maps.LatLng(list[marker]['latitude'], list[marker]['longitude']),
			map: me.map,
			icon: icon,
			title: list[marker]['name']
		});
		
		var infoContent  = '';
		if (list[marker]['openHours'] && list[marker]['openHours'] !== '')
			infoContent += list[marker]['openHours'];
		
		var layer  = false;
		var latest = false;
		(function(m, name, url, info) {
			var layer = new Wel.MapOverlay(name, m.getPosition(), me.map);
			var info  = new Wel.InfoWindow(name, info, url, me.map, m.getPosition());
			var iOpen = false;
			
			google.maps.event.addListener(m, 'click', function() {
				if (latest)
					latest.hide();
				
				if (!info.isOpen())
					info.show();
				else
					info.hide();
				
				latest = info;
				
				me.map.panTo(m.getPosition());
			});
			google.maps.event.addListener(m, 'mouseover', function() {
				layer.show();
			});
			google.maps.event.addListener(m, 'mouseout', function() {
				layer.hide();
			});
		})(m, list[marker]['name'], list[marker]['URL'], infoContent);
		
		this.markers.push(m);
	}
	
	if (list.length == 1) {
		this.StreetViewAvailable(list[0]['latitude'], list[0]['longitude']);
	}
}
Wel.Maps.prototype.FetchMarkers = function(list, useXML) {
	var me = this;
	
	var dataType = 'json';
	if (typeof useXML != 'undefined' && useXML === true)
		dataType = 'xml';

	if (dataType == 'xml')
		list = me._xmlMarkersToJson(list);
	
	me.AddMarkers(list);
	
}
Wel.Maps.prototype._xmlMarkersToJson = function(xmlDocument) {
	var destinations = xmlDocument.getElementsByTagName('destination');
	var markers      = [];
	
	for (var i = 0; i < destinations.length; i++) {
		var attr = destinations[i].attributes;
		markers.push({
			name:        attr.getNamedItem('name').nodeValue,
			description: attr.getNamedItem('description').nodeValue,
			latitude:    attr.getNamedItem('latitude').nodeValue,
			longitude:   attr.getNamedItem('longitude').nodeValue,
			url:         attr.getNamedItem('URL').nodeValue
		});
	}
	
	return markers;
}
Wel.Maps.prototype.Geocode = function(address, callback) {
	var geo = new google.maps.Geocoder();
	geo.geocode({address: address + ', sverige'}, function(results, status) {
		if (status == google.maps.GeocoderStatus.OK) {
			callback(results[0].geometry.location);
		} else {
			callback(false);
		}
	});
}
Wel.Maps.prototype.Pan = function(latlng, zoomLevel, callback) {
	var me       = this;
	var listener = google.maps.event.addListener(this.map, 'center_changed', function() {
		setTimeout(function() {
			me.map.setZoom(zoomLevel);
			google.maps.event.removeListener(listener);
			
			if (typeof callback == 'function')
				callback();
		}, 1500);
	});
	this.map.panTo(latlng);
}
Wel.Maps.prototype.HasMarkersInBounds = function() {
	var bounds = this.map.getBounds();
	for (var i = 0; i < this.markers.length; i++) {
		if (bounds.contains(this.markers[i].getPosition())) {
			return true;
		}
	}
	
	return false;
}
Wel.Maps.prototype.FindNearestMarker = function(latlng) {
	var R              = 6371;
	var closest        = false;
	var lowestDistance = 999999;
	
	for (var i = 0; i < this.markers.length; i++) {
		var pos  = this.markers[i].getPosition();
		var dLat = (pos.lat() - latlng.lat()) * Math.PI / 180;
		var dLng = (pos.lng() - latlng.lng()) * Math.PI / 180;
		
		var current  =  Math.sin(dLat / 2) * Math.sin(dLat / 2) +
						Math.cos(pos.lat() * Math.PI / 180) * Math.cos(pos.lat() * Math.PI / 180) *
						Math.sin(dLng / 2) * Math.sin(dLng / 2);
		var distance = 2 * Math.atan2(Math.sqrt(current), Math.sqrt(1 - current)) * R;
		
		if (Math.abs(distance) < lowestDistance) {
			closest        = this.markers[i];
			lowestDistance = Math.abs(distance);
		}
	}
	
	return {
		marker: closest,
		distance: lowestDistance
	}
}

Wel.MapOverlay = function(title, position, map) {
	this.title    = title;
	this.position = position;
	this.map      = map;
	this.div      = null;
	this.setMap(map);
}
Wel.MapOverlay.prototype = new google.maps.OverlayView();
Wel.MapOverlay.prototype.onAdd = function() {
	var bar   = $('<div></div>');
	bar.css({
		position: 'absolute',
		backgroundImage: 'url(http://www.teamsportia.se/i/maps/label_arrow.png)',
		backgroundPosition: 'center left',
		backgroundRepeat: 'no-repeat',
		height: '40px',
		lineHeight: '40px',
		padding: '0 0 0 15px',
		whiteSpace: 'nowrap',
		display: 'none'
	});
	var title = $('<p></p>');
	title.css({
		margin: 0,
		backgroundImage: 'url(http://www.teamsportia.se/i/maps/label_bar.png)',
		backgroundPosition: 'center right',
		backgroundRepeat: 'no-repeat',
		lineHeight: '40px',
		fontWeight: 'bold',
		color: '#fff',
		whiteSpace: 'nowrap',
		padding: '0 15px 0 5px'
	});
	title.html(this.title);
	bar.append(title);
	
	this.div = bar;
	$(this.getPanes().floatPane).append(bar);
}
Wel.MapOverlay.prototype.draw = function() {
	var proj     = this.getProjection();
	var position = proj.fromLatLngToDivPixel(this.position);
	$(this.div).css({
		top: (position.y - 20) + 'px',
		left: (position.x + 10) + 'px'
	});
}
Wel.MapOverlay.prototype.onRemove = function() {
	$(this.div).remove();
	this.div = null;
}
Wel.MapOverlay.prototype.show = function() {
	$(this.div).show();
}
Wel.MapOverlay.prototype.hide = function() {
	$(this.div).hide();
}

Wel.InfoWindow = function(title, content, link, map, position) {
	this.title    = title;
	this.content  = content;
	this.link     = link;
	this.map      = map;
	this.position = position;
	this._isOpen   = false;
	
	this.div      = null;
	this.setMap(map);
}
Wel.InfoWindow.prototype = new google.maps.OverlayView();
Wel.InfoWindow.prototype.onAdd = function() {
	var infoWindow = $('<div></div>');
	infoWindow.css({
		display: 'none',
		position: 'absolute',
		top: 0,
		left: 0
	});
	infoWindow.html('<div class="mapInfoWindow"><div class="padding"><h4></h4><p><strong>Öppettider</strong><br /></p></div><div class="bottomArrow"></div></div>');
	if(this.link != '')
		infoWindow.find('.padding').append('<div class="link"><a href="">Butikens sida &#187;</a></div>')
	infoWindow.find('h4').html(this.title);
	infoWindow.find('p').append(this.content);
	infoWindow.find('a').attr('href', this.link);
	
	var close = $('<div></div>');
	close.css({
		position: 'absolute',
		top: 0,
		right: 0,
		width: '22px',
		height: '22px',
		cursor: 'pointer'
	});
	infoWindow.append(close);
	var me = this;
	close.click(function() {
		me.hide();
	});
	
	this.div = infoWindow;
	$(this.getPanes().floatPane).append(infoWindow);
}
Wel.InfoWindow.prototype.draw = function() {
	var proj     = this.getProjection();
	var position = proj.fromLatLngToDivPixel(this.position);
	$(this.div).css({
		top: (position.y - $(this.div).height() - 32) + 'px',
		left: (position.x - 36 - 17) + 'px'
	});
}
Wel.InfoWindow.prototype.onRemove = function() {
	$(this.div).remove();
	this.div = null;
}
Wel.InfoWindow.prototype._updatePosition = function() {
	var proj     = this.getProjection();
	var position = proj.fromLatLngToDivPixel(this.position);
	$(this.div).css({
		top: (position.y - $(this.div).height() - 32) + 'px',
		left: (position.x - 36 - 17) + 'px'
	});
}
Wel.InfoWindow.prototype.show = function() {
	this._isOpen = true;
	return $(this.div).show();
}
Wel.InfoWindow.prototype.hide = function() {
	this._isOpen = false;
	return $(this.div).hide();
}
Wel.InfoWindow.prototype.isOpen = function() {
	return this._isOpen;
}
