try
{
    wedebug.addLogger("gui", "GUIController");    
}
catch(e)
{
    alert(e.message);
}


var GUIController = Class.create();

GUIController.prototype = {
    m_mapController : null,
    m_shortestPathController : null,
    m_menuController : null,
    m_xmlTemp : null,
    m_onRSSLoaded : null,
    //m_idprefix : 'http://test.gisline.no/GISLINEPOI/RssService.aspx?command=GetPOI&amp;',
    m_bubbleBase : '<div id="pop"><div id="popinnerwrapper"><div id="popHeader"></div><div id="popBody"></div></div></div>',
        
    initialize : function(t_mapController, t_shortestPathController, t_menuController) {
        wedebug.log("gui", "GUIController.initialize: " + [t_mapController, t_shortestPathController]);
        this.m_mapController = t_mapController;
        this.m_menuController = t_menuController;
        this.m_mapController.addEventListener("onbeginpan", this._cb_onBeginPan.bind(this));
        this.m_mapController.addEventListener("onendpan", this._cb_onEndPan.bind(this));
        this.m_mapController.addEventListener("onbeginzoomrect", this._lowerMapControls.bind(this));
        this.m_mapController.addEventListener("onendzoomrect", this._elevateMapControls.bind(this));
        this.m_mapController.addEventListener("onpan", this._cb_onPan.bind(this));
        this.m_mapController.addEventListener("onchangeview", this._cb_onChangeView.bind(this)); 
        this.m_mapController.addEventListener("onbeginslide", this._cb_onBeginSlide.bind(this));
        this.m_mapController.addEventListener("onendslide", this._cb_onEndSlide.bind(this));
        
        try
        {
            this.m_mapController.addEventListener("onloadbirdseye", this._cb_onLoadBirdsEye.bind(this));
            this.m_mapController.addEventListener("onbirdseyeloaded", this._cb_onBirdsEyeLoaded.bind(this));
            this.m_mapController.addEventListener("onbirdseyefailed", this._cb_onBirdsEyeLoaded.bind(this));
        }
        catch(e)
        {
            //ignore
        }
            
        this.m_mapController.addEventListener("onmapstylechange", this._cb_onMapStyleChange.bind(this));
        this.m_shortestPathController = t_shortestPathController;
        
        this.m_onRSSLoaded = this.addEventType("onrssloaded");        
    },
    
    /**
	 * Load up a GeoRSS file asyncronously
	 */
	_requestStamp : 0,
	loadGeoRSS : function(t_url, t_collectionId, t_icon, t_responseCoordSys, t_upperLevel, t_setBox, t_offsetX, t_offsetY)
	{
	    var id = (t_collectionId) ? t_collectionId : "_defaultRSS"; //new Date().valueOf();
	    
	    //Is t_url complete?
	    if( t_url.substring(0,1) == "/" )
	    {
	        var t_baseurl = window.location.href.substring(0, window.location.href.indexOf("/",8));
	        t_url = t_baseurl + t_url;
	        
	    }
	    
	    wedebug.log("gui", "-> loadGeoRSS: " + t_url);
	    if (document.implementation && document.implementation.createDocument)
	    {
	        wedebug.log("gui", "Loading xml using document.implementation.createDocument.");
		    this.m_xmlTemp = document.implementation.createDocument("", "", null);
		    this.m_xmlTemp.async = "false";
		    this.m_xmlTemp.onload = this._addAnnotationsFromXML.bind(this, id, t_icon, t_responseCoordSys, t_upperLevel, t_setBox, t_offsetX, t_offsetY, ++this._requestStamp);
	    }
	    else if(document.documentElement && typeof document.documentElement.style.maxHeight!="undefined")
	    {
	        wedebug.log("gui", "Loading xml using xml island.");
	        var t_xmlIsland = document.getElementById("xmlI");
    	    if(t_xmlIsland != null)
    	    {
    	        t_xmlIsland.async = false;
    	        wedebug.log("gui", "Retrieving RSS feed.", "time");
    	        
    	        t_xmlIsland.load(t_url);
                this.m_xmlTemp = t_xmlIsland;
                this._addAnnotationsFromXML.bind(this, id, t_icon, t_responseCoordSys, t_upperLevel, t_setBox, t_offsetX, t_offsetY, ++this._requestStamp)();                
    	    }
    	    else
    	    {
    	        wedebug.log("gui", "Page is missing element xmlI. This is required for XML support for this browser.", "error");
    	    }
	    	
	        return;
	    }	
	    else if (window.ActiveXObject)
	    {
	        try
	        {
	            wedebug.log("gui", "Loading xml using Microsoft.XMLDOM.");
	            this.m_xmlTemp = new ActiveXObject("Microsoft.XMLDOM");
	            this.m_xmlTemp.async = "false";
	            this.m_xmlTemp.onreadystatechange = this._addAnnotationsFromXML.bind(this, id, t_icon, t_responseCoordSys, t_upperLevel, t_setBox, t_offsetX, t_offsetY, ++this._requestStamp);
		    }catch(e){alert(e.message);}
 	    }
 	    else
 	    {
		    wedebug.log("gui", "Browser unable to load geoRss. Missing native XML support.", "error");
		    return;
	    }
	    wedebug.log("gui", "Retrieving RSS feed.", "time");
	    this.m_xmlTemp.load(t_url);
    },
    
    addAnnotationsFromService : function(POI, t_collectionId, t_upperLevel)
    {
        var t_markers = new Array();
        for (i=0;i<POI.length;i++){
            var wgs = UTMToLatLon(Number(POI[i].Coordinate.Northing), Number(POI[i].Coordinate.Easting), 33);
            var t_geoLat = wgs.lat;
            var t_geoLon = wgs.lon;
       
            id = i;
            //FIXME: dynamic icon
            var t_icon = "";
            if(POI[i].Typename == 'Informasjon tilgjengelig')
                var t_icon = "Resource/Map/images/gfx2/poi/gjengsymbol.gif";
            else
                var t_icon = "Resource/Map/images/gfx2/poi/" + POI[i].Typename + ".gif";
            var t_type = POI[i].Typename;
            //var t_icon = "/tolk/Resource/Map/images/gfx2/poi/1.gif";
            var t_coords = {'x': Number(t_geoLon),'y':Number(t_geoLat)};  
            var t_title = POI[i].Name;
            var t_description = "<div>" + POI[i].Description + "</div>"
            var t_url1 = POI[i].Url;
            var t_url2 = POI[i].Url2;
            var t_url3 = POI[i].Url3;
            var t_visible = POI[i].Visibility;
            //t_description += "<br/><div><span>Lag veibeskrivelse:&nbsp;</span><span class='link' onclick='shortestPathController.setDestination(\"" + t_title + "\", " + t_geoLat + ", " + t_geoLon + ");'>Til hit</span>";
            //t_description += "&nbsp;<span class='link' onclick='shortestPathController.setStart(\"" + t_title + "\", " + t_geoLat + ", " + t_geoLon + ");'>Herfra</span>";
            //t_description += "</div>";
            t_markers.push([
                        "poi_" + id,
                        t_icon,
                        t_coords.y,
                        t_coords.x, 
                        t_title,
                        t_description,
                        this.cb_onHotspotTrigger.bind(this),
                        null,
                        null,
                        null,
                        null,
                        t_type,
                        t_url1,
                        t_url2,
                        t_url3,
                        t_visible
                        ]);
        
        }
        this.m_mapController.setHotspots(t_collectionId, t_markers, t_upperLevel);        
    },
    
    /**
     * Adds annotations from a xml file. Uses the geoRSS standard. FIXME: IE7 support!
     */
    _addAnnotationsFromXML : function(t_collectionId, t_icon, t_responseCoordSys, t_upperLevel, t_setBox, t_offsetX, t_offsetY, requestNr)
    {
        wedebug.log("gui", "-> _addAnnotationsFromXML: " + [t_collectionId, t_icon, t_responseCoordSys, requestNr]);
        wedebug.log("gui", "RSS Feed loaded", "time");
        if( this._requestStamp > requestNr )
        {
            wedebug.log("gui", "Request callback " + requestNr + " ignored. Global requestStamp: " + this._requestStamp);
        }
        else
        {
            var x = this.m_xmlTemp.getElementsByTagName('item');

            var t_length = 0;
            try{    	    
                t_length = (x != null)?x.length:0;
            }
            catch(e)
            {
                //Exception is thrown in IE6
                //Investigate further if causing trouble.
            }	    
            if(t_length==0)
            {
                x = this.m_xmlTemp.getElementsByTagName('entry');
                
                try{    
                    t_length = (x != null)?x.length:0;
                }
                catch(e)
                {
                    //Exception is thrown in IE6
                    //Investigate further if causing trouble.
                }	
            }
    	    
            wedebug.log("gui", "Number of RSS items: " + t_length);
            
            var t_markers = new Array();
            
            var t_west = 180, t_east = -180, t_north = -90, t_south = 90;
            for (i=0;i<t_length;i++){
	            var t_icon = (typeof t_icon != "undefined" && t_icon != null) ? t_icon : "/Resource/Map/gfx2/leftmenu/poi/universitet.gif";
	            var t_title = null, t_description = "", t_geoLat = null, t_geoLon = null, id = t_collectionId + "_" + i;
	            for (j=0;j<x[i].childNodes.length;j++){	                
	                if (x[i].childNodes[j].nodeType != 1){continue;}
	                
	                try
	                {
		                if (x[i].childNodes[j].tagName == 'title'){t_title = x[i].childNodes[j].firstChild.nodeValue;}
		                if (x[i].childNodes[j].tagName == 'description' || x[i].childNodes[j].tagName == 'content')
		                {   
		                    t_description = x[i].childNodes[j].firstChild.nodeValue;	            
    		             
		                    var cdataloc = t_description.indexOf("<![CDATA[");
		                    if( cdataloc != -1 )
		                    {
		                        var dlength = t_description.length;
		                        t_description = t_description.substring(9, dlength - 3);		                    
		                    }
		                }
    		            
		                if (x[i].childNodes[j].tagName == 'icon'){t_icon = x[i].childNodes[j].firstChild.nodeValue;}
		                if (x[i].childNodes[j].tagName == 'gisline:ikonurl'){t_icon = x[i].childNodes[j].firstChild.nodeValue;}
		                if (x[i].childNodes[j].tagName == 'ikonurl'){t_icon = x[i].childNodes[j].firstChild.nodeValue;}					    
		                if (x[i].childNodes[j].tagName == 'geo:lat'){t_geoLat = x[i].childNodes[j].firstChild.nodeValue;}
	                    if (x[i].childNodes[j].tagName == 'geo:long'){t_geoLon = x[i].childNodes[j].firstChild.nodeValue;}
	                    if (x[i].childNodes[j].tagName == 'id'){id = x[i].childNodes[j].firstChild.nodeValue;}
        		        
        		        
	                    if (x[i].childNodes[j].tagName == 'georss:where' || x[i].childNodes[j].tagName == 'where')
	                    {	                        
	                        var value = x[i].childNodes[j].text;
	                        
	                        if( value == null )
	                        {
	                            //For firefox.
	                            value = x[i].childNodes[j].textContent;
	                        }
	                        	                        
    	                    //if(i==0)alert(["test", i,j,x[i].childNodes[j].tagName, value]);
	                        if( value.indexOf(",") != -1 )
	                        {
	                            wedebug.log("gui", "Georss feed coordinates uses comma as decimal separator.", "warn");
	                            value = value.replace(/,/g, ".");
	                        }	                        
    	                    
	                        //var pos = location[0].firstChild.nodeValue.split(" ");                        
                            var pos = value.strip().split(" ");
                            
                            if ( typeof t_responseCoordSys != "undefined" && t_responseCoordSys != null)
                            {
                                var wgs = UTMToLatLon(Number(pos[0]), Number(pos[1]), t_responseCoordSys + 10);
                                t_geoLat = wgs.lat;
                                t_geoLon = wgs.lon;
                            }
                            else
                            {
                                t_geoLat = Number(pos[0].strip());
                                t_geoLon = Number(pos[1].strip());                            
                            }
	                    }
    		        }catch(e){}
	                // FIXME: uncomment to enable wgs84coords
	                //var newCoords = decimalDegreesToUTM(coords);
                }
                
                if( t_geoLat != null && t_geoLon != null)
                {                    
                    var t_coords = {'x': Number(t_geoLon),'y':Number(t_geoLat)};   
                    
                    if( t_coords.x != 0 && t_coords.y != 0 )
                    {
                        if( t_coords.x < t_west ) t_west = t_coords.x;
                        if( t_coords.x > t_east ) t_east = t_coords.x;
                        if( t_coords.y < t_south ) t_south = t_coords.y;
                        if( t_coords.y > t_north ) t_north = t_coords.y;         
                        
                        t_markers.push([
                            id,
                            t_icon,
                            t_coords.y,
                            t_coords.x, 
                            t_title,
                            t_description,
                            this.cb_onHotspotTrigger.bind(this),
                            undefined,
                            undefined,
                            t_offsetX,
                            t_offsetY]);
                    }
                    else
                    {
                        wedebug.log("gui", "Rss item is missing valid coordinates.", "warn");
                    }
                }
                else
                {
                    wedebug.log("gui", "Rss item is missing geo:lat/geo:lon.", "warn");
                }
	        }
	        
	        if( typeof t_setBox != "undefined" && t_setBox == true )
	        {
	            if( t_west != 180 && t_east != -180 && t_south != 180 && t_north != -180 )
	            {
	                var t_navMenuWidth = 80; //TODO: get value from controller
	            
	                //expand on left cause of navigation menu and possibly left menu
	                var t_resx = t_east - t_west;
                    
                    var t_width = this.m_mapController.getWidth();                    
                    var t_menuRelSize = 0;
                    var t_mapWidth = 0;
                    
	                if( this.m_menuController != null && this.m_menuController.isVisible() )
	                {	     
	                    t_mapWidth = t_width - this.m_menuController.getMenuWidth() - t_navMenuWidth;	                               
	                    //t_menuRelSize = (this.m_menuController.getMenuWidth() + t_navMenuWidth) / t_width;
	                }
	                else
	                {
	                    t_mapWidth = t_width - t_navMenuWidth;	                
	                    t_menuRelSize = t_navMenuWidth / t_width;
	                }
	                
	                var t_newResX = (t_resx*t_mapWidth) / t_width;
	                
	                w = t_west - (t_resx - t_newResX);
                    e = t_east;
                    s = t_south;
                    n = t_north;

                    //Offset bbox according to 

	                this.m_mapController.setViewport(w, s, e, n);
	                
	                var t_center = this.m_mapController.getCenter();
	                var t_level = this.m_mapController.getZoomLevel();
	                this.m_mapController.setInitialPosition(
	                        t_center.lat,
	                        t_center.lon,
	                        t_level    
	                    );
	            }
	        }
    		// HACK: Ensure that the first point is added to the topmost layer in the map, as
    		// it is probably the most important (i.e. the 'start' point in a route).
    		if( t_markers.length > 2 )
	        {
	            var t_tmpMarker = t_markers[t_markers.length -2];
	            t_markers[t_markers.length -2] = t_markers[0];
	            t_markers[0] = t_tmpMarker;
	        }
	        
	        if( t_markers.length > 0 )
	        {
	            this.m_mapController.setHotspots(t_collectionId, t_markers, t_upperLevel);
	        }
	        else
	        {
	            this.m_mapController.removeHotspots(t_collectionId);	            
	        }
	        
	        this.m_onRSSLoaded.fire(t_collectionId, t_length, {west:t_west, east:t_east, south:t_south, north:t_north});
	    }
	},
	
	setFlag : function(t_lat, t_lon, t_title, t_content)
	{
	/*
	    this.m_mapController.setHotspot(
	        "Resource/Map/images/gfx2/poi/tegnestift.gif",
	        t_lat,
	        t_lon,
	        -20,
	        -32,
	        t_title,
	        t_content
	    );
	    */
	},
    addFlags : function(flags){
    var t_markers = new Array();
    		for(var i = 0; i < flags.length; i++){
    		var northing = flags[i].y;
    		var easting = flags[i].x;
    		var title = flags[i].labeltext;
    		t_collectionId = 'cID';
		    t_upperLevel = 99;
		    

            var wgs = UTMToLatLon(Number(northing), Number(easting), 33);
            var t_geoLat = wgs.lat;
            var t_geoLon = wgs.lon;
       
            id = 'flag';
            //FIXME: dynamic icon
            //var t_icon = "Resource/Map/images/gfx2/poi/" + POI[i].Typename + ".gif";
            var t_type = "flag";
            var t_icon = "Resource/Map/images/gfx2/poi/tegnestift.gif";
            var t_coords = {'x': Number(t_geoLon),'y':Number(t_geoLat)};  
            var t_title = title;
            var t_description = ""
            var t_url1 = "";
            var t_url2 = 'url2';
            var t_url3 = 'url3';
            var t_visible = true;
            
            t_markers.push([
                         id,
                        t_icon,
                        t_coords.y,
                        t_coords.x, 
                        t_title,
                        "flag",
                        this.cb_onHotspotTrigger.bind(this),
                        null,
                        null,
                        -20,
                        -32,
                        t_title,
                        "",
                        "",
                        "",
                        false
                        ]);
        
         
     /*
        	 this.m_mapController.setHotspot(
	        "Resource/Map/images/gfx2/poi/b.gif",
	        wgs.lat,
	        wgs.lon,
	        0,
	        0,
	        "",
	        ""
	        );*/
	        }
    this.m_mapController.setHotspots(t_collectionId, t_markers, t_upperLevel); 
    },
    
    addSingleAnnotation: function(northing, easting,cat,title,description,url){
		t_collectionId = 'cID';
		t_upperLevel = 99;
		        var t_markers = new Array();

            var wgs = UTMToLatLon(Number(northing), Number(easting), 33);
            var t_geoLat = wgs.lat;
            var t_geoLon = wgs.lon;
       
            id = 'sid0';
            //FIXME: dynamic icon
            //var t_icon = "Resource/Map/images/gfx2/poi/" + POI[i].Typename + ".gif";
            var t_type = cat;
            var t_icon = "Resource/Map/images/gfx2/poi/tegnestift.gif";
            var t_coords = {'x': Number(t_geoLon),'y':Number(t_geoLat)};  
            var t_title = title;
            var t_description = description
            var t_url1 = url;
            var t_url2 = 'url2';
            var t_url3 = 'url3';
            var t_visible = true;
            
            t_markers.push([
                        "poi_" + id,
                        t_icon,
                        t_coords.y,
                        t_coords.x, 
                        t_title,
                        t_description,
                        this.cb_onHotspotTrigger.bind(this),
                        null,
                        null,
                        -20,
                        -32,
                        t_type,
                        t_url1,
                        t_url2,
                        t_url3,
                        t_visible
                        ]);
        
        this.m_mapController.setHotspots(t_collectionId, t_markers, t_upperLevel);  
        if(cat != "Adresse" && cat != "Stedsnavn" && cat){     
        	 this.m_mapController.setHotspot(
	        "Resource/Map/images/gfx2/poi/"+cat+".gif",
	        wgs.lat,
	        wgs.lon,
	        0,
	        0,
	        "",
	        ""
	        );
	        }
		},
	/**
	Callback for map hotspot
	*/
	m_displayBubbles : true,
	m_openBubble : false,
	m_currentBubble : null,
	cb_onHotspotTrigger : function(t_title, t_description, t_lat, t_lon, t_imgX, t_imgY, t_type,t_url1,t_url2,t_url3,t_visible)
	{
	    if( this.m_openBubble )
	    {
	        this.closeBubble();
	    }
	    if(this.m_displayBubbles == true){
	    if(t_visible == "1"){
	    var t_offsetY = 0;
	    var t_offsetX = -40;
	    wedebug.log("gui", "-> cb_onHotspotTrigger: " + [t_title,t_description,t_lat,t_lon, t_imgX, t_imgY]);
	    
	    
        try{
	        //Set bubble
	        var t_controlPane = $("bubbleContainer");//this.m_mapController.getControlPane();
	        var t_div = $dom("div");
	        t_div.innerHTML = this.m_bubbleBase;	        
	        t_div.$addTo(t_controlPane);
	        
	        $("popHeader").innerHTML = t_type;
	        
	        if(t_type == 'Informasjon tilgjengelig')
	            $("popHeader").innerHTML += "<div onclick='window.parent.guiController.closeBubble()' style='position:absolute;right:10px;top:6px'><img src='Resource/Map/images/gfx2/poi/closebutton.jpg' /></div>";

	        $("popBody").innerHTML = '<div>' + t_title + '</div>' + '<br />';// + t_description;
	        if(t_type != 'Informasjon tilgjengelig')
	        if(t_url1 != ""){
	            $("popBody").innerHTML += '<a href="'+t_url1+'" target="new">Les mer om '+t_title+'</a>';
	        }
    	    
    	    //Ved rare feil, sjekk at det kan scriptes umiddelbart mot lastede ressurser
    	    
	        var t_element = $("pop");
            t_element.style.display = "none";
	        t_offsetY = -Element.getHeight(t_element);
	        
	        var t_x = Number(t_imgX.replace(/px/g, "")) + t_offsetX;
            //var t_y = Number(t_imgY.replace(/px/g, "")) + t_offsetY;
	        var t_y = Number(t_imgY.replace(/px/g, ""));
	        if( t_x < this.m_mapController.getWidth() &&
                t_y < this.m_mapController.getHeight() )
            {
                t_element.style.left = t_x + 10+"px";
	            t_element.style.top = t_y + "px";
	            this.m_openBubble = true; 
	            t_element.style.display = "block";   
	        }	 
	        else
	        {
	            t_controlPane.removeChild(t_div);
	        }       	    
	    }
	    catch(e)
	    {
	        wedebug.log("gui", "cb_onHotspotTrigger: Exception loading bubble content. " + e.message, "error");
	    }
	    
	    this.m_currentBubble = {
	        title : t_title,
	        description : t_description,
	        lat : t_lat,
	        lon : t_lon,
	        offsetY : t_offsetY,
	        offsetX : t_offsetX
	    };
	    }
	    }
	},
	
	toggleDisplayBubbles : function(){
	    this.m_displayBubbles = ! this.m_displayBubbles;
	    
	    if(this.m_displayBubbles == true)
	        $('vis_bobler').innerHTML = "Ikke vis informasjonsbokser";
	    else
	        $('vis_bobler').innerHTML = "Vis informasjonsbokser";
	},
	
	openLoypePop : function(t_value)
	{
	//alert("blab");
	    if(this.m_displayBubbles == true){
	        if(this.m_openBubble == false){
	        if(t_value != null){
		           var t_element = $("loypePop");
		           $("loypePop").innerHTML = t_value;
		           

		           viewportwidth = document.getElementsByTagName('body')[0].clientWidth;
                   viewportheight = document.getElementsByTagName('body')[0].clientHeight;
		           t_element.style.display = "block";

		           var w = Element.getWidth('loypePop');
		           var h = Element.getHeight('loypePop');
		           var popLeft = t_element.offsetLeft; 
		           if(popLeft + w +50 > viewportwidth){
		           //$('loypePop').style.top = (h) + "px";
                   $('loypePop').style.left = (viewportwidth - 50 - w) +"px";
                   }        
                   map.setSelectLayer($("selectedID").innerHTML,$("selectedIDLayer").innerHTML);
                   map._createWMSLayer();
                   }
            }
        }
	},
	
	closeLoypePop : function()
	{
			       var t_element = $("loypePop");
			       
            t_element.style.display = "none";
	},
	
	closeBubble : function()
	{
	    var t_element = $("pop");
	    
	    if(t_element != null)
	    {
	        Element.remove(t_element);
	    }
	    this.m_openBubble = false;
	    this.m_currentBubble = null;
	},
	
   /**
    * Displays a loading indicator
    */
    _spinnerCounter : 0,
	showSpinner : function()
	{
	    this._spinnerCounter++;
	    $("spinner").style.display = 'block';
	},
   /**
    * Removes the loading indicator
    */
	hideSpinner : function()
	{
	    this._spinnerCounter--;
	    
	    if( this._spinnerCounter == 0 )
	    {
	        $("spinner").style.display = 'none';
	    }
	},
	
	_hasPoint : false,
	m_pointData : "",
	setPointData : function(pointData)
	{
	    this._hasPoint = true;
	    this.m_pointData = pointData;
	},
	
	getPointData : function()
	{
	    return this.m_pointData;	    
	},
	
	clearPointData : function()
	{
	    this._hasPoint = false;
	    this.m_pointData = "";
	},
	
	_hasPath : false,
	m_spStart : null,
	m_spDestination : null,
	m_spViewport : null,
	showShortestPath : function(t_startValues, t_destinationValues)
	{	    
	    if(this.m_mapController.getMapStyle() == MapController.Styles.BIRDS_EYE)
	    {
	        this.m_mapController.setMapStyle(MapController.Styles.REGULAR);
	    }
	
	    this._hasPath = true;
	    
	    if( typeof t_startValues != "undefined" )
	    {
	        this.m_spViewport = this.m_spViewport = this._parseShortestPathViewport(t_startValues, t_destinationValues);;
	        this.m_spStart = t_startValues;
	        this.m_spDestination = t_destinationValues;	        
	    }
	    this._updateShortestPath();
	},
	
	setShortestPath : function(t_startValues, t_destinationValues)
	{
	    this._hasPath = true;
	    this.m_spStart = t_startValues;
	    this.m_spDestination = t_destinationValues;
	    this.m_spViewport = this._parseShortestPathViewport(t_startValues, t_destinationValues);
	},
	
	_parseShortestPathViewport : function(t_startValues, t_destinationValues)
	{
	    var t_startHash = t_startValues.toQueryParams();
        var t_lat1 = parseFloat(t_startHash.lat1);
        var t_lon1 = parseFloat(t_startHash.lon1);
        
        var t_destHash = t_destinationValues.toQueryParams();
        var t_lat2 = parseFloat(t_destHash.lat2);
        var t_lon2 = parseFloat(t_destHash.lon2);
        
        var t_viewport = {
            minLat : (t_lat1 < t_lat2) ? t_lat1 : t_lat2,
            maxLat : (t_lat1 < t_lat2) ? t_lat2 : t_lat1,
            minLon : (t_lon1 < t_lon2) ? t_lon1 : t_lon2,
            maxLon : (t_lon1 < t_lon2) ? t_lon2 : t_lon1
        };
        
        return t_viewport;
	},
	
	getShortestPath : function()
	{   
	    if( this._hasPath )
	    {
	        return {
	            start : this.m_spStart,
	            destination : this.m_spDestination,
	            viewport : this.m_spViewport
	        }
	    }
	    return null;
	},
	
	disableShortestPath : function()
	{
	    this._hasPath = false;
	    
	    var cp = this.m_mapController.getControlPane();
	    Element.setStyle(cp, 
        {
            "background-image": ""
        });
        
        //HACK: hide route layer from vemap
        this.m_mapController.hideLine("route");
	},
	
	_cb_onEndSlide : function(direction)
	{
	    this._updateShortestPath();
	},
	
	_cb_onBeginSlide : function()
	{
	    var cp = this.m_mapController.getControlPane();
	    Element.setStyle(cp, 
        {
            "background-image": ""
        });
	},
	
	_cb_onLoadBirdsEye : function()
	{
	    this.showSpinner();
	},
	
	_cb_onBirdsEyeLoaded : function()
	{
	    this.hideSpinner();
	},
	
	_cb_onMapStyleChange : function(t_style)
	{
	    if( t_style == MapController.Styles.BIRDS_EYE )
	    {
	        Element.show($("minimapContainer"));
	        
	        //Hide print/email/favorites field.
	        var t_favField = $("printSend");
	        if( t_favField != null )
	        {
	            t_favField.style.display = "none";
	        }
	    }
	    else
	    {
	        Element.hide($("minimapContainer"));
	        
	        //Show print/email/favorites field.
	        var t_favField = $("printSend");
	        if( t_favField != null )
	        {
	            t_favField.style.display = "block";
	        }
	    }
	},	
	
	_updateShortestPath : function(t_viewport)
	{
	    if(!this._hasPath)return;
	    
	    if( typeof t_viewport == "undefined" )
	    {
	        t_viewport = this.m_mapController.getViewport();
	    }
	    
	    //Update shortest path drawing.
	    var t_southWest = decimalDegreesToUTM({x:t_viewport.minLon, y:t_viewport.minLat});
	    var t_northEast = decimalDegreesToUTM({x:t_viewport.maxLon, y:t_viewport.maxLat});
	    
	    var t_args = null;
	    var t_url = null;
	    
	    //Get the first and last point.
	    if( this.m_spStart != null )
	    {
	        var t_qsstart = this.m_spStart.toQueryParams();
	        var t_qsdestination = this.m_spDestination.toQueryParams();
	        
	        t_args = $H({ "WIDTH":  t_viewport.width, "HEIGHT": t_viewport.height, "WEST": t_southWest.x, "EAST": t_northEast.x, "SOUTH": t_southWest.y, "NORTH": t_northEast.y, "lat1" : t_qsstart.lat1, "lon1" : t_qsstart.lon1, "lat2": t_qsdestination.lat2, "lon2" : t_qsdestination.lon2});	    
	        t_url = "/tolk/Page/Map/RouteImageTransfer.aspx?" + t_args.toQueryString();
	    }  
	    else
	    {
	        t_args = $H({ "WIDTH":  t_viewport.width, "HEIGHT": t_viewport.height, "WEST": southwest.x, "EAST": t_northEast.x, "SOUTH": southwest.y, "NORTH": t_northEast.y});	    	        
	        t_url = "/tolk/Page/Map/RouteImage.aspx?" + t_args.toQueryString();
	    }
	   
	    var cp = this.m_mapController.getControlPane();

        try
        {
            Element.setStyle(cp, 
                {
                    "background-image": "url(" + t_url + "&run=" + new Date().getTime() + ")"
                });
        }
        catch(e){alert(e.message);}
	},
	
	_showBubble : function()
	{
	    Element.show($("pop"));
	},
	
	_hideBubble : function()
	{
	    Element.hide($("pop"));
	},
	
	/**
	Event callback when user is panning map
	*/
	_navMenuZ : null,
	_bubbleContainerZ : null,
	_printContainerZ : null,
	_annotationZ : null,
	_fadeNavOut : null,
	_fadeNavIn : null,
	_cb_onBeginPan : function(t_type)
	{
	    //"hide" navigation menu by lowering z-index.
	    try
	    {	    
	        this._lowerMapControls(t_type);
	            
	        //GLMap, change z-index of navigation to avoid that it get selected.
	        if( t_type == "GLMap" )
	        {     	            
	            //Remove container background-image
	            if( this._hasPath )
	            {
	                this.m_mapController.getControlPane().setStyle(
	                    {
	                        "background-image" : "none"
	                    }
	                );
	            }
	            
	            this._inPanMode = true;
	        }	  
	        
	        wedebug.log("gui", "Navigation menu z-index: " + Element.getStyle(t_bubbleContainer, "z-index"));    
	        
	    }
	    catch(e)
	    {	        
	        wedebug.log("gui", "_cb_onBeginPan exception. " + e.message, "error");
	    }
	},  
	
	_lowerMapControls : function(t_type)
	{
	    var t_navMenu = $("navigationMenu");
        var t_bubbleContainer = $("bubbleContainer");	 
        var t_printContainer = $("printSend");
        var t_annotation = $("annotation");
        t_tmpElement = $('annotationlayer');
        //$('controllerNavigationPane').removeChild($('annotationlayer'));
        $('controllerDrawingPane').replaceChild(t_tmpElement,$('nohotannotationlayer'));
        var t_newdiv = document.createElement('div');
        t_newdiv.id = 'nohotannotationlayertmp';
        $('controllerNavigationPane').appendChild(t_newdiv);
        //$("annotationlayer").style.display = 'none';
	    if( t_type == "GLMap" )
        {      
            var t_tempZ = {"z-index":"1900"};
            if(t_navMenu!=null)
            {
                this._navMenuZ = Element.getStyle(t_navMenu, "z-index");
                Element.setStyle(t_navMenu, t_tempZ);
            }
            if(t_bubbleContainer!=null)
            {
                this._bubbleContainerZ = Element.getStyle(t_bubbleContainer, "z-index");	 
                Element.setStyle(t_bubbleContainer, t_tempZ);
            }
            if(t_printContainer!=null)
            {
                this._printContainerZ =  Element.getStyle(t_printContainer, "z-index");
                Element.setStyle(t_printContainer, t_tempZ);
            }	
            if(t_annotation!=null)
            {
                this._annotationZ =  Element.getStyle(t_annotation, "z-index");
                Element.setStyle(t_annotation, t_tempZ);
            }                
        }
	},
	
	_elevateMapControls : function(t_type)
	{
	    var t_navMenu = $("navigationMenu");
        var t_bubbleContainer = $("bubbleContainer");	 
        var t_printContainer = $("printSend");
        var t_annotation = $("annotation");
        t_tmpElement = $('annotationlayer');
        //$('controllerNavigationPane').removeChild($('annotationlayer'));
        $('controllerNavigationPane').replaceChild(t_tmpElement,$('nohotannotationlayertmp'));
        var t_newdiv = document.createElement('div');
        t_newdiv.id = 'nohotannotationlayer';
        $('controllerDrawingPane').appendChild(t_newdiv);
        var t_tempZ;
        if( t_navMenu != null )
        {          
            t_tempZ = {"z-index":this._navMenuZ};
            Element.setStyle($("navigationMenu"), t_tempZ);
	    }
	       
	    if( t_bubbleContainer != null )
	    {
            t_tempZ = {"z-index":this._bubbleContainerZ};
            Element.setStyle($("bubbleContainer"), t_tempZ);	 
        }
           
        if( t_printContainer != null )
        {
            t_tempZ = {"z-index":this._printContainerZ};
            Element.setStyle($("printSend"), t_tempZ);	                
        } 
        
        if( t_annotation != null )
        {
            t_tempZ = {"z-index":this._annotationZ};
            Element.setStyle($("annotation"), t_tempZ);	                
        }
	},
	
	/**
	Event callback when user ends paning of map
	*/
	_cb_onEndPan : function(t_type)
	{
	    //Reset z-indexes of map controls
	    try
	    {
            this._elevateMapControls(t_type);             
	    }
	    catch(e)
	    {	        
	        wedebug.log("gui", "_cb_onBeginPan exception.", "error");
	    }
	}, 
	
	_doMoveBubble : false,
	/**
	Event callback when user pans map
	*/
	_cb_onPan : function(t_moveX, t_moveY)
	{
	    wedebug.log("gui", "-> _cb_onPan: " + [t_moveX, t_moveY]);
	    
	    if( this._doMoveBubble )
	    {
	        this._moveBubble(t_moveX,t_moveY);
	    }
	    else
	    {
	        this.closeBubble();
	    }
	},
	
	_moveBubble : function(t_moveX, t_moveY)
	{
	    if(this.m_openBubble)
	    {
	        //move bubble.
	        var t_tmp_bubble = $("pop");
	        var t_left = Element.getStyle(t_tmp_bubble, "left").replace(/px/g, "");
	        var t_top = Element.getStyle(t_tmp_bubble, "top").replace(/px/g, "");
	        
	        var t_newLeft = Number(t_left) + t_moveX;
	        var t_newTop = Number(t_top) + t_moveY;
	        
	        Element.setStyle(t_tmp_bubble, {"left":t_newLeft, "top":t_newTop});
	    }
	},
		
	/**
	Callback for onchangeview event in MapController
	*/
	_cb_onChangeView : function(t_centerPoint, t_mapStyle, t_zoomLevel, t_viewport)
	{
	    wedebug.log("gui", "-> _cb_onChangeView: " + [t_centerPoint.lat, t_centerPoint.lon, t_mapStyle, t_zoomLevel, t_viewport]);
	    if( this.m_openBubble )
	    {
	        if( this._doMoveBubble )
	        {
	            var left = (this.m_menuController != null && this.m_menuController.isVisible()) ? this.m_menuController.getMenuWidth() : 0;
	            //alert(this.m_mapController.isInside(this.m_currentBubble.lat, this.m_currentBubble.lon, left));
	            if( this.m_mapController.isInside(this.m_currentBubble.lat, this.m_currentBubble.lon, left) )
	            {
	                this._showBubble();
    	            
	                //reposition bubble
	                var t_pixel = this.m_mapController.getLatLonPixel(
	                    this.m_currentBubble.lat,
	                    this.m_currentBubble.lon
	                );
    	            
	                //move bubble.
                    var t_bubble = $("pop");
                    //var t_newLeft = (t_pixel.x + this.m_currentBubble.offsetX) + "px";
                    //var t_newTop = (t_pixel.y + this.m_currentBubble.offsetY) + "px";
                    var t_newLeft = t_pixel.x  + "px";
                    var t_newTop = t_pixel.y  + "px";
    	            //alert([t_newLeft,t_newTop]);
                    Element.setStyle(t_bubble, {"left":t_newLeft, "top":t_newTop});
	            }
	            else
	            {
	                this._hideBubble();
	            }
	        }
	        else
	        {
	            this.closeBubble();
	        }
	    }
	    
	    this._updateShortestPath(t_viewport);  
	}
}
Object.extend(GUIController.prototype, new AbstractEventTrigger()); //Extend with methods to make object an eventtrigger