﻿CategorizedMarkers = {
    ///<summary>Object that holds the different marker categories along with their markers.</summary>

    _markerCategories: [],

    _category: function(name, visibility, markers, visibleIcon, hiddenIcon) {
        ///<summary>Marker category object</summary>
        ///<param name="name"></param>
        ///<param name="visibility"></param>
        ///<param name="markers"></param>
        this.name = name;
        this.visibility = visibility;
        this.visibleIcon = visibleIcon;
        this.hiddenIcon = hiddenIcon;
        this.minZoom = 0;
        this.maxZoom = 17;

        if (markers == null) this.markers = [];
        else this.markers = markers;
    },

    getCategory: function(name) {
        ///<summary>Returns the marker category specified</summary>
        ///<param name="name"></param>
        var category = null;
        for (var a = 0; a < this._markerCategories.length; a++) {
            if (this._markerCategories[a].name == name) {
                category = this._markerCategories[a];
                break;
            }
        }
        return category;
    },

    getCategoryIcon: function(name) {
        ///<summary>
        /// Returns the visible-/hidden icon representing the
        /// marker category based on the value of the visibility property.
        ///</summary>
        ///<param name="name"></param>
        var category = this.getCategory(name);
        if ((category.visibleIcon == null) || (category.hiddenIcon == null)) {
            return '';
        } else {
            if (category.visibility == 0) return category.hiddenIcon;
            else return category.visibleIcon;
        }
    },

    addCategory: function(name, visibility, markers, visibleIcon, hiddenIcon) {
        ///<summary>Adds a marker category with markers</summary>
        ///<param name="name"></param>
        ///<param name="visibility">0 | 1</param>
        ///<param name="markers"></param>
        this._markerCategories.push(new this._category(name, visibility, markers, visibleIcon, hiddenIcon));
    },

    addCategory: function(name, visibility, visibleIcon, hiddenIcon) {
        ///<summary>Adds a marker category</summary>
        ///<param name="name"></param>
        ///<param name="visibility"></param>
        this._markerCategories.push(new this._category(name, visibility, null, visibleIcon, hiddenIcon));
    },

    toggleCategoryVisibility: function(categoryName) {
        ///<summary>Toggles the category's visibility property</summary>
        ///<param name="categoryName"></param>
        var category = this.getCategory(categoryName);
        category.visibility != category.visibility;
    },

    addMarker: function(marker, categoryName) {
        ///<summary>Adds a marker to the specified category</summary>
        ///<param name="marker">GMarker object</param>
        ///<param name="categoryName"></param>
        var category = this.getCategory(categoryName);
        if (category == null) {
            alert('User error, no category with the specified name exists.');
        }
        
        category.markers.push(marker);
    },
    
    clearMarkers: function() {
		///<summary>Clears all markers from all categories</summary>
		for (var i = 0; i < this._markerCategories.length; i++) {
			this._markerCategories[i].markers = [];
		}
    }
};

var RTMMap = {
	///<summary>Object holding methods used when generating the RTM-map</summary>

	_map: null,         // GMap object
	_mgr: null,         // MarkerManager object
	//_mcls: null, 	// MarkerClusterer object
	_geocoder: null,    // GGeocoder object
	_zLevel: 4,         // Default zoom-level
	_zLevelArea: 7,     // Zoom-level used when an area is selected
	_egeoRtm: null, 		// EGeoXml object holding the RTMs
	_egeoRtmLow: null, 		// EGeoXml object holding the RTMs with low priority
	_egeoRtmMed: null, 		// EGeoXml object holding the RTMs with medium priority
	_egeoPartner: null, 	// EGeoXml object holding the partner markers
	_egeoBikeStands: null, // EGeoXml object holding the bicycle stands feed
	_centrePoint: null,     // Default centre-point of the map
	_rtMessages: [],        // Array holding the RTM messages
	_currentZoomLevel: null, // Map's current zoom-level
	_currentCenter: null,   // Map's current center
	_geoLocations: null, // Holds the area's coordinates
	_mapRefreshTimer: null, // Holds the map refresh thread
	AllowMapRefresh: true,  // Turns automatic map-refresh on/off
	categorizedMarkers: null,
	homeLocationListener: null,

	_wheelevent: function(e) {
		///<summary>Prevent page scrolling if the mouse-wheel is rolled when the pointer is above the map</summary>
		///<param name="e">Event</param>
		if (!e) e = window.event;
		if (e.preventDefault) e.preventDefault();
		e.returnValue = false;
	},

	_setMapCenter: function(point, zoomLevel) {
		///<summary>
		/// Sets the center of the map to the specified point (lat/lng) at
		/// the specified zoom level.
		///</summary>
		///<param name="point">Lat/Lng</param>
		///<param name="zoomLevel">Zoom level</param>
		this._map.setCenter(point, zoomLevel);
	},

	_addP4Marker: function() {
		///<summary>Adds the marker for the P4 Radio Hele Norge AS HQ to the map</summary>
		var _self = this;
		var icon = new GIcon();
		icon.iconSize = new GSize(10, 10);
		icon.iconAnchor = new GPoint(6, 20);
		icon.infoWindowAnchor = new GPoint(5, 1);
		icon.image = '/images/icons/rtm/circle.png';

		var infoWindowHTML = '<table><tr><td><img src="/images/p4.gif" alt="P4"/></td>' +
                '<td><a href="http://www.p4.no" target="_new">' +
                'P4 Radio Hele Norge AS</a><br/><br/>' +
                'Send "trafikk" til 1904 for trafikktips.<br/><br/>' +
                'E-mail: <a href="mailto:p4@p4.no">p4@p4.no</a><br/>' +
                '</td></tr></table>';

		var p4HQPosition = new GLatLng(61.12068232642678, 10.462117195129395);
		var marker = new GMarker(p4HQPosition, { icon: icon, title: "P4 Radio Hele Norge" });
		this._map.addOverlay(marker);

		GEvent.addListener(marker, "click",
            function() {
            	currentCenter = _self._map.getCenter();
            	currentZoomLevel = _self._map.getZoom();

            	_self._map.setCenter(p4HQPosition, 15);
            	marker.openInfoWindowHtml(infoWindowHTML)
            }
        );

		GEvent.addListener(marker, "infowindowclose", function() {
			_self._setMapCenter(currentCenter, currentZoomLevel);
		});
	},

	_setBaseIcon: function() {
		///<summary>
		/// Method used to set the base icon. The icon used for the overlaymarkers,
		/// if an icon-style is not found in the KML-feed.
		/// NOTE: The size-setting also affects the icons read from the KML-feed.
		///</summary>
		var icon = new GIcon();
		icon.iconSize = new GSize(20, 20);
		icon.iconAnchor = new GPoint(6, 20);
		icon.infoWindowAnchor = new GPoint(5, 1);
		return icon;
	},

	_addMarkersToMap: function(categoryName, minZoom, maxZoom, useCluster) {
		///<summary>
		/// Method used when parsing a KML-feed and adding markers
		/// from the specified marker-category to the map.
		///<param name="categoryName">Marker category</param>
		///<param name="minZoom">Minimum zoom-level the added markers should appear on</param>
		///<param name="maxZoom">Maximum zoom-level the added markers should appear on</param>
		///</summary>
		try {
			var category = this.categorizedMarkers.getCategory(categoryName);
			category.minZoom = minZoom;
			category.maxZoom = maxZoom;
			if (category.markers.length > 0 && category.visibility == 1) {
				this._mgr.addMarkers(category.markers, minZoom, maxZoom);
			}
		} catch (e) { }
	},

	_addMarkerOverlay: function() {
		///<summary>Method used when parsing the different KML-feeds for the RTM- partner-, airport- and camera markers</summary>
		var _self = this;
		_self._mgr = new MarkerManager(_self._map);
		// _self._mcls = new MarkerClusterer(_self._map, null, { maxZoom: 13 });

		$('mapLoader').show();

		GEvent.addListener(this._egeoRtm, 'parsed', function() {
			_self._addMarkersToMap('rtm', 4, 17, false);
			_self._egeoRtmMed.parse();
		});

		GEvent.addListener(this._egeoRtmMed, 'parsed', function() {
			_self._addMarkersToMap('rtmmed', 7, 17, false);
			_self._egeoRtmLow.parse();
		});

		GEvent.addListener(this._egeoRtmLow, 'parsed', function() {
			_self._addMarkersToMap('rtmlow', 7, 17, false);
			_self._egeoCameras.parse();
		});

		GEvent.addListener(this._egeoCameras, 'parsed', function() {
			_self._addMarkersToMap('camera', 7, 17);
			_self._egeoAirports.parse();
		});

		GEvent.addListener(this._egeoAirports, 'parsed', function() {
			_self._addMarkersToMap('airport', 7, 17);
			_self._egeoBikeStands.parse();
		});

		GEvent.addListener(this._egeoBikeStands, 'parsed', function() {
			_self._addMarkersToMap('bicyclestand', 12, 17);
			_self._egeoPartner.parse();
		});

		GEvent.addListener(this._egeoPartner, 'parsed', function() {
			_self._addMarkersToMap('partner', 7, 17);
			_self._mgr.refresh();

			Effect.SwitchOff('mapLoader');

			_self._setMapCenter(_self._centrePoint, _self._zLevel);

			// Function only available if the site is requested
			// by an external source like "GuleSider" or similar.
			try {
				setTimeout(function() {
					if (typeof openMarkerInfo == 'function') {
						openMarkerInfo();
					}
				}, 0);
			} catch (e) { }
		});

		this._egeoRtm.parse();
	},

	_set16By16Icon: function() {
		///<summary>Method used to define a 16x16 pixels GIcon object</summary>
		var icon = new GIcon();
		icon.iconSize = new GSize(16, 16);
		icon.iconAnchor = new GPoint(6, 16);
		icon.infoWindowAnchor = new GPoint(5, 1);
		return icon;
	},

	_setVikingIcon: function() {
		///<summary>
		/// Method used to create a new GIcon object 
		/// used for the "Viking Redning" logo found on the map.
		///</summary>
		var icon = new GIcon();
		icon.iconSize = new GSize(38, 7);
		icon.iconAnchor = new GPoint(6, 16);
		icon.infoWindowAnchor = new GPoint(5, 1);
		return icon;
	},

	_setHomeLocationIcon: function() {
		///<summary>
		/// Method used to create a new GIcon object for the
		/// icon appearing on the map when the user uses the 
		/// "Mitt hjemsted" functionality.
		///</summary>
		var icon = new GIcon();
		icon.image = '/images/icons/user_red.png';
		icon.iconSize = new GSize(16, 16);
		icon.iconAnchor = new GPoint(6, 16);
		icon.infoWindowAnchor = new GPoint(5, 1);
		return icon;
	},

	_addCameraMarker: function(marker, name, desc, imagefile, n) {
		///<summary>Method used when adding road-camera markers to the map</summary>
		///<param name="marker">GMarker object</param>
		///<param name="name">Title</param>
		///<param name="desc">Description</param>
		///<param name="imagefile">URL to the image to display upon click</param>
		///<param name="n"></param>
		GEvent.clearListeners(marker, "click");
		GEvent.addListener(marker, "click", function() {
			var pattern = '<a href=".*">(.*)</a>';
			var re = new RegExp(pattern);
			var m = re.exec(desc);
			imageUrl = m[1];
			var elem = RTMMap._createImageDiv(imageUrl);
			LightBox.Show(elem, { top: 0, left: 0 });
		});
		RTMMap.categorizedMarkers.addMarker(marker, 'camera');
	},

	_createImageDiv: function(imageUrl) {
		///<summary>
		/// Adds the contents of the KML-feed to the map
		/// and creates the DIV used to display the image from one
		//  of the road cameras.
		///</summary>
		///<param name="imageUrl">The URL to the image from the road camera</param>
		var leftPos = parseInt((document.viewport.getWidth() / 2) - 320);
		var topPos = parseInt((document.viewport.getHeight() / 2) - 240 + document.viewport.getScrollOffsets().top);

		var newDiv = new Element('div', {
			'id': 'roadImage',
			'style': 'position: absolute; left: ' + leftPos + 'px; top: ' + topPos + 'px;'
		});

		newDiv.innerHTML = '<img style="width: 640px; height: 480px; border: solid black 1px;" src="' + imageUrl + '" alt=""/>' +
            '<div style="width: 642px; background: black; float:left; color: #F96A28;">' +
            '<div style="margin-left: 5px; float:left;">Kilde: <a style="color: #F96A28;" href="http://www.vegvesen.no" target="_new">Statens Vegvesen</a></div>' +
            '<div class="button" style="float:right; margin-right: 0px;">' +
            '<a href="#" class="button" onclick="LightBox.Hide(\'roadImage\', null); $(\'roadImage\').remove(); return false;"><span>Lukk</span></a>' +
            '</div>' +
            '</div>';

		return newDiv;
	},

	_addThirdPartyMarker: function(marker, name, desc, imagefile, n) {
		///<summary>Method used to push the third-party markers into the thirdpartyMarkers array</summary>
		///<param name="marker">GMarker object</param>
		///<param name="name"></param>
		///<param name="desc"></param>
		///<param name="imagefile"></param>
		///<param name="n"></param>
		RTMMap.categorizedMarkers.addMarker(marker, 'partner');
	},

	_addBicycleStandMarker: function(marker, name, desc, imagefile, n) {
		///<summary>Method for adding bicycle stand markers to the map</summary>
		///<param name="marker">GMarker object</param>
		///<param name="name"></param>
		///<param name="desc"></param>
		///<param name="imagefile"></param>
		///<param name="n"></param>
		GEvent.clearListeners(marker, 'click');
		GEvent.addListener(marker, 'click', function() {
			var htmlContent = '<b>' + name + '</b><br/>' + desc;
			marker.openInfoWindowHtml(htmlContent, { maxwidth: 300 });
		});
		RTMMap.categorizedMarkers.addMarker(marker, 'bicyclestand');
	},

	_addAirportMarker: function(marker, name, desc, imagefile, n) {
		///<summary>Method for adding the ariport markers to the map</summary>
		///<param name="marker">GMarker object</param>
		///<param name="name"></param>
		///<param name="desc"></param>
		///<param name="imagefile"></param>
		///<param name="n"></param>
		var airportCode = desc;

		GEvent.clearListeners(marker, "click");

		GEvent.addListener(marker, "click", function() {
			var url = '/kml/feeds/airportinfo.ashx';

			new Ajax.Request(url, {
				method: 'get',
				parameters: { 'airportCode': airportCode, 'airportName': name },
				onSuccess: function(transport) {
					var infoHTML = transport.responseText;
					marker.openInfoWindowHtml(infoHTML, { maxwidth: 400 });
				},
				onFailure: function(transport) {
					alert('Det har oppstått en feil.');
				}
			});
		});

		RTMMap.categorizedMarkers.addMarker(marker, 'airport');
	},

	_refreshMap: function() {
		///<summary>Refreshes the map automatically every 10 minutes</summary>
		if (this.AllowMapRefresh) {
			this._mapRefreshTimer = setTimeout('GUnload();RTMMap.init()', 600000);
		}
	},

	RTM: function(latLng, title, description) {
		///<summary>Object holding the RTM</summary>
		///<param name="latLng">Lat/Lng position of the message</param>
		///<param name="title">Message title</param>
		///<param name="description">Message description</param>
		this.LatLng = latLng;
		this.Title = title;
		this.Description = description;
	},

	toggleMarkers: function(categoryName) {
		///<summary>Toggles the visibility of the markers contained in the array markerArray</summary>
		///<param name="categoryName">Marker category name</param>
		var iconDiv = $('toggle' + categoryName + 'Icon');
		var category = this.categorizedMarkers.getCategory(categoryName);
		var markers = category.markers;

		//		if (categoryName.startsWith('rtm')) {
		//			// use clustering
		//			if (category.visibility == 0) {
		//				// Show markers
		//				this._mcls.addMarkers(markers);
		//			} else {
		//				// Hide markers
		//				for (var a = 0; a < markers.length; a++) {
		//					this._mcls.removeMarker(markers[a]);
		//				}
		//			}
		//			this._mcls.resetViewport();
		//			this._mcls.redraw_();
		//		} else {
		if (category.visibility == 0) {
			// Show markers
			this._mgr.addMarkers(markers, category.minZoom, category.maxZoom);
			this._mgr.refresh();
		} else {
			// Hide markers
			for (var a = 0; a < markers.length; a++) {
				this._mgr.removeMarker(markers[a]);
			}
		}
		//		}

		if (category.visibility == 0) {
			category.visibility = 1;
			if (category.visibleIcon && iconDiv) iconDiv.src = category.visibleIcon;
			if (categoryName == 'bicyclestand') {
				RTMMap._map.closeInfoWindow();
				RTMMap._map.setZoom(12);
				RTMMap._map.panTo(this._findGeoLocation('Oslo'));
			} else {
				var currZoom = RTMMap._map.getZoom();
				if (currZoom < category.minZoom)
					RTMMap._map.setZoom(category.minZoom);
				if (currZoom > category.maxZoom)
					RTMMap._map.setZoom(category.maxZoom);
			}
		}
		else {
			category.visibility = 0;
		}
	},

	createAreaPanel: function(areaName) {
		///<summary>
		/// Method used when creating the panel that appears
		/// once the user has clicked on an area name.
		///</summary>
		var rtmIcon = this.categorizedMarkers.getCategoryIcon('rtm');
		var rtmMedIcon = this.categorizedMarkers.getCategoryIcon('rtmmed');
		var rtmLowIcon = this.categorizedMarkers.getCategoryIcon('rtmlow');
		var airportIcon = this.categorizedMarkers.getCategoryIcon('airport');
		var cameraIcon = this.categorizedMarkers.getCategoryIcon('camera');

		var html = '';
		html += '<div style="font-size: 10pt; font-weight: bold; margin-top: 5px; margin-bottom: 5px; text-align:center;">' + areaName;
		html += '<div style="color:#999999;font-size:8pt;font-weight:normal;"><a href="#" onclick="RTMMap.hideAreaPanel();return false;" class="mapregionselector">Velg fylke</a></div></div>';

		html += '<table>';
		html += '<tr><td><input type="checkbox" style="background-color:#ffffff;" id="togglertmCheckbox" onclick="RTMMap.toggleMarkers(\'rtm\');"' + RTMMap.getCategoryVisibility('rtm') + ' /><label for="togglertmCheckbox" style="position:relative;top:-2px;">Trafikk (høy pri)</label></td>';
		html += '<td><img id="togglertmIcon" src="' + rtmIcon + '" alt=""/></td></tr>';
		html += '<tr><td><input type="checkbox" style="background-color:#ffffff;" id="togglertmMedCheckbox" onclick="RTMMap.toggleMarkers(\'rtmmed\');"' + RTMMap.getCategoryVisibility('rtmmed') + ' /><label for="togglertmMedCheckbox" style="position:relative;top:-2px;">Trafikk (med pri)</label></td>';
		html += '<td><img id="togglertmMedIcon" src="' + rtmMedIcon + '" alt=""/></td></tr>';
		html += '<tr><td><input type="checkbox" style="background-color:#ffffff;" id="togglertmLowCheckbox" onclick="RTMMap.toggleMarkers(\'rtmlow\');"' + RTMMap.getCategoryVisibility('rtmlow') + ' /><label for="togglertmLowCheckbox" style="position:relative;top:-2px;">Trafikk (lav pri)</label></td>';
		html += '<td><img id="togglertmLowIcon" src="' + rtmLowIcon + '" alt=""/></td></tr>';
		html += '<tr><td><input type="checkbox" style="background-color:#ffffff;" id="toggleairportCheckbox" onclick="RTMMap.toggleMarkers(\'airport\');"' + RTMMap.getCategoryVisibility('airport') + ' /><label for="toggleairportCheckbox" style="position:relative;top:-2px;">Flyplasser</label></td>';
		html += '<td><img id="toggleairportIcon" src="' + airportIcon + '" alt=""/></td></tr>';
		html += '<tr><td><input type="checkbox" style="background-color:#ffffff;" id="togglecameraCheckbox" onclick="RTMMap.toggleMarkers(\'camera\');"' + RTMMap.getCategoryVisibility('camera') + ' /><label for="togglecameraCheckbox" style="position:relative;top:-2px;">Vegkameraer</label></td>';
		html += '<td><img id="togglecameraIcon" src="' + cameraIcon + '" alt=""/></td></tr>';

		// Display City-bikes for Oslo only
		if (areaName == 'Oslo') {
			var bicycleStandIcon = this.categorizedMarkers.getCategoryIcon('bicyclestand');
			html += '<tr><td><input type="checkbox" style="background-color:#ffffff;" id="togglebicyclestandCheckbox" onclick="RTMMap.toggleMarkers(\'bicyclestand\');"' + RTMMap.getCategoryVisibility('bicyclestand') + ' /><label for="togglebicyclestandCheckbox" style="position:relative;top:-2px;">Bysykler</label></td>';
			html += '<td><img id="togglebicyclestandIcon" src="' + bicycleStandIcon + '" alt=""/></td></tr>';

		}

		html += '</table>';

		var parnerIcon = this.categorizedMarkers.getCategoryIcon('partner');
		html += '<div style="padding-top:5px; margin-top:5px;">Partnere</div>';
		html += '<table style="width:100%;">'
		html += '<tr><td><input type="checkbox" style="background-color:#ffffff;" id="togglepartnerCheckbox" onclick="RTMMap.toggleMarkers(\'partner\');"' + RTMMap.getCategoryVisibility('partner') + ' /><label for="togglepartnerCheckbox" style="position:relative;top:-2px;">Viking</label></td>'
		html += '<td align="right"><img id="toggleparnerIcon" src="' + parnerIcon + '" alt="Viking Redningstjenester" /></td></tr>';
		html += '</table>'

		html += '<div style="font-size: 8pt; color: #999999; margin-top: 25px; margin-bottom: 5px;">';
		html += 'Velg hvilke markører som skal vises i kartet.';
		html += '</div>';

		$('areaList').hide();
		$('areaPanel').update(html);
		$('areaPanel').show();

		if (areaName.length > 0)
			this.displayArea(areaName);
	},

	getCategoryVisibility: function(name) {
		///<summary>
		/// Returns the string cheched='checked' if the category is visible
		///</summary>
		///<param name="name"></param>
		var category = CategorizedMarkers.getCategory(name);
		if (category.visibility == 1)
			return "checked='checked'";
	},

	hideAreaPanel: function() {
		///<summary>Method called when hiding the area panel</summary
		$('areaPanel').hide();
		$('areaList').show();
	},

	SaveMapPoint: function(lat, lng, zoom) {
		///<summary>
		/// Method called when the user decides to save the start point in the map.
		/// <param name="lat">Latitude</param>
		/// <param name="lng">Longitude</param>
		/// <param name="zoom">Current map zoom-level</param>
		///</summary>
		var _self = this;
		if (Membership.CurrentUser.IsLoggedIn) {
			new Ajax.Request('homelocation.aspx', {
				method: 'post',
				parameters: {
					mode: 'save',
					userid: 'userid',
					lat: lat,
					lng: lng,
					zoom: zoom
				},
				onSuccess: function() {
					_self._map.closeInfoWindow();
				}
			});
		} else {
			alert('Punktet ble ikke lagret, du må være innlogget for å benytte deg av denne funksjonaliteten.');
		}
	},

	GetHomeLocation: function() {
		///<summary>
		/// Method called when the user is logged in in order to set start point
		/// on the map to the user's default home location.
		///</summary>
		var _self = this;
		if ((Membership.CurrentUser != null) && (Membership.CurrentUser.IsLoggedIn)) {
			new Ajax.Updater('testDiv',
                '/homelocation.aspx',
                {
                	method: 'post',
                	parameters: { mode: 'load' },
                	evalScripts: true
                });
		}
	},

	SetHomeLocation: function() {
		///<summary>
		/// Method called when activating the "Mitt hjemsted" feature
		///</summary>
		var _self = this;
		this.homeLocationListener = GEvent.addListener(this._map, 'click', function(overlay, latLng) {
			if (!overlay) {
				var marker = new GMarker(latLng, _self._setHomeLocationIcon());
				_self._map.addOverlay(marker);

				var lat = marker.getLatLng().lat();
				var lng = marker.getLatLng().lng();
				var zoom = _self._map.getZoom();

				var infoHtml = '<b>Mitt startpunkt</b>';
				infoHtml += '<br/>Dersom du ønsker at dette skal være ditt startpunkt<br/>';
				infoHtml += 'neste gang du logger deg på Trafikkflyt.no, klikk \"Lagre\" nedenfor.';
				infoHtml += '<br>';
				infoHtml += '<div onclick=\"RTMMap.SaveMapPoint(' + lat + ',' + lng + ',' + zoom + ');\" style="border: solid 1px black; padding: 2px; width: 50px;">';
				infoHtml += '<img src="/images/icons/disk.png" alt="Lagre"> Lagre';
				infoHtml += '</div>';
				marker.openInfoWindowHtml(infoHtml);

				GEvent.addListener(_self._map, 'infowindowclose', function() {
					_self._map.removeOverlay(marker);
				});
			}
		});
	},

	init: function() {
		///<summary>Initializes the RTM-map</summary>
		var _self = this;

		this._geoLocations = new GeoLocation();
		this._geoLocations.init();
		this._rtMessages = [];

		if (this.categorizedMarkers)
			this.categorizedMarkers.clearMarkers();

		if (!this.AllowMapRefresh) clearTimeout(RTMMap._mapRefreshTimer);

		if (GBrowserIsCompatible()) {
			this._map = new GMap2(document.getElementById("map"));
			this._map.enableScrollWheelZoom();

			// Disable default page scroll
			var mapDiv = document.getElementById("map");
			GEvent.addDomListener(mapDiv, "DOMMouseScroll", this._wheelevent);
			mapDiv.onmousewheel = this._wheelevent;

			// Make sure all infowindows are closed if the
			// user drags the map.
			GEvent.addListener(this._map, 'dragstart', function() {
				_self._map.closeInfoWindow();
			});

			// Set map center to Hemnes, Norway  
			this._centrePoint = new GLatLng(this._geoLocations.coords[0].lattitude, this._geoLocations.coords[0].longitude);
			this._setMapCenter(this._centrePoint, this._zLevel);

			// Add different map types
			this._map.addMapType(G_SATELLITE_MAP);
			this._map.addMapType(G_HYBRID_MAP);
			this._map.addMapType(G_PHYSICAL_MAP);

			// Add zoom-/pan control
			this._map.addControl(new GLargeMapControl());

			// Add scale control
			this._map.addControl(new GScaleControl());

			// P4s Trafikkredaksjon Lillehammer
			this._addP4Marker();

			// Add marker categories
			CategorizedMarkers.addCategory('rtm', 1, '/images/icons/RTM/severity_orange_16.png', '/images/icons/RTM/severity_orange_16.png'); // RTM-markers
			CategorizedMarkers.addCategory('rtmmed', 0, '/images/icons/RTM/severity_yellow_16.png', '/images/icons/RTM/severity_yellow_16.png'); // RTM-markers medium priority
			CategorizedMarkers.addCategory('rtmlow', 0, '/images/icons/RTM/severity_green_16.png', '/images/icons/RTM/severity_green_16.png'); // RTM-markers low priority
			CategorizedMarkers.addCategory('camera', 0, '/images/icons/camera.png', '/images/icons/camera.png'); // Traffic-cameras
			CategorizedMarkers.addCategory('airport', 0, '/images/icons/airports.png', '/images/icons/airports.png'); // Airports
			CategorizedMarkers.addCategory('partner', 1, '/images/partnericons/viking_logo.png', '/images/partnericons/viking_logo.png');   // Partners
			CategorizedMarkers.addCategory('bicyclestand', 0, '/images/icons/bicyclestand.png', '/images/icons/bicyclestand.png'); // City-bikes bicycle stands

			this.categorizedMarkers = CategorizedMarkers;

			// Read KML-feed with RTM-marker data.
			this._egeoRtm = new EGeoXml('egeoRtm', this._map, '/kml/feeds/roadmessages.ashx?pri=high', {
				baseicon: _self._set16By16Icon(),
				icontype: 'style', // Use the icon styles defined in the KML-feed.
				noshadow: 'true', // Prevents icons to appear as "doubles" when no shadowicon has been defined in the KML
				createCustomMarker: function(point, name, description, style, icon) {
					var marker = new GMarker(point, {
						icon: icon,
						title: name,
						zIndexProcess: function() { return 10000; }
					});
					GEvent.addListener(marker, "click", function() {
						var str = '';
						str += '<center><div id="tabMap" style="width: 250px; height: 100px; border: 1px black solid;"></div></center>';
						str += '<script type="text/javascript">';
						str += 'var point = new GLatLng(' + point.lat() + ',' + point.lng() + '); ';
						str += 'var marker = new GMarker(point); ';
						str += 'var tabMap = new GMap2(document.getElementById(\'tabMap\')); ';
						str += 'tabMap.setCenter(point,12); ';
						str += 'tabMap.addOverlay(marker); ';
						str += '</script>';

						str = description + str;

						// Hack: Map-details does not work in other browsers
						// than Firefox, seems that script-tags are skipped..
						var useragent = navigator.userAgent;
						if (useragent.indexOf('Firefox') > -1) marker.openInfoWindow(str, { maxWidth: 350 });
						else marker.openInfoWindow(description, { maxWidth: 350 });
					});
					GEvent.addListener(marker, "infowindowclose", function() {
						_self._setMapCenter(_self.currentCenter, _self.currentZoomLevel);
					});
					_self.categorizedMarkers.addMarker(marker, 'rtm');
					_self._rtMessages.push(new _self.RTM(marker.getLatLng(), name, description));
				}
			});

			// Medium pri rtm data
			this._egeoRtmMed = new EGeoXml('egeoRtmMed', this._map, '/kml/feeds/roadmessages.ashx?pri=med', {
				baseicon: _self._set16By16Icon(),
				icontype: 'style', // Use the icon styles defined in the KML-feed.
				noshadow: 'true', // Prevents icons to appear as "doubles" when no shadowicon has been defined in the KML
				createCustomMarker: function(point, name, description, style, icon) {
					var marker = new GMarker(point, {
						icon: icon,
						title: name,
						zIndexProcess: function() { return 9900; }
					});
					//_self._map.addOverlay(marker);
					GEvent.addListener(marker, "click", function() {
						var str = '';
						str += '<center><div id="tabMap" style="width: 250px; height: 100px; border: 1px black solid;"></div></center>';
						str += '<script type="text/javascript">';
						str += 'var point = new GLatLng(' + point.lat() + ',' + point.lng() + '); ';
						str += 'var marker = new GMarker(point); ';
						str += 'var tabMap = new GMap2(document.getElementById(\'tabMap\')); ';
						str += 'tabMap.setCenter(point,12); ';
						str += 'tabMap.addOverlay(marker); ';
						str += '</script>';

						str = description + str;

						// Hack: Map-details does not work in other browsers
						// than Firefox, seems that script-tags are skipped..
						var useragent = navigator.userAgent;
						if (useragent.indexOf('Firefox') > -1) marker.openInfoWindow(str, { maxWidth: 350 });
						else marker.openInfoWindow(description, { maxWidth: 350 });
					});
					GEvent.addListener(marker, "infowindowclose", function() {
						_self._setMapCenter(_self.currentCenter, _self.currentZoomLevel);
					});
					_self.categorizedMarkers.addMarker(marker, 'rtmmed');
					_self._rtMessages.push(new _self.RTM(marker.getLatLng(), name, description));
				}
			});

			// Low pri rtm data
			this._egeoRtmLow = new EGeoXml('egeoRtmLow', this._map, '/kml/feeds/roadmessages.ashx?pri=low', {
				baseicon: _self._set16By16Icon(),
				icontype: 'style', // Use the icon styles defined in the KML-feed.
				noshadow: 'true', // Prevents icons to appear as "doubles" when no shadowicon has been defined in the KML
				createCustomMarker: function(point, name, description, style, icon) {
					var marker = new GMarker(point, {
						icon: icon,
						title: name,
						zIndexProcess: function() { return 9900; }
					});
					//_self._map.addOverlay(marker);
					GEvent.addListener(marker, "click", function() {
						var str = '';
						str += '<center><div id="tabMap" style="width: 250px; height: 100px; border: 1px black solid;"></div></center>';
						str += '<script type="text/javascript">';
						str += 'var point = new GLatLng(' + point.lat() + ',' + point.lng() + '); ';
						str += 'var marker = new GMarker(point); ';
						str += 'var tabMap = new GMap2(document.getElementById(\'tabMap\')); ';
						str += 'tabMap.setCenter(point,12); ';
						str += 'tabMap.addOverlay(marker); ';
						str += '</script>';

						str = description + str;

						// Hack: Map-details does not work in other browsers
						// than Firefox, seems that script-tags are skipped..
						var useragent = navigator.userAgent;
						if (useragent.indexOf('Firefox') > -1) marker.openInfoWindow(str, { maxWidth: 350 });
						else marker.openInfoWindow(description, { maxWidth: 350 });
					});
					GEvent.addListener(marker, "infowindowclose", function() {
						_self._setMapCenter(_self.currentCenter, _self.currentZoomLevel);
					});
					_self.categorizedMarkers.addMarker(marker, 'rtmlow');
					_self._rtMessages.push(new _self.RTM(marker.getLatLng(), name, description));
				}
			});

			// Read KML-feed with partner-marker data.
			this._egeoPartner = new EGeoXml('egeoPartner', this._map, '/kml/feeds/partners.kml', {
				baseicon: _self._setVikingIcon(),
				icontype: 'style',
				noshadow: 'true',
				createCustomMarker: function(point, name, description, style, icon) {
					var marker = new GMarker(point, {
						icon: icon,
						title: name,
						zIndexProcess: function() {
							return 9000
						}
					});
					GEvent.addListener(marker, 'click', function() {
						marker.openInfoWindow('<b>' + name + '</b><br/>' + description, { maxWidth: 300 });
					});
					RTMMap.categorizedMarkers.addMarker(marker, 'partner');
				}
			});

			// Read KML-feed with camera info.
			this._egeoCameras = new EGeoXml('egeoCameras', this._map, '/kml/feeds/cameras.ashx', {
				baseicon: _self._set16By16Icon(),
				icontype: 'style',
				noshadow: 'true',
				useNameAsTitle: 'true',
				addmarker: _self._addCameraMarker
			});

			// Read KML-feed with airport & delay information.
			this._egeoAirports = new EGeoXml('egeoAirports', this._map, '/kml/feeds/airportsnorway.ashx', {
				baseicon: _self._set16By16Icon(),
				icontype: 'style',
				noshadow: 'true',
				useNameAsTitle: 'true',
				zIndex: 9000,
				addmarker: _self._addAirportMarker
			});

			// Read KML-feed with bicyclestands in Oslo
			this._egeoBikeStands = new EGeoXml('egeoBikeStands', this._map, '/kml/feeds/bicyclestands.ashx', {
				baseicon: _self._set16By16Icon(),
				icontype: 'style',
				noshadow: 'true',
				useNameAsTitle: 'true',
				addmarker: _self._addBicycleStandMarker
			});

			// Add marker overlay
			this._addMarkerOverlay();

			// Add area panel for country
			this.createAreaPanel('');

			// Refresh map every 10 minutes.
			this._refreshMap();
		}
	},

	_findGeoLocation: function(areaName) {
		///<summary>Get the Lat/Lng of the specified area from the list of predefined areas/points</summary>
		///<param name="areaName"></param>
		var point = null;
		for (var i = 0; i < this._geoLocations.coords.length; i++) {
			if (this._geoLocations.coords[i].area == areaName) {
				point = new GLatLng(this._geoLocations.coords[i].lattitude, this._geoLocations.coords[i].longitude);
				break;
			}
		}
		return point;
	},

	displayArea: function(areaName) {
		///<summary>Centers the map to the selected area</summary>
		///<param name="areaName"></param>
		this._map.closeInfoWindow();
		this._map.setZoom(7);
		this._map.panTo(this._findGeoLocation(areaName));
	},

	_addRTMMarkers: function() {
		///<summary>
		/// Method called after a route has been planned using 
		/// the route planner in order top add the missing RTM-markers.
		///</summary>
		var _self = this;
		var oldHandle = evtExmlParsed;
		GEvent.clearListeners(this._egeoRtm);
		GEvent.addListener(this._egeoRtm, 'parsed', function() {
			GEvent.clearListeners(_self._egeoRtm);
			evtExmlParsed = GEvent.addListener(_self._egeoRtm, 'parsed', handleExmlParsed);
			_self._map.returnToSavedPosition();
		});
		_self._egeoRtm.parse();
	}
};

