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) {
            if (cat.indexOf("restaurant") != -1) {
                cat = "Restaurant";
            }
            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