var MapTypeMenu = {
    ///<summary>Object-variable holding the methods used to handle the 'Karttyper' menu</summary>

    startMouseObserving: function(skipItem) {
        ///<summary>Method used when adding mouseover/mouseout observers to the menuitems</summary>
        ///<param name="skipItem">
        /// The selected element, skip adding mouseout observer for this
        /// in order to make it appear selected.
        ///</param>

        for (var i = 0; i < $('contents').childElements().length; i++) {
            var el = $('contents').childElements()[i];
            if (el.id == skipItem) {
                Event.stopObserving(el, 'mouseout');
            } else {
                el.style.textDecoration = 'none';
                Event.observe(el, 'mouseover', function(ev) { $(Event.element(ev)).style.textDecoration = 'underline'; });
                Event.observe(el, 'mouseout', function(ev) { $(Event.element(ev)).style.textDecoration = 'none'; });
            }
        }
    },

    startClickObserving: function() {
        ///<summary>Method used to append 'click' observing to the menuitems</summary>

        for (var i = 0; i < $('contents').childElements().length; i++) {
            Event.observe($('contents').childElements()[i], 'click', function(ev) {
                var map = RTMMap._map;
                var el = $(Event.element(ev));
                switch (el.id) {
                    case 'mapTypeNormal':
                        map.setMapType(G_NORMAL_MAP);
                        break;
                    case 'mapTypeSatellite':
                        map.setMapType(G_SATELLITE_MAP);
                        break;
                    case 'mapTypePhysical':
                        map.setMapType(G_PHYSICAL_MAP);
                        break;
                    case 'mapTypeHybrid':
                        map.setMapType(G_HYBRID_MAP);
                        break;
                }
                MapTypeMenu.startMouseObserving(el.id);
            });
        }
    }
}

function switchMap(id) {
    ///<summary>
    /// Method used when switching between the RTMs,
    /// the Routeplanner and the Trelocity map.
    ///</summary>
    ///<param name="id">ID of the clicked item</param>
    $('areaPanel').update();
    switch (id) {
        case 'mapTabAreas':
            RoutePlanner.end();
            RTMMap.AllowMapRefresh = true;
            RTMMap._refreshMap();
            $('trelocityMap').hide();
            $('areaList').show();
            $('map').show();
            break;
        case 'mapTabRoutePlanner':
            $('trelocityMap').hide();
            $('mapTabMapType').show();
            $('map').show();
            RTMMap.AllowMapRefresh = false;
            RoutePlanner.init(RTMMap._map);
            RoutePlanner.start();
            break;
           case 'mapTabTrelocity':
           	RoutePlanner.end();
           	RTMMap.AllowMapRefresh = false;
           	RTMMap._refreshMap();
           	frames['trelocityIFrame'].location.href = "http://oslo.trelocity.se/";
           	__LogWidgetHits('Trelocity');
           	$('areaList').hide();
           	$('map').hide();
           	$('trelocityMap').show();
           	break;
    }
    setButtonActive(id);
}

function setButtonActive(id) {
    ///<summary>Method used to set the active button's background orange</summary>
    ///<param name="id">ID of the clicked button</param>
    var obj = $(id);
    var child = obj.childElements()[0];

    // Remove event-listener added when the "Mitt hjemsted" button was clicked
    if ((RTMMap.homeLocationListener != null) && (id != 'mapTabHomeLocation')) {
        GEvent.removeListener(RTMMap.homeLocationListener);
    }

    if (id == 'mapTabRoutePlanner') {
        //$('mapTabAreas').style.background = 'transparent url(\'/images/gfx/map_tab_left.png\') no-repeat';
        //$('mapTabAreas').childElements()[0].style.background = 'transparent url(\'/images/gfx/map_tab.png\') no-repeat';
        $('mapTabAreas').className = "maptab";

        //$('mapTabTrelocity').style.background = 'transparent url(\'/images/gfx/map_tab_left.png\') no-repeat';
        //$('mapTabTrelocity').childElements()[0].style.background = 'transparent url(\'/images/gfx/map_tab.png\') no-repeat';
        $('mapTabTrelocity').className = "maptab";

        //obj.style.background = 'transparent url(\'/images/gfx/map_tab.png\') no-repeat scroll bottom left';
        //child.style.backgroundPosition = 'bottom left';
        obj.className = "maptabselect";
    } else if (id == 'mapTabAreas') {
        $('mapTabMapType').show();
        
        //$('mapTabRoutePlanner').style.background = 'transparent url(\'/images/gfx/map_tab.png\') no-repeat';
        //$('mapTabRoutePlanner').childElements()[0].style.background = 'transparent url(\'/images/gfx/map_tab.png\') no-repeat';
        $('mapTabRoutePlanner').className = "maptab";
        
        //$('mapTabTrelocity').style.background = 'transparent url(\'/images/gfx/map_tab_left.png\') no-repeat';
        //$('mapTabTrelocity').childElements()[0].style.background = 'transparent url(\'/images/gfx/map_tab.png\') no-repeat';
        $('mapTabTrelocity').className = "maptab";

        //obj.style.background = 'transparent url(\'/images/gfx/map_tab_left.png\') no-repeat scroll bottom left';
        //child.style.backgroundPosition = 'bottom left';
        obj.className = 'maptabselect';
    } else if (id == 'mapTabTrelocity') {
        //$('mapTabAreas').style.background = 'transparent url(\'/images/gfx/map_tab_left.png\') no-repeat';
        //$('mapTabAreas').childElements()[0].style.background = 'transparent url(\'/images/gfx/map_tab.png\') no-repeat';
        $('mapTabAreas').className = "maptab";

        //$('mapTabRoutePlanner').style.background = 'transparent url(\'/images/gfx/map_tab.png\') no-repeat';
        //$('mapTabRoutePlanner').childElements()[0].style.background = 'transparent url(\'/images/gfx/map_tab.png\') no-repeat';
        $('mapTabRoutePlanner').className = "maptab";

        $('mapTabMapType').hide();
        
        //obj.style.background = 'transparent url(\'/images/gfx/map_tab_left.png\') no-repeat scroll bottom left';
        //child.style.backgroundPosition = 'bottom left';
        obj.className = "maptabselect";
    }
}

function getLeftPos(obj) {
    ///<summary>Method used to get the left position of the menutab</summary>
    ///<param name="obj">Object to get the left position for</param>
    return (obj.style.left).replace('px', '');
}


