function AJAXMAP(map, useWMS, server, /*int*/mapScheme, wmsUrl) {
	this.mapMovedListeners = [];
	this.mapPannedListeners = [];
	this.useWMS = useWMS;
    this.primaryServerHost = server;
    this.MAPCOORDX=262970;
    this.MAPCOORDY=6650580;
    this.TMPMAPCOORDX=this.MAPCOORDX;
    this.TMPMAPCOORDY=this.MAPCOORDY;
    this.BBOXLEFT=this.MAPCOORDX;
    this.BBOXTOP=this.MAPCOORDY;	
    this._gridCoords(this.MAPCOORDX,this.MAPCOORDY);
	this.map = document.getElementById(map);
	this.maximized = false;
	this.mouselayer = null;
	this.tilelayer = null;
	this.tileSize = 256;
	this.width = 0;
	this.height = 0;
	this.top = 0;
	this.left = 0;
	this.x = 0;
	this.y = 0;
	this.noTileX = 0;
	this.noTileY = 0;
	this.border = -1;
	this.mark = { 'x' : 0, 'y' : 0 };
	this.pressed = false;
	this.tiles = [];
	this.cache = {};
    this.mouseCoords = { 'x' : 0, 'y' : 0 };
	this.mouseMapCoords = null;
	this.mouseClickedMapCoords = null;
	this.mouseClickedMapCoordsOld = null;
	this.initialized = false;
	this.wms = this.primaryServerHost + WMS;
	this.zoominy = 0;
	this.zoominx = 0;
	this.zoomIndicatorInSize = 100;
	this.zoomIndicatorOutSize = 100;
    this.dy = 0;
    this.dx = 0;
	// employed to throttle the number of redraws that
	// happen while the mouse is moving
	this.moveCount = 0;
	this.slideMonitor = 0;
	this.slideAcceleration = 0;

	this.zoomInIndicatorMotion = 0;
	this.zoomOutIndicatorMotion = 0;
	this.zoomSliderActive = false;
	this.zoomSliderYPosition = this.height / 8 * zoomLevel;
	this.overlay = null;
	this.overlayX = 0;
	this.noTileLayers = [];
	this.noTileLayers2 = [];
	this.noTileMoves = [];
	this.noTileLayersWMSStrings = [];
	this.loypeWMS = wmsUrl;
	this.WMSLayers = [
            {'name' : 'Lys_status', 'visible' : false},
            {'name' : 'Skoyting_status', 'visible' : false},
            {'name' : 'Tospor_status', 'visible' : false},
            {'name' : 'Normal', 'visible' : false},
            {'name' : 'Tospor', 'visible' : false},
            {'name' : 'Kommuneskogen', 'visible' : false},
            {'name' : 'Markagrense', 'visible' : false},
            {'name' : 'Lys', 'visible' : false},
            {'name' : 'Skoyting', 'visible' : false},
            {'name' : 'Scooter', 'visible' : false},
            {'name' : 'Skiforeningen', 'visible' : false},
            {'name' : 'StilleOmr', 'visible' : false},
            {'name' : 'FriOmrHund', 'visible' : false},
            {'name' : 'TurstiMarka_Natur', 'visible' : true},
            {'name' : 'Skogsbilveier', 'visible' : true},
            {'name' : 'Sykkelruter', 'visible' : true},
            {'name' : 'TurstiMarka', 'visible' : true},
            {'name' : 'TurstierBy', 'visible' : true},
            {'name' : 'TurveierBy', 'visible' : true}
            ];
	this.markers = [];
	this.markersA = [];
	this.distanceMarkers = [];
	this.distanceMarkersA = [];
	this.selectedPointId = null;
	this.pointMove = false;
	this.selectedMarker = null;
	this.markerCount = 0;
	this.distanceMarkerCount = 0;
	this.detailsShown = false;
	this.xmlDoc = null;
	this.defaultZoom = 0;
	
	this.hotspotCount = 0;
	this._hotspots = [];
	this._hotspotDivs = [];

	this.menuBarWidth = 300;
	this.sidebar = 0;
    this.widthPercent = 0;
	this.heightPercent = 0;

	this.navigate = true;
	this.zoomed = false;
	this.menuShown = false;
	this.sidebarShown = false;
	this.coordinateBoxShown = false;
	this.group = null;
	this.line = null;
	this.line2 = null;
	this.line3 = null;
	this.points = [];
	//Holds line objects that should be painted on the map
	this.polyLines = [];
	this.mapScheme = 0; // Default to vector
	if(mapScheme){this.mapScheme = mapScheme;}
	this.pageOffsetY = null;
	this.tooltTipTimer = null;
	this.selectedLayer = "";
	this.selectedLayerWMS = "";
	this.t_drawCanvas = null;
	this.t_currentHost = 1;
	this.t_drawLayer = null;
	this.state = "navigate"; //default state
}

g_zoomLevels = [56,128,256,512,1024,2048,5120,10240,20480,40960,81920,131072,262144,524288];
zoomLevel=6;
//cacheURL= 'http://test.gisline.no/maps/caching/N1000_Raster,N250_Raster,N50_Raster,N5_Raster_4MPP';
WMS='/apache2-default/tilevol/tiles/';
NIB = 'http://www.norgei3d.no/wms.fcgi?request=GetMap&service=WMS&SRS=EPSG:32633&LAYERS=global_mosaic,s5-setesdalsheiane,ortofoto&FORMAT=image/jpeg';
ZOOMLEVEL = g_zoomLevels[zoomLevel];
AJAXMAP.MOUSELAYER_STYLE_CLASS = 'mouselayer';
AJAXMAP.TILELAYER_STYLE_CLASS = 'tilelayer';
AJAXMAP.CONTROLS_STYLE_CLASS = 'controls';
AJAXMAP.TILE_STYLE_CLASS = 'tile';

AJAXMAP.MOVE_THROTTLE = 3;
AJAXMAP.DOM_ONLOAD = (navigator.userAgent.indexOf('KHTML') >= 0 ? false : true);
AJAXMAP.USE_LOADER = false;
AJAXMAP.USE_SLIDE = true;
AJAXMAP.SLIDE_DELAY = 25;
AJAXMAP.SLIDE_ACCELERATION_FACTOR = 2;

AJAXMAP.prototype = {

    /**
    * Resize the map to fit snug inside the browser window (or frame),
    * spacing it from the edges by the specified border.
    *
    * This method should be called prior to init()
    * FIXME: option to hide map to prevent scrollbar interference Only width resize
    */
    fitToWindow: function(border, sidebar, width, height) {
        if (!border || border < 0) {
            border = 0;
        }
        this.sidebar = sidebar;
        this.border = border;

        var t_size = Utilities.Window.getSize();
        var t_calcWidth = t_size.width;
        var t_calcHeight = t_size.height;

        if (sidebar > 0) {
            t_calcWidth = Math.max((t_calcWidth - 2 * border) - sidebar, 0);
        } else {
            t_calcWidth = Math.max((t_calcWidth - 2 * border), 0);
        }

        t_calcHeight = Math.max(t_calcHeight - 2 * border, 0);

        if (t_calcWidth % 2) {
            t_calcWidth--;
        }

        if (t_calcHeight % 2) {
            t_calcHeight--;
        }

        if (width != undefined) {
            t_calcWidth = width;
        }
        if (height != undefined) {
            t_calcHeight = height;
        }
        this.pageOffsetY = getElementTop('mapContainer');

        this.width = t_calcWidth;
        this.height = t_calcHeight - this.pageOffsetY;
        this.height = t_calcHeight;
        this.map.style.width = this.width + 'px';
        this.map.style.height = this.height + 'px';

        if (this.t_drawCanvas != null) {
            this.t_drawCanvas.element.width = t_calcWidth;
            this.t_drawCanvas.element.height = t_calcHeight;
        }

        //document.getElementById('measures').width = t_calcWidth;
        //document.getElementById('measures').height = t_calcHeight;
        //this.map.style.top = border + 'px';
        //this.map.style.left = border + 'px';
        //this.map.style.top = 0 + 'px';
        this.map.style.left = 0 + 'px';
        this.redrawMeasures();
    },

    /**
    * Creates the layers used in the map.
    * FIXME: should be refactored to constructLayers or something similar.
    */
    _maketilelayer: function() {
        var ni = document.getElementById('map'),
            t_newdiv = document.createElement('div'),
            t_divIdName = 'tilelayer';
        t_newdiv.innerHTML = '<!-- -->';
        t_newdiv.setAttribute('id', t_divIdName);
        document.getElementById('map').appendChild(t_newdiv);

        this.tilelayer = t_newdiv;

        var ni = document.getElementById('map');
        var t_newdiv = document.createElement('div');
        var t_divIdName = 'paintlayer';
        t_newdiv.innerHTML = '<!-- -->';
        t_newdiv.setAttribute('id', t_divIdName);
        document.getElementById('map').appendChild(t_newdiv);

        var ni = document.getElementById('map');
        var t_newdiv = document.createElement('div');
        var t_divIdName = 'mouselayer';
        t_newdiv.innerHTML = '<!-- -->';
        t_newdiv.setAttribute('id', t_divIdName);
        document.getElementById('map').appendChild(t_newdiv);
        this.mouselayer = t_newdiv;

        var t_ni = document.getElementById('map');
        var t_newdiv = document.createElement('div');
        var t_divIdName = 'drawlayer';
        t_newdiv.innerHTML = '<!-- -->';
        t_newdiv.setAttribute('id', t_divIdName);
        t_newdiv.style.position = "absolute";
        t_newdiv.style.top = "0px";
        t_newdiv.style.left = "0px";
        t_newdiv.style.width = "100%";
        t_newdiv.style.height = "100%";
        t_newdiv.style.zindex = 1000;
        t_ni.appendChild(t_newdiv);
        this.t_drawLayer = t_newdiv;


        var t_newdiv = document.createElement('canvas');
        t_newdiv.setAttribute('id', 'measures');
        t_newdiv.setAttribute('width', 100);
        t_newdiv.setAttribute('height', 100);
        t_newdiv.style.position = "absolute";
        t_newdiv.style.top = "0px";
        t_newdiv.style.left = "0px";
        t_newdiv.style.width = "100%";
        t_newdiv.style.height = "100%";
        t_newdiv.style.zindex = 1000;
        document.getElementById('paintlayer').appendChild(t_newdiv);
        //this.mouselayer.backingBean = this;

        var ni = document.getElementById('paintlayer');
        var t_newdiv = document.createElement('div');
        var t_divIdName = 'test';
        if (navigator.appName != "Microsoft Internet Explorer") {
            //t_newdiv.innerHTML = '<img src="../../Resource/Map/media/interface/zett/zoomer_circle_pluss.png" style="width: 100%; height: 100%;"/>';
        }
        t_newdiv.setAttribute('id', t_divIdName);
        document.getElementById('paintlayer').appendChild(t_newdiv);

        var ni = document.getElementById('paintlayer');
        var t_newdiv = document.createElement('div');
        var t_divIdName = 'test2';
        if (navigator.appName != "Microsoft Internet Explorer") {
            //t_newdiv.innerHTML = '<img src="../../Resource/Map/media/interface/zett/zoomer_circle_minus.png" style="width: 100%; height: 100%;"/>';
        }
        t_newdiv.setAttribute('id', t_divIdName);
        document.getElementById('paintlayer').appendChild(t_newdiv);

        ni = document.getElementById('map');
        t_newdiv = document.createElement('div');
        t_divIdName = 'bubble';
        t_newdiv.setAttribute('id', t_divIdName);
        ni.appendChild(t_newdiv);

        ni = document.getElementById('bubble');
        t_newdiv = document.createElement('div');
        t_divIdName = 'bubbleheader';
        t_newdiv.setAttribute('id', t_divIdName);
        ni.appendChild(t_newdiv);

        ni = document.getElementById('bubble');
        t_newdiv = document.createElement('div');
        t_divIdName = 'bubblecontent';
        t_newdiv.setAttribute('id', t_divIdName);
        ni.appendChild(t_newdiv);

        ni = document.getElementById('bubble');
        t_newdiv = document.createElement('div');
        t_divIdName = 'bubblefooter';
        t_newdiv.setAttribute('id', t_divIdName);
        ni.appendChild(t_newdiv);

        ni = document.getElementById('bubble');
        t_newdiv = document.createElement('div');
        t_divIdName = 'bubbleButton';
        t_newdiv.setAttribute('id', t_divIdName);
        ni.appendChild(t_newdiv);
        t_newdiv.innerHTML = "<a href=\"javascript: void(0);\" onclick=\"map.hideDetails();\"class=\"slideRight\" title=\"Close Window\"><img src=\"/Resource/Map/media/interface/transparent.gif\" style=\"width: 15px; height: 15px;\"/></a>";

        ni = document.getElementById('paintlayer');
        t_newdiv = document.createElement('div');
        t_divIdName = 'webatlas_logo';
        t_newdiv.setAttribute('id', t_divIdName);
        ni.appendChild(t_newdiv);

        //ni = document.getElementById('paintlayer');
        //t_newdiv = document.createElement('div');
        //t_divIdName = 'dbar';
        //t_newdiv.setAttribute('id',t_divIdName);
        //ni.appendChild(t_newdiv);

        ni = document.getElementById('paintlayer');
        t_newdiv = document.createElement('div');
        t_divIdName = 'copy';
        t_newdiv.setAttribute('id', t_divIdName);
        ni.appendChild(t_newdiv);
    },

    /**
    * Initializes the map with default values.
    */
    init: function(d_northing, d_easting, d_zoomlevel) {
        zoomLevel = d_zoomlevel;
        ZOOMLEVEL = g_zoomLevels[zoomLevel];
        this._gridCoords(d_easting, d_easting);

        this._maketilelayer();
        if (document.attachEvent) {
            document.body.ondragstart = function() { return false; };
        }

        if (this.map.addEventListener) {
            this.map.addEventListener('DOMMouseScroll', wheel, false);
        }
        this.mouselayer.onmousewheel = wheel;

        if (this.width == 0 && this.height == 0) {
            this.width = this.map.offsetWidth;
            this.height = this.map.offsetHeight;
            //window.status = this.map.offsetHeight + " " + this.map.offsetWidth;
        }

        // offset of map in the window
        for (var node = this.map; node; node = node.offsetParent) {
            this.top += node.offsetTop;
            this.left += node.offsetLeft;
        }

        for (var child = this.map.firstChild; child; child = child.nextSibling) {
            if (child.id == AJAXMAP.MOUSELAYER_STYLE_CLASS) {
                this.mouselayer = child;
                child.backingBean = this;
            }
            else if (child.className == AJAXMAP.TILELAYER_STYLE_CLASS) {
                this.tilelayer = child;
                child.backingBean = this;
            }
            else if (child.className == AJAXMAP.CONTROLS_STYLE_CLASS) {
                for (var control = child.firstChild; control; control = control.nextSibling) {
                    if (control.className) {
                        control.onclick = AJAXMAP[control.className + 'Handler'];
                    }
                }
            }

            else if (child.className == "rightArrowClickable") {
                for (var control = child.firstChild; control; control = control.nextSibling) {
                    if (control.className) {
                        control.onclick = AJAXMAP[control.className + 'Handler'];
                    }
                }
            }
            else if (child.className == "leftArrowClickable") {
                for (var control = child.firstChild; control; control = control.nextSibling) {
                    if (control.className) {
                        control.onclick = AJAXMAP[control.className + 'Handler'];
                    }
                }
            }
            else if (child.className == "upArrowClickable") {
                for (var control = child.firstChild; control; control = control.nextSibling) {
                    if (control.className) {
                        control.onclick = AJAXMAP[control.className + 'Handler'];
                    }
                }
            }
            else if (child.className == "downArrowClickable") {
                for (var control = child.firstChild; control; control = control.nextSibling) {
                    if (control.className) {
                        control.onclick = AJAXMAP[control.className + 'Handler'];
                    }
                }
            }
        }
        this.map.backingBean = this;
        //this.mouselayer.style.cursor = AJAXMAP.GRAB_MOUSE_CURSOR;
        this._prepareTiles(false);
        this.activate(false);
        //this._initDojoSurface();
        this.initialized = true;
        this.centerOnCoords({ 'x': d_easting, 'y': d_northing }, false, false);
    },

    redrawMeasures: function() {
        var canvas = document.getElementById("measures");
        if (/msie/i.test(navigator.userAgent)) {
            canvas = G_vmlCanvasManager.initElement(document.getElementById("measures"));
        }
        canvas.width = this.width;
        canvas.height = this.height;
        if (canvas.getContext) {
            var ctx = canvas.getContext("2d");
            ctx.clearRect(0, 0, this.width, this.height);

            ctx.beginPath();
            ctx.strokeStyle = "rgba(189,49,16,1.0)";
            ctx.lineWidth = "2";
            for (var i = 0; i < this.distanceMarkers.length - 1; i++) {
                marker = this.distanceMarkers[i];
                destMarker = this.distanceMarkers[i + 1];

                ctx.moveTo(marker.relX, marker.relY);
                ctx.lineTo(destMarker.relX, destMarker.relY);
            }
            ctx.stroke();
        }

    },

    /**
    * Centers and zooms the map at the given northing/easting/zoomlevel. UTM33 coordinates
    */
    centerAndZoomUTM: function(northing, easting, zoom) {
        var coords = { 'x': Number(easting), 'y': Number(northing) };
        this.zoomToLevel(zoom, false);
        this.defaultZoom = zoom;
        this.centerOnCoords({ 'x': coords.x, 'y': coords.y }, false);

    },

    /**
    * Centers and zooms the map at the given lat/lon/zoomlevel. WGS84 coordinates
    */
    centerAndZoom: function(lat, lon, zoom) {
        var coords = decimalDegreesToUTM({ 'x': Number(lon), 'y': Number(lat) });
        this.zoomToLevel(zoom, false);
        this.defaultZoom = zoom;
        this.centerOnCoords({ 'x': coords.x, 'y': coords.y }, false);
    },

    centerAndZoomOnBoundingBoxUTM: function(x1, y1, x2, y2, zoffset) {
        var metersX = x2 - x1,
	        metersY = y2 - y1,
	        halfWidth = this.width / 2,
	        halfHeight = this.height / 2,
	        zoomPoint = { 'x': x1 + (metersX / 2), 'y': y1 + (metersY / 2) };
        for (var i = 0; i < g_zoomLevels.length; i++) {
            var tmpLevel = g_zoomLevels[i];
            var t_coordsperpixel = tmpLevel / 256;
            var tmpBoundX = zoomPoint.x + (halfWidth * t_coordsperpixel);
            var tmpBoundY = zoomPoint.y + (halfHeight * t_coordsperpixel);
            //FIXME:
            if (tmpBoundX > x2 && tmpBoundY > y2) {
                this.centerAndZoomUTM(zoomPoint.y, zoomPoint.x, i + zoffset);
                return;
            }
        }
        this.centerAndZoomUTM(zoomPoint.y, zoomPoint.x, i + zoffset);
    },

    simulateCenterAndZoomOnBoundingBox: function(minLon, minLat, maxLon, maxLat) {
        var min = decimalDegreesToUTM({ y: minLat, x: minLon }),
	        max = decimalDegreesToUTM({ y: maxLat, x: maxLon }),
	        y1 = min.y,
	        x1 = min.x,
	        y2 = max.y,
	        x2 = max.x,
	        outLevel = -1, outX, outY,
	        metersX = x2 - x1,
	        metersY = y2 - y1,
	        halfWidth = this.width / 2,
	        halfHeight = this.height / 2,
	        zoomPoint = { 'x': x1 + (metersX / 2), 'y': y1 + (metersY / 2) };
        for (var i = 0; i < g_zoomLevels.length; i++) {
            var tmpLevel = g_zoomLevels[i];
            var t_coordsperpixel = tmpLevel / 256;
            var tmpBoundX = zoomPoint.x + (halfWidth * t_coordsperpixel);
            var tmpBoundY = zoomPoint.y + (halfHeight * t_coordsperpixel);

            if (tmpBoundX > x2 && tmpBoundY > y2) {
                //this.centerAndZoomUTM(zoomPoint.y,zoomPoint.x,i);
                outLevel = i;
                outX = zoomPoint.x;
                outY = zoomPoint.y;
                break;
            }
        }

        if (outLevel == -1) {
            //this.centerAndZoomUTM(zoomPoint.y,zoomPoint.x,i);
            outLevel = i;
            outX = zoomPoint.x;
            outY = zoomPoint.y;
        }

        var ll = UTMToLatLon(y, x, 33);
        return { level: outLevel, lon: ll.lon, lat: ll.lat };
    },

    simulateCenterAndZoomOnBoundingBoxUTM: function(x1, y1, x2, y2) {
        var outLevel = -1, outX, outY,
	        metersX = x2 - x1,
	        metersY = y2 - y1,
	        halfWidth = this.width / 2,
	        halfHeight = this.height / 2,
	        zoomPoint = { 'x': x1 + (metersX / 2), 'y': y1 + (metersY / 2) };
        for (var i = 0; i < g_zoomLevels.length; i++) {
            var tmpLevel = g_zoomLevels[i];
            var t_coordsperpixel = tmpLevel / 256;
            var tmpBoundX = zoomPoint.x + (halfWidth * t_coordsperpixel);
            var tmpBoundY = zoomPoint.y + (halfHeight * t_coordsperpixel);

            if (tmpBoundX > x2 && tmpBoundY > y2) {
                //this.centerAndZoomUTM(zoomPoint.y,zoomPoint.x,i);
                outLevel = i;
                outX = zoomPoint.x;
                outY = zoomPoint.y;
                break;
            }
        }

        if (outLevel == -1) {
            //this.centerAndZoomUTM(zoomPoint.y,zoomPoint.x,i);
            outLevel = i;
            outX = zoomPoint.x;
            outY = zoomPoint.y;
        }

        return { level: outLevel, x: outX, y: outY };
    },

    /**
    * Fits all current markers in the viewport. Centers and zooms to a level were all markers are 
    * visible.
    */
    centerAndZoomOnCurrentMarkers: function() {

    },
    /**
    * Calculates how many tiles are needed to tile up the map, and constructs the tiles needed.
    */
    _prepareTiles: function(t_setSource) {
        var rows = Math.ceil(this.height / this.tileSize) + 1;
        var cols = Math.ceil(this.width / this.tileSize) + 1;
        for (var c = 0; c < cols; c++) {
            var tileCol = [];

            for (var r = 0; r < rows; r++) {
                this.t_currentHost = this.t_currentHost == 4 ? this.t_currentHost = 1 : this.t_currentHost + 1;
                var tile = {
                    'element': null,
                    'posx': 256 * c,
                    'posy': 256 * r,
                    'xIndex': c,
                    'yIndex': r,
                    'host': this.t_currentHost
                };

                tileCol.push(tile);
            }

            this.tiles.push(tileCol);
        }

        this.mouselayer.onmousedown = AJAXMAP.mousePressedHandler;
        this.mouselayer.onmouseup = AJAXMAP.mouseUpHandler;
        this.mouselayer.onmouseout = AJAXMAP.mouseReleasedHandler;
        this.mouselayer.ondblclick = AJAXMAP.doubleClickHandler;

        this._positionTiles({ "x": 0, "y": 0 }, false, t_setSource);

    },

    /**
    * Position the tiles based on the x, y coordinates of the
    * map, taking into account the motion offsets, which
    * are calculated by a motion event handler.
    */
    _positionTiles: function(t_motion, reset, t_setSource) {
        // default to no t_motion, just setup tiles
        if (!t_motion) {
            t_motion = { 'x': 0, 'y': 0 };
        }

        var i, t_length = this.noTileLayers.length;
        for (i = 0; i < t_length; i++) {
            //if (this.noTileMoves[i]) {
            var t_overlay = this.noTileLayers[i];
            t_overlay.style.left = this.noTileX + t_motion.x + 'px';
            t_overlay.style.top = this.noTileY + t_motion.y + 'px';
            //}
        }

        var i, t_length = this.noTileLayers2.length;
        for (i = 0; i < t_length; i++) {
            //if (this.noTileMoves[i]) {
            var t_overlay = this.noTileLayers2[i];
            t_overlay.style.left = this.noTileX + t_motion.x + 'px';
            t_overlay.style.top = this.noTileY + t_motion.y + 'px';
            //}
        }

        t_length = this.markers.length;
        for (i = 0; i < t_length; i++) {
            var t_marker = this.markers[i];
            t_marker.element.style.left = t_marker.x + this.x + t_motion.x + 'px';
            t_marker.element.style.top = t_marker.y + this.y + t_motion.y + 'px';
            t_marker.relX = t_marker.x + this.x + t_motion.x;
            t_marker.relY = t_marker.y + this.y + t_motion.y;
        }

        //Move hotspots
        t_length = this._hotspots.length;
        for (i = 0; i < t_length; i++) {
            var spot = this._hotspots[i];
            this._hotspotDivs[i].style.left = this._hotspots[i].x + this.x + t_motion.x + spot.xOffset + 'px';
            this._hotspotDivs[i].style.top = this._hotspots[i].y + this.y + t_motion.y + spot.yOffset + 'px';
            this._hotspots[i].relX = this._hotspots[i].x + this.x + t_motion.x;
            this._hotspots[i].relY = this._hotspots[i].y + this.y + t_motion.y;
        }

        t_length = this.distanceMarkers.length;
        for (i = 0; i < t_length; i++) {
            var t_marker = this.distanceMarkers[i];
            t_marker.element.style.left = t_marker.x - 4 + this.x + t_motion.x + 'px';
            t_marker.element.style.top = t_marker.y - 4 + this.y + t_motion.y + 'px';
            t_marker.relX = t_marker.x + this.x + t_motion.x;
            t_marker.relY = t_marker.y + this.y + t_motion.y;
        }
        //this._drawToolLine();

        if (this.detailsShown) {
            var ni = document.getElementById('bubble');
            ni.style.top = this.selectedMarker.relY - 250 + 'px';
            ni.style.left = this.selectedMarker.relX - 150 + 'px';
        }

        for (var c = 0; c < this.tiles.length; c++) {
            for (var r = 0; r < this.tiles[c].length; r++) {
                var tile = this.tiles[c][r];
                tile.posx = (tile.xIndex * this.tileSize) + this.x + t_motion.x;
                tile.posy = (tile.yIndex * this.tileSize) + this.y + t_motion.y;

                var visible = true;

                if (tile.posx > this.width) {
                    // tile moved out of view to the right
                    // consider the tile coming into view from the left
                    do {
                        tile.xIndex -= this.tiles.length;
                        tile.posx = (tile.xIndex * this.tileSize) + this.x + t_motion.x;
                    } while (tile.posx > this.width);

                    if (tile.posx + this.tileSize < 0) {
                        visible = false;
                    }

                } else {
                    // tile may have moved out of view from the left
                    // if so, consider the tile coming into view from the right
                    while (tile.posx < -this.tileSize) {
                        tile.xIndex += this.tiles.length;
                        tile.posx = (tile.xIndex * this.tileSize) + this.x + t_motion.x;
                    }

                    if (tile.posx > this.width) {
                        visible = false;
                    }
                }

                if (tile.posy > this.height) {
                    // tile moved out of view to the bottom
                    // consider the tile coming into view from the top
                    do {
                        tile.yIndex -= this.tiles[c].length;
                        tile.posy = (tile.yIndex * this.tileSize) + this.y + t_motion.y;
                    } while (tile.posy > this.height);

                    if (tile.posy + this.tileSize < 0) {
                        visible = false;
                    }

                } else {
                    // tile may have moved out of view to the top
                    // if so, consider the tile coming into view from the bottom
                    while (tile.posy < -this.tileSize) {
                        tile.yIndex += this.tiles[c].length;
                        tile.posy = (tile.yIndex * this.tileSize) + this.y + t_motion.y;
                    }

                    if (tile.posy > this.height) {
                        visible = false;
                    }
                }

                // initialize the image object for this quadrant
                if (!this.initialized) {
                    this._assignTileImage(tile, true, false, t_setSource);
                    tile.element.style.top = tile.posy + 'px';
                    tile.element.style.left = tile.posx + 'px';
                }

                //FIXME: Not a good solution
                if (this.zoomed) {
                    this._assignTileImage(tile, true, false, t_setSource);
                    tile.element.style.top = tile.posy + 'px';
                    tile.element.style.left = tile.posx + 'px';
                }
                // display the image if visible
                if (visible) {
                    this._assignTileImage(tile, false, false, t_setSource);
                }

                // seems to need this no matter what
                tile.element.style.top = tile.posy + 'px';
                tile.element.style.left = tile.posx + 'px';

                //window.status = tile.xIndex + ', ' + tile.xTile;
            }
        }

        // reset the x, y coordinates of the map according to motion
        if (reset) {
            this.x += t_motion.x;
            this.y += t_motion.y;
            this.noTileX += t_motion.x;
            this.noTileY += t_motion.y;
            var t_coordsperpixel = g_zoomLevels[zoomLevel] / 256;
            this.BBOXLEFT -= t_motion.x * t_coordsperpixel;
            this.BBOXTOP += t_motion.y * t_coordsperpixel;
            //window.status = this.BBOXLEFT + ', ' + this.BBOXTOP;
        }
    },
    getWidth: function() {
        return this.width;
    },

    getHeight: function() {
        return this.height;
    },

    addDrawCanvas: function(canvasIn) {
        this.t_drawCanvas = canvasIn;
        this.t_drawCanvas.parent = this;
        var t_divIdName = this.t_container + 'canvas';
        this.t_drawCanvas.element.setAttribute('id', t_divIdName);
        this.t_drawLayer.appendChild(this.t_drawCanvas.element);

        var t_calcWidth = 0;
        var t_calcHeight = 0;

        // Get the window width and height
        if (window.innerWidth) {
            t_calcWidth = window.innerWidth;
            t_calcHeight = window.innerHeight;
        } else {
            t_calcWidth = document.compatMode == 'CSS1Compat'
                ? document.documentElement.clientWidth
                : document.body.clientWidth;
            t_calcHeight = document.compatMode == 'CSS1Compat'
                ? document.documentElement.clientHeight
                : document.body.clientHeight;
        }

        this.t_drawCanvas.element.width = t_calcWidth;
        this.t_drawCanvas.element.height = t_calcHeight;

        if (/msie/i.test(navigator.userAgent)) {
            hack = G_vmlCanvasManager.initElement(map.getDrawCanvas().element);
            map.getDrawCanvas().element = hack;
        }

        canvas = this.t_drawCanvas.element;
        this.t_drawCanvas.surface = canvas.getContext("2d");
    },

    getDrawCanvas: function() {
        return this.t_drawCanvas;
    },

    /**
    * Determine the source image of the specified tile based
    * on the zoom level and position of the tile.  If forceBlankImage
    * is specified, the source should be automatically set to the
    * null tile image.  This method will also setup an onload
    * routine, delaying the appearance of the tile until it is fully
    * loaded, if configured to do so.
    */
    _assignTileImage: function(tile, forceBlankImage, roads, t_setSource) {
        var tileImgId, src;
        var useBlankImage = (forceBlankImage ? true : false);

        var mapx = this.MAPCOORDX + (ZOOMLEVEL * tile.xIndex);
        var mapy = this.MAPCOORDY - (ZOOMLEVEL * tile.yIndex) - ZOOMLEVEL;
        //var topx = mapx+ZOOMLEVEL;
        //var topy = mapy+ZOOMLEVEL;

        tileImgId = src = 'http://ts' + tile.host + '.webatlas.no/'
        + '?x1=' + mapx + '&y1=' + mapy + '&z=' + g_zoomLevels[zoomLevel] + '&s=' + this.mapScheme + '&l=1';

        // only remove tile if identity is changing
        if (tile.element != null && tile.element.parentNode != null && tile.element.relativeSrc != src) {
            this.tilelayer.removeChild(tile.element);
        }

        var tileImg = this.cache[tileImgId];
        // create cache if not exist
        if (!tileImg) {
            tileImg = this.cache[tileImgId] = this._createPrototype(src, t_setSource);
        }

        if (useBlankImage || !AJAXMAP.USE_LOADER || tileImg.complete || (tileImg.image && tileImg.image.complete)) {
            tileImg.onload = null;

            if (tileImg.image) {
                tileImg.image.onload = null;
            }

            if (!tileImg.parentNode) {
                tile.element = this.tilelayer.appendChild(tileImg);
            }
        } else {
            var loadingImg = this.cache[loadingImgId];
            if (!loadingImg) {
                loadingImg = this.cache[loadingImgId] = this._createPrototype(null, t_setSource);
            }

            loadingImg.targetSrc = tileImgId;

            var tilelayer = this.tilelayer;
            tile.element = tilelayer.appendChild(loadingImg);
        }
    },

    _createPrototype: function(src, t_setSource) {
        //var now = new Date();
        var img = document.createElement('img');
        //img.src = src + '&t=' + now.getTime();

        if (typeof t_setSource == "undefined" || t_setSource == true) {
            img.src = src;
            img.relativeSrc = src;
        }
        img.alt = "Loading Tile...";
        img.className = AJAXMAP.TILE_STYLE_CLASS;
        img.style.width = this.tileSize + 'px';
        img.style.height = this.tileSize + 'px';
        return img;
    },

    /**
    * Creates a custom layer, which is fetched directly from a WMS server
    */
    _createCustomLayer: function() {
        var tilelayer = this.tilelayer;
        for (var i = 0; i < this.noTileLayers.length; i++) {
            tilelayer.removeChild(this.noTileLayers[i]);
        }
        this.noTileLayers = [];
        for (var i = 0; i < this.noTileLayersWMSStrings.length; i++) {
            var layer = this.noTileLayers[i];
            this.noTileX = 0;
            this.noTileY = 0;
            var img = document.createElement('img');
            var t_coordsperpixel = g_zoomLevels[zoomLevel] / 256;
            var mapMinX = this.BBOXLEFT;
            var mapMaxX = this.BBOXLEFT + t_coordsperpixel * this.width;
            var mapMinY = this.BBOXTOP - t_coordsperpixel * this.height;
            var mapMaxY = this.BBOXTOP;

            //var WMS='http://clusterb.gisline.no/wms-loyper/?request=GetMap&service=WMS&SRS=EPSG:32633&Layers=' + this.noTileLayersWMSStrings[i]+ '&FORMAT=image/png';
            var WMS = this.loypeWMS + '?request=GetMap&service=WMS&SRS=EPSG:32633&Layers=' + this.noTileLayersWMSStrings[i]+ '&FORMAT=image/png';
            
            //var WMS = this.noTileLayersWMSStrings[i];
            var roadsURL = WMS + '&BBOX='+mapMinX+','+mapMinY+','+mapMaxX+','+mapMaxY+'&width='+this.width+'&height='+this.height;
            img.src = roadsURL;
            img.alt = "Loading custom layer...";
            img.relativeSrc = roadsURL;
            img.className = 'overlay';

            img.style.top = 0 + 'px';
            img.style.left = 0 + 'px';

            tilelayer.appendChild(img);
            this.noTileLayers.push(img);
        }
    },

    getBoundingBox: function() {
        var t_coordsperpixel = g_zoomLevels[zoomLevel] / 256;

        var mapMinX = this.BBOXLEFT;
        var mapMaxX = this.BBOXLEFT + t_coordsperpixel * this.width;
        var mapMinY = this.BBOXTOP - t_coordsperpixel * this.height;
        var mapMaxY = this.BBOXTOP;

        return { 'minX': mapMinX, 'minY': mapMinY, 'maxX': mapMaxX, 'maxY': mapMaxY };
    },

    _setSelectedLayer: function(id, layer) {
        this.selectedLayer = id;
        this.selectedLayerWMS = layer;
        this._createWMSLayer();
    },

    _createWMSLayer: function() {
        var refreshNeeded = false;
        for (var j = 0; j < this.WMSLayers.length; j++) {
            if (this.WMSLayers[j].visible == true) {
                refreshNeeded = true;
                break;
            }
        }

        var tilelayer = this.tilelayer;
        for (var i = 0; i < this.noTileLayers.length; i++) {
            tilelayer.removeChild(this.noTileLayers[i]);
        }
        this.noTileLayers = [];
        if (refreshNeeded) {
            //var layer = this.noTileLayers[i];
            this.noTileX = 0;
            this.noTileY = 0;
            var img = document.createElement('img');
            var t_coordsperpixel = g_zoomLevels[zoomLevel] / 256;
            var mapMinX = this.BBOXLEFT;
            var mapMaxX = this.BBOXLEFT + t_coordsperpixel * this.width;
            var mapMinY = this.BBOXTOP - t_coordsperpixel * this.height;
            var mapMaxY = this.BBOXTOP;

            //var WMS='http://clusterb.gisline.no/wms-loyper/?request=GetMap&service=WMS&SRS=EPSG:32633&Layers=';
            var WMS=this.loypeWMS + '?request=GetMap&service=WMS&SRS=EPSG:32633&Layers=';

            for (var j = 0; j < this.WMSLayers.length; j++) {
                if (this.WMSLayers[j].visible == true) {
                    WMS += this.WMSLayers[j].name + ',';
                }


            }
            WMS += '&FORMAT=image/png';
            //var WMS = this.noTileLayersWMSStrings[i];
            var roadsURL = WMS + '&BBOX=' + mapMinX + ',' + mapMinY + ',' + mapMaxX + ',' + mapMaxY + '&width=' + this.width + '&height=' + this.height;
            img.src = roadsURL;
            img.alt = "Loading custom layer...";
            img.relativeSrc = roadsURL;
            img.className = 'overlay';

            img.style.top = 0 + 'px';
            img.style.left = 0 + 'px';

            tilelayer.appendChild(img);
            this.noTileLayers.push(img);
        }
        if (this.selectedLayer != "") {
//            if (g_season != 'sommer') {
                this.noTileX = 0;
                this.noTileY = 0;
                var img = document.createElement('img');
                var t_coordsperpixel = g_zoomLevels[zoomLevel] / 256;
                var mapMinX = this.BBOXLEFT;
                var mapMaxX = this.BBOXLEFT + t_coordsperpixel * this.width;
                var mapMinY = this.BBOXTOP - t_coordsperpixel * this.height;
                var mapMaxY = this.BBOXTOP;

//                var WMS = 'http://clusterb.gisline.no/wms-loyper?SERVICE=WMS&VERSION=1.1.0&REQUEST=GetFeatureMap&FORMAT=image/png&SRS=EPSG:32633&ID='
//            + this.selectedLayer + '&LAYERS=' + this.selectedLayerWMS; //Tospor,Lys,Skoyting,Skiforeningen,Scooter,TurstiMarka_Natur,Skogsbilveier,Sykkelruter,TurstiMarka,TurstierBy,TurveierBy';

            var WMS=this.loypeWMS + '?SERVICE=WMS&VERSION=1.1.0&REQUEST=GetFeatureMap&FORMAT=image/png&SRS=EPSG:32633&ID='
            +this.selectedLayer+'&LAYERS=' +this.selectedLayerWMS;//Tospor,Lys,Skoyting,Skiforeningen,Scooter,TurstiMarka_Natur,Skogsbilveier,Sykkelruter,TurstiMarka,TurstierBy,TurveierBy';
            
            //WMS += '&FORMAT=image/png';
            //var WMS = this.noTileLayersWMSStrings[i];
            var roadsURL =  WMS + '&BBOX='+mapMinX+','+mapMinY+','+mapMaxX+','+mapMaxY+'&width='+this.width+'&height='+this.height;
            img.src = roadsURL;
            img.alt = "Loading custom layer...";
            img.relativeSrc = roadsURL;
            img.className = 'overlay';

                img.style.top = 0 + 'px';
                img.style.left = 0 + 'px';

                tilelayer.appendChild(img);
                this.noTileLayers.push(img);
//            }
        }
    },

    getLoypeLayers: function() {
        var layers = '';
        for (var j = 0; j < this.WMSLayers.length; j++) {
            if (this.WMSLayers[j].visible == true) {
                layers += this.WMSLayers[j].name + ',';
            }
        }

        return layers;
    },

    addmapMovedListener: function(listener) {
        this.mapMovedListeners.push(listener);
    },


    /**
    * Notify listeners of a move event on the map.
    */
    notifymapMoved: function(coords) {
        if (!coords) {
            coords = { 'x': 0, 'y': 0 };
        }

        for (var i = 0; i < this.mapMovedListeners.length; i++) {
            this.mapMovedListeners[i].mapMoved(
				new AJAXMAP.MoveEvent(
					this.x + (coords.x - this.mark.x),
					this.y + (coords.y - this.mark.y)
				)
			);
        }
    },

    addmapPannedListener: function(listener) {
        this.mapPannedListeners.push(listener);
    },
    /**
    * Notify listeners of a move event on the map.
    */
    notifymapPanned: function(coords) {
        if (!coords) {
            coords = { 'x': 0, 'y': 0 };
        }

        for (var i = 0; i < this.mapPannedListeners.length; i++) {
            this.mapPannedListeners[i].mapPanned(
				new AJAXMAP.MoveEvent(
					this.x + (coords.x - this.mark.x),
					this.y + (coords.y - this.mark.y)
				)
			);
        }
    },

    setScaleIndicator: function() {
        //$('dbar').style.backgroundImage = "url(Resource/Map/images/gfx2/mapview/zoom_"+g_zoomLevels[zoomLevel]+".gif)";
    },

    zoomIn: function(pointer) {
        if (this.navigate) {
            this.centerOnCoords({ 'x': this.mouseMapCoords.x, 'y': this.mouseMapCoords.y }, false);
            this.zoomPlus();
            /*if(this.navigate){
            if(zoomLevel > 0){
            this.zoomed = true;
            this._sizeZoomIndicatorIn();
            this.dx = 0;
            this.dy = 0;

			//Zoom on center
            //this.TMPMAPCOORDX = this.BBOXLEFT + (g_zoomLevels[zoomLevel]/256)*this.width/2;
            //this.TMPMAPCOORDY = this.BBOXTOP -(g_zoomLevels[zoomLevel]/256)*this.height/2;
            //Zoom on mousecoords
            this.TMPMAPCOORDX = this.mouseMapCoords.x;
            this.TMPMAPCOORDY = this.mouseMapCoords.y;
            var xCoord = this.TMPMAPCOORDX;
            var yCoord = this.TMPMAPCOORDY;

			this.x = 0;
            this.y = 0;

			zoomLevel--;
            this.blank();
            this.tiles = [];
            this.tiles2 = [];
            this.cache = {};
            ZOOMLEVEL = g_zoomLevels[zoomLevel];

            t_coordsperpixel = g_zoomLevels[zoomLevel]/256;

			this.TMPMAPCOORDX = this.BBOXLEFT + (g_zoomLevels[zoomLevel]/256)*this.width/2;
            this.TMPMAPCOORDY = this.BBOXTOP -(g_zoomLevels[zoomLevel]/256)*this.height/2;

			this.MAPCOORDX = this.TMPMAPCOORDX;
            this.MAPCOORDY = this.TMPMAPCOORDY;
            this.BBOXLEFT = this.MAPCOORDX;
            this.BBOXTOP = this.MAPCOORDY;
            this._gridCoords(this.MAPCOORDX,this.MAPCOORDY);
            this.placeMarkers();
            this.centerOnCoords({ 'x' : (xCoord), 'y' : (yCoord) },true);

			//this._recenter({ 'x' : (this.mouseCoords.x), 'y' : (this.mouseCoords.y) },true);
            this._prepareTiles(true);
            this.zoomed = false;  
            this._createCustomLayer();

		  }
      this.refresh();
      
      this.moveSlider();
            }*/
            this.setScaleIndicator();
        }
    },

    zoomOut: function(pointer) {
        if (this.navigate) {
            if (zoomLevel < g_zoomLevels.length - 1) {
                this.zoomed = true;
                this._sizeZoomIndicatorOut();
                this.dx = 0;
                this.dy = 0;
                //this._recenter(this.mouseCoords,false);
                var t_coordsperpixel = g_zoomLevels[zoomLevel] / 256;


                //this.TMPMAPCOORDX = this.BBOXLEFT + (g_zoomLevels[zoomLevel]/256)*this.width/2;
                //gthis.TMPMAPCOORDY = this.BBOXTOP -(g_zoomLevels[zoomLevel]/256)*this.height/2;
                //Zoom on mousecoords
                this.TMPMAPCOORDX = this.mouseMapCoords.x;
                this.TMPMAPCOORDY = this.mouseMapCoords.y;

                var xCoord = this.TMPMAPCOORDX;
                var yCoord = this.TMPMAPCOORDY;

                this.x = 0;
                this.y = 0;
                zoomLevel++;
                this.blank();
                this.tiles = [];
                this.tiles2 = [];
                this.cache = {};
                ZOOMLEVEL = g_zoomLevels[zoomLevel];

                this.MAPCOORDX = this.TMPMAPCOORDX;
                this.MAPCOORDY = this.TMPMAPCOORDY;

                this.TMPMAPCOORDX = this.mouseMapCoords.x - ((this.width / 2) * t_coordsperpixel);
                this.TMPMAPCOORDY = this.mouseMapCoords.y + ((this.height / 2) * t_coordsperpixel);
                this.TMPMAPCOORDX = this.BBOXLEFT + (g_zoomLevels[zoomLevel] / 256) * this.width / 2;
                this.TMPMAPCOORDY = this.BBOXTOP - (g_zoomLevels[zoomLevel] / 256) * this.height / 2;

                this.MAPCOORDX = this.TMPMAPCOORDX;
                this.MAPCOORDY = this.TMPMAPCOORDY;
                this.BBOXLEFT = this.MAPCOORDX;
                this.BBOXTOP = this.MAPCOORDY;
                this._gridCoords(this.MAPCOORDX, this.MAPCOORDY);
                this.placeMarkers();
                this.centerOnCoords({ 'x': (xCoord), 'y': (yCoord) }, true);
                this._prepareTiles();
                //this.center({ 'x' : (this.dx), 'y' : (this.dy) },true);
                this.zoomed = false;
                //this.notifymapZoomed();
                this._createCustomLayer();
                this._createWMSLayer();
            }
            this.refresh();
            this.moveSlider();
        }
        this.setScaleIndicator();
    },

    zoomToLevel: function(toLevel, useIndicator) {
        this.zoomed = true;
        this.dx = 0;
        this.dy = 0;

        //Zoom on center
        this.TMPMAPCOORDX = this.BBOXLEFT + (g_zoomLevels[zoomLevel] / 256) * this.width / 2;
        this.TMPMAPCOORDY = this.BBOXTOP - (g_zoomLevels[zoomLevel] / 256) * this.height / 2;
        //Zoom on mousecoords
        //this.TMPMAPCOORDX = this.mouseMapCoords.x;
        //this.TMPMAPCOORDY = this.mouseMapCoords.y;
        var xCoord = this.TMPMAPCOORDX;
        var yCoord = this.TMPMAPCOORDY;

        this.x = 0;
        this.y = 0;

        zoomLevel = toLevel;
        this.blank();
        this.tiles = [];
        this.tiles2 = [];
        this.cache = {};
        ZOOMLEVEL = g_zoomLevels[zoomLevel];

        t_coordsperpixel = g_zoomLevels[zoomLevel] / 256;

        this.MAPCOORDX = this.TMPMAPCOORDX;
        this.MAPCOORDY = this.TMPMAPCOORDY;
        this.BBOXLEFT = this.MAPCOORDX;
        this.BBOXTOP = this.MAPCOORDY;
        this._gridCoords(this.MAPCOORDX, this.MAPCOORDY);
        this.placeMarkers();
        this.centerOnCoords({ 'x': (xCoord), 'y': (yCoord) }, false);
        this._prepareTiles();
        this.zoomed = false;

        this._createCustomLayer();
        this._createWMSLayer();
        this.refresh();
        this.moveSlider();
        this.setScaleIndicator();
    },

    zoomPlus: function() {
        if (this.navigate && zoomLevel != 0) {
            this.zoomed = true;
            this.dx = 0;
            this.dy = 0;

            //Zoom on center
            this.TMPMAPCOORDX = this.BBOXLEFT + (g_zoomLevels[zoomLevel] / 256) * this.width / 2;
            this.TMPMAPCOORDY = this.BBOXTOP - (g_zoomLevels[zoomLevel] / 256) * this.height / 2;
            //Zoom on mousecoords
            //this.TMPMAPCOORDX = this.mouseMapCoords.x;
            //this.TMPMAPCOORDY = this.mouseMapCoords.y;
            var xCoord = this.TMPMAPCOORDX;
            var yCoord = this.TMPMAPCOORDY;

            this.x = 0;
            this.y = 0;

            zoomLevel = zoomLevel - 1;
            this.blank();
            this.tiles = [];
            this.tiles2 = [];
            this.cache = {};
            ZOOMLEVEL = g_zoomLevels[zoomLevel];

            t_coordsperpixel = g_zoomLevels[zoomLevel] / 256;
            //this.TMPMAPCOORDX = {.x- ((this.width/2) * t_coordsperpixel);
            //this.TMPMAPCOORDY = this.mouseMapCoords.y+ ((this.height/2) * t_coordsperpixel);

            //this.TMPMAPCOORDX = this.BBOXLEFT + (g_zoomLevels[zoomLevel]/256)*this.width/2;
            //this.TMPMAPCOORDY = this.BBOXTOP  - (g_zoomLevels[zoomLevel]/256)*this.height/2;

            this.MAPCOORDX = this.TMPMAPCOORDX;
            this.MAPCOORDY = this.TMPMAPCOORDY;
            this.BBOXLEFT = this.MAPCOORDX;
            this.BBOXTOP = this.MAPCOORDY;
            this._gridCoords(this.MAPCOORDX, this.MAPCOORDY);
            this.placeMarkers();
            this.centerOnCoords({ 'x': (xCoord), 'y': (yCoord) }, false);
            this._prepareTiles();
            this.zoomed = false;
            //this.center({ 'x' : (this.dx), 'y' : (this.dy) },true);

            this._createCustomLayer();
            this._createWMSLayer();

            //this.notifymapZoomed();

            this.refresh();
            this.moveSlider();
        }
        this.setScaleIndicator();
    },

    zoomMinus: function() {
        if (this.navigate && zoomLevel != g_zoomLevels.length - 1) {
            this.zoomed = true;
            this.dx = 0;
            this.dy = 0;

            //Zoom on center
            this.TMPMAPCOORDX = this.BBOXLEFT + (g_zoomLevels[zoomLevel] / 256) * this.width / 2;
            this.TMPMAPCOORDY = this.BBOXTOP - (g_zoomLevels[zoomLevel] / 256) * this.height / 2;
            //Zoom on mousecoords
            //this.TMPMAPCOORDX = this.mouseMapCoords.x;
            //this.TMPMAPCOORDY = this.mouseMapCoords.y;
            var xCoord = this.TMPMAPCOORDX;
            var yCoord = this.TMPMAPCOORDY;

            this.x = 0;
            this.y = 0;

            zoomLevel = zoomLevel + 1;
            this.blank();
            this.tiles = [];
            this.tiles2 = [];
            this.cache = {};
            ZOOMLEVEL = g_zoomLevels[zoomLevel];

            t_coordsperpixel = g_zoomLevels[zoomLevel] / 256;
            //this.TMPMAPCOORDX = this.mouseMapCoords.x- ((this.width/2) * t_coordsperpixel);
            //this.TMPMAPCOORDY = this.mouseMapCoords.y+ ((this.height/2) * t_coordsperpixel);

            //this.TMPMAPCOORDX = this.BBOXLEFT + (g_zoomLevels[zoomLevel]/256)*this.width/2;
            //this.TMPMAPCOORDY = this.BBOXTOP  - (g_zoomLevels[zoomLevel]/256)*this.height/2;

            this.MAPCOORDX = this.TMPMAPCOORDX;
            this.MAPCOORDY = this.TMPMAPCOORDY;
            this.BBOXLEFT = this.MAPCOORDX;
            this.BBOXTOP = this.MAPCOORDY;
            this._gridCoords(this.MAPCOORDX, this.MAPCOORDY);
            this.placeMarkers();
            this.centerOnCoords({ 'x': (xCoord), 'y': (yCoord) }, false);
            this._prepareTiles();
            this.zoomed = false;
            //this.center({ 'x' : (this.dx), 'y' : (this.dy) },true);

            this._createCustomLayer();
            this._createWMSLayer();

            //this.notifymapZoomed();

            this.refresh();
            this.moveSlider();
        }
    },

    _gridCoords: function(xCoord, yCoord) {
        var timesX = parseInt(xCoord / g_zoomLevels[zoomLevel]);
        var timesY = parseInt(yCoord / g_zoomLevels[zoomLevel]);

        this.MAPCOORDX = g_zoomLevels[zoomLevel] * timesX;
        this.MAPCOORDY = g_zoomLevels[zoomLevel] * timesY;

        var t_coordsperpixel = 256 / g_zoomLevels[zoomLevel];
        //this.dx = Math.floor((xCoord - this.MAPCOORDX)*t_coordsperpixel) + this.width/2;
        //this.dy = Math.floor((this.MAPCOORDY - yCoord)*t_coordsperpixel) + this.height/2;

        this.TMPMAPCOORDX = this.MAPCOORDX;
        this.TMPMAPCOORDY = this.MAPCOORDY;
        this.BBOXLEFT = this.MAPCOORDX;
        this.BBOXTOP = this.MAPCOORDY;
    },

    slideRight: function(pixels) {
        this.resetSlideMotion();
        this._recenter({ 'x': this.width / 2 + pixels, 'y': this.height / 2 }, false);
    },
    slideLeft: function(pixels) {
        this.resetSlideMotion();
        this._recenter({ 'x': this.width / 2 - pixels, 'y': this.height / 2 }, false);
    },
    slideUp: function(pixels) {
        this.resetSlideMotion();
        this._recenter({ 'x': this.width / 2, 'y': this.height / 2 - pixels }, false);
    },
    slideDown: function(pixels) {
        this.resetSlideMotion();
        this._recenter({ 'x': this.width / 2, 'y': this.height / 2 + pixels }, false);
    },
    /**
    * Clear all the tiles from the tilelayer for a complete reinitialization of the
    * map. At this point the map is not considered to be initialized.
    */
    clear: function() {
        this.blank();
        this.initialized = false;
        this.tiles = [];
        this.tiles2 = [];
    },

    refresh: function() {
        var now = new Date();
        for (imgId in this.cache) {
            var img = this.cache[imgId];
            if (img.src != imgId) {
                img.src = imgId; // + '?' + now.getTime();
            }
        }
    },
    /**
    * Remove all tiles from the tilelayer, which effectively "hides"
    * them for a repaint.
    */
    blank: function() {
        for (imgId in this.cache) {
            var img = this.cache[imgId];
            img.onload = null;
            img.src = '../../Resource/Map/media/interface/blank.png';
            if (img.image) {
                img.image.onload = null;
            }

            if (img.parentNode != null) {
                this.tilelayer.removeChild(img);
            }
        }
        this.cache = {};
    },

    /**
    * Method specifically for handling a mouse move event.  A direct
    * movement of the map can be achieved by calling _positionTiles() directly.
    */
    movemap: function(coords) {
        if (this.navigate) {
            this._positionTiles({ 'x': (coords.x - this.mark.x), 'y': (coords.y - this.mark.y) });
            this.notifymapMoved(coords);
        }
    },

    setStatus: function(coords) {
        //window.status = coords;
    },

    fetchLoypeInfo: function() {
        Opplysningen.Rio.Web.AjaxServices.LoypeInfoProxy.getLoypeInfo(
	    this.mouseMapCoords.x,
	    this.mouseMapCoords.y,
	    this._onLoypeSuccess,
        this._onLoypeFailed,
        this);

    },

    _onLoypeSuccess: function(t_value, t_thisbind) {
        //wedebug.log("poi", "_onPOISuccess: " + t_value);
        try {
            alert(t_value);
            //var pois = t_value;
            //wedebug.log("poi", "POI querystring: " + t_thisbind.m_guiController );
            //wedebug.log("poi", "_onPOISuccess: " + pois[0].Name);
            //t_thisbind.m_guiController.addAnnotationsFromService(t_value,t_thisbind.m_poiCollectionId, t_thisbind.m_upperLevel);
            //t_thisbind.m_guiController.addAnnotationsFromService(t_value,t_thisbind.m_poiCollectionId, 66);
        }
        catch (e)
        { }

        //t_thisbind.m_guiController.hideSpinner();
    },

    _onLoypeFailed: function(t_value, t_thisbind) {
        //wedebug.log("poi", "Error communicating with shortest path web service proxy.","error");
        //t_thisbind.m_guiController.hideSpinner();
    },

    // MENU
    toggleMenu: function(rightClick) {
        /*
        if(rightClick){
        if(this.menuShown){
        dojo.lfx.html.fadeOut(document.getElementById('rightmenu'), 400).play() ;
        document.getElementById('rightmenu').style.display = 'none';
        this.menuShown = false;
        }
        else{
        document.getElementById('rightmenu').style.top = this.mouseCoords.y + 'px';
        document.getElementById('rightmenu').style.left = this.mouseCoords.x + 'px';
        document.getElementById('rightmenu').style.display = 'block';
        dojo.lfx.html.fadeIn(document.getElementById('rightmenu'), 400).play(); 
        this.menuShown = true;
        this._buildMenuItems();
        }
        }
        if(!rightClick){
        dojo.lfx.html.fadeOut(document.getElementById('rightmenu'), 400).play(); 
        document.getElementById('rightmenu').style.display = 'none';
        this.menuShown = false;
        }
        */
    },

    _buildMenuItems: function() {
        document.getElementById('rightmenu').innerHTML = '<a href="javascript:void(map.toggleSidebar())">Toggle Debug</a><br><a href="javascript:void(dojo.lfx.html.fadeWipeOut(document.getElementById(\'sidebar\'), 400).play());map.toggleMenu()">Hide Debug</a><br><a href="javascript:void(dojo.lfx.html.fadeOut(\'map\', 300).play());map.toggleMenu()">Hide Map</a><br><a href="javascript:void(dojo.lfx.html.fadeIn(\'map\', 300).play());map.toggleMenu()">Show Map</a><br>';
    },

    // SIDEBAR
    toggleSidebar: function() {
        if (this.sidebarShown) {
            dojo.lfx.html.fadeWipeOut(document.getElementById('sidebar'), 400).play();
            this.sidebarShown = false;
        }
        else {
            document.getElementById('sidebar').style.display = 'block';
            dojo.lfx.html.fadeWipeIn(document.getElementById('sidebar'), 400).play();
            this.sidebarShown = true;
        }
    },

    toggleCoordinateBox: function() {
        if (this.coordinateBoxShown) {
            dojo.lfx.html.fadeWipeOut(document.getElementById('coordinatebox'), 400).play();
            this.coordinateBoxShown = false;
        }
        else {
            document.getElementById('coordinatebox').style.display = 'block';

            dojo.lfx.html.fadeIn(document.getElementById('coordinatebox'), 400).play();
            //dojo.html.setOpacity(document.getElementById('coordinatebox'), 0.9);
            this.coordinateBoxShown = true;
        }
        this.setState();
    },
    /*
    * Fill the sidebar with html
    */
    fillSideBar: function() {
        if (this.mouseClickedMapCoords != null) {
            var points = [];
            for (var i = 0; i < this.distanceMarkers.length; i++) {
                marker = this.distanceMarkers[i];
                points[i] = { 'x': this.distanceMarkers[i].easting, 'y': this.distanceMarkers[i].northing };
            }
            /*
            html =  '<h4>Current Mousecoords:</h4>';
            html =  html + '<b>UTM Easting:</b> ' + this.mouseMapCoords.x;
            html =  html + '<br><b>UTM Northing:</b> ' + this.mouseMapCoords.y;
        
        currdg = UTMToLatLon(this.mouseMapCoords.y, this.mouseMapCoords.x);
            html =  html + '<br><b>Latitude:</b> ' + currdg.lat;
            html =  html + '<br><b>Longitude:</b> ' + currdg.lon;
        
        html =  html + '<h4>Clicked Mousecoords:</h4>';
            html =  html + '<b>UTM Easting:</b> ' + this.mouseClickedMapCoords.x;
            html =  html + '<br><b>UTM Northing:</b> ' + this.mouseClickedMapCoords.y;
        
        currdg = UTMToLatLon(this.mouseClickedMapCoords.y, this.mouseClickedMapCoords.x);
            html =  html + '<br><b>Latitude:</b> ' + currdg.lat;
            html =  html + '<br><b>Longitude:</b> ' + currdg.lon;
        
        html =  html + '<h4>Distance Measurements:</h4>';
            html =  html + '<b>Length in meters:</b> ' + this.getStraightLineDistance(points);
            html =  html + '<br><b>Length in meters:</b> ' + this.getArea(points);
            html =  html + '<br><b>Omkrets in meters:</b> ' + this.getCircuit(points);
            //html = html + '<form name="tagform" onsubmit="tagMap(this.form)"><input type="button" NAME="button" Value="Delete Tile" onClick="map.deleteTile()"></form>'
            html = html + '<form name="tagform" onsubmit="tagMap(this.form)"><input type="button" NAME="button" Value="Add Marker" onClick="map.setState();map._drawToolLine();return false;"></form>'
            */
            document.getElementById('sidebar').innerHTML = html;
        }
    },

    fillCoordinateBox: function() {
        if (this.mouseClickedMapCoords != null) {
            var points = [];
            for (var i = 0; i < this.distanceMarkers.length; i++) {
                marker = this.distanceMarkers[i];
                points[i] = { 'x': this.distanceMarkers[i].easting, 'y': this.distanceMarkers[i].northing };
            }

            html = '';
            /*
            html = "<br><br><br>";
            html =  html + '<b>Avstand:</b> ' + this.getStraightLineDistance(points) + "m";
            html =  html + '<br><b>Areal:</b> ' + this.getArea(points) + "m&sup2;";
            html =  html + '<br><b>Omkrets:</b> ' + this.getCircuit(points) + "m";
            */
            //html = html + '<form name="tagform" onsubmit="tagMap(this.form)"><input type="button" NAME="button" Value="Delete Tile" onClick="map.deleteTile()"></form>'
            if (points.length > 1) {
                html = html + 'Avstand: ' + this.getStraightLineDistance(points) + "m" + '<br />Areal: ' + this.getArea(points) + "m&sup2;" + '<br />Omkrets: ' + this.getCircuit(points) + "m" + '';
            }
            //document.getElementById('coordinatebox').innerHTML = html;
            return html;
        }
    },

    fillGPSBox: function() {
        html = '';

        html = 'X:' + this.mouseMapCoords.x + '<br />';
        html = html + 'Y:' + this.mouseMapCoords.y + '<br />';
        html = html + 'Euref89 Sone 33';

        return html;
    },

    deleteTile: function() {
        if (this.wms == NIB) {
            src = this._createPrototype(this.primaryServerHost + 'tileadm/tileadm.py' + '?x1=' + this.mouseClickedMapCoords.x + '&y1=' + this.mouseClickedMapCoords.y + '&z=' + g_zoomLevels[zoomLevel] + '&s=1&l=1');
        } else {
            //tileImgId = src = this.primaryServerHost +'?x1='+ mapx+'&y1='+mapy+'&x2='+topx+'&y2='+topy + '&z='+g_zoomLevels[zoomLevel] + '&s=0';
            src = this._createPrototype(this.primaryServerHost + 'tileadm/tileadm.py' + '?x1=' + this.mouseClickedMapCoords.x + '&y1=' + this.mouseClickedMapCoords.y + '&z=' + g_zoomLevels[zoomLevel] + '&s=0&l=1');
        }
    },

    // FIXME: Do not use magical constants
    _sizeZoomIndicatorIn: function() {
        if (this.zoomIndicatorInSize > 300) {
            document.getElementById('test').style.display = 'none';
            this.zoomIndicatorInSize = 100;
            return;
        }
        if (this.zoomIndicatorInSize == 100) {
            document.getElementById('test').style.display = 'block';
            this.zoominx = this.mouseCoords.x;
            this.zoominy = this.mouseCoords.y;
        }
        var self = this;
        this.zoomIndicatorInSize = this.zoomIndicatorInSize + 10;
        var ni = document.getElementById('test');
        ni.style.width = this.zoomIndicatorInSize + 'px';
        ni.style.height = this.zoomIndicatorInSize + 'px';
        ni.style.top = this.zoominy - (this.zoomIndicatorInSize / 2) + 'px';
        ni.style.left = this.zoominx - (this.zoomIndicatorInSize / 2) + 'px';
        this.notifymapMoved();

        this.zoomInIndicatorMotion = setTimeout(function() { self._sizeZoomIndicatorIn(); }, 3);
    },

    // FIXME: do not use magical constants
    _sizeZoomIndicatorOut: function(inwards) {
        if (this.zoomIndicatorOutSize < 200 && this.zoomIndicatorOutSize > 100) {
            document.getElementById('test2').style.display = 'none';
            this.zoomIndicatorOutSize = 100;
            return;
        }
        if (this.zoomIndicatorOutSize == 100) {
            document.getElementById('test2').style.display = 'block';
            this.zoomIndicatorOutSize = 300;
            this.zoominx = this.mouseCoords.x;
            this.zoominy = this.mouseCoords.y;
        }
        var self = this;
        this.zoomIndicatorOutSize = this.zoomIndicatorOutSize - 10;
        var ni = document.getElementById('test2');
        ni.style.width = this.zoomIndicatorOutSize + 'px';
        ni.style.height = this.zoomIndicatorOutSize + 'px';
        ni.style.top = this.zoominy - (this.zoomIndicatorOutSize / 2) + 'px';
        ni.style.left = this.zoominx - (this.zoomIndicatorOutSize / 2) + 'px';
        this.notifymapMoved();

        this.zoomOutIndicatorMotion = setTimeout(function() { self._sizeZoomIndicatorOut(); }, 3);
    },
    /**
    * Make the specified coords the new center of the image placement.
    * This method is typically triggered as the result of a double-click
    * event.  The calculation considers the distance between the center
    * of the viewable area and the specified (map-relative) coordinates.
    * If absolute is specified, treat the point as relative to the entire
    * image, rather than only the viewable portion.
    */
    _recenter: function(coords, absolute) {
        if (this.navigate) {
            if (absolute) {
                coords.x += this.x;
                coords.y += this.y;
            }

            var motion = {
                'x': Math.floor((this.width / 2) - coords.x),
                'y': Math.floor((this.height / 2) - coords.y)
            };

            if (motion.x == 0 && motion.y == 0) {
                this._createCustomLayer();
                this._createWMSLayer();
                this.mouseCoords = { 'x': 0, 'y': 0 }
                var t_coordsperpixel = 256 / g_zoomLevels[zoomLevel];
                this.mouseMapCoords = { 'x': (this.BBOXLEFT + (0 * t_coordsperpixel)), 'y': (this.BBOXTOP - (0 * t_coordsperpixel)) };
                this.notifymapPanned();
                return;
            }

            if (AJAXMAP.USE_SLIDE) {
                var target = motion;
                var x, y;
                // handle special case of vertical movement
                if (target.x == 0) {
                    x = 0;
                    y = this.slideAcceleration;
                }
                else {
                    var slope = Math.abs(target.y / target.x);
                    x = Math.round(Math.pow(Math.pow(this.slideAcceleration, 2) / (1 + Math.pow(slope, 2)), 0.5));
                    y = Math.round(slope * x);
                }

                motion = {
                    'x': Math.min(x, Math.abs(target.x)) * (target.x < 0 ? -1 : 1),
                    'y': Math.min(y, Math.abs(target.y)) * (target.y < 0 ? -1 : 1)
                };
            }

            this._positionTiles(motion, true);



            if (!AJAXMAP.USE_SLIDE) {
                return;
            }

            var newcoords = {
                'x': coords.x + motion.x,
                'y': coords.y + motion.y
            };

            var self = this;
            // TODO: use an exponential growth rather than linear (should also depend on how far we are going)
            // FIXME: this could be optimized by calling _positionTiles directly perhaps
            this.slideAcceleration += AJAXMAP.SLIDE_ACCELERATION_FACTOR;
            this.slideMonitor = setTimeout(function() { self._recenter(newcoords); }, AJAXMAP.SLIDE_DELAY);
        }
    },

    center: function(coords, absolute) {
        if (absolute) {
            coords.x += this.x;
            coords.y += this.y;
        }

        var motion = {
            'x': Math.floor((this.width / 2) - coords.x),
            'y': Math.floor((this.height / 2) - coords.y)
        };

        if (motion.x == 0 && motion.y == 0) {
            return;
        }


        this._positionTiles(motion, true);
        this.notifymapMoved();
    },

    centerOnCoords: function(coords, mouse, t_setSource) {
        var t_coordsperpixel = 256 / g_zoomLevels[zoomLevel];

        if (mouse) {
            var motion = {
                'x': Math.floor(((coords.x - this.BBOXLEFT) * -t_coordsperpixel) + (this.mouseCoords.x)),
                'y': Math.floor(((coords.y - this.BBOXTOP) * t_coordsperpixel) + (this.mouseCoords.y))
            };
        }
        else {
            var motion = {
                'x': Math.floor(((coords.x - this.BBOXLEFT) * -t_coordsperpixel) + (this.width / 2)),
                'y': Math.floor(((coords.y - this.BBOXTOP) * t_coordsperpixel) + (this.height / 2))
            };
        }
        this._positionTiles(motion, true, t_setSource);
        this.notifymapMoved();
    },

    /*
    * Resizes the map window. NOTE: this should be used in conjunction with a fullscreen implementation
    * of the map, as it consumes available width/ height in the page.
    */
    resize: function(width, height, t_setSource) {
        // IE fires a premature resize event
        if (!this.initialized) {
            return;
        }

        var t_display = this.map.style.display;
        this.map.style.display = 'none';
        this.clear();

        var before = {
            'x': Math.floor(this.width / 2),
            'y': Math.floor(this.height / 2)
        };

        if (this.border >= 0) {
            if (this.sidebar > 0) {
                this.fitToWindow(this.border, this.sidebar, width, height);
            }
            else {
                this.fitToWindow(this.border, 0, width, height);
            }
        }
        else {
            this.fitToWindow(this.border, false, width, height);
        }

        this._prepareTiles(t_setSource);

        var after = {
            'x': Math.floor(this.width / 2),
            'y': Math.floor(this.height / 2)
        };

        this.x += (after.x - before.x);
        this.y += (after.y - before.y);
        var t_coordsperpixel = g_zoomLevels[zoomLevel] / 256;
        this.BBOXLEFT -= (after.x - before.x) * t_coordsperpixel;
        this.BBOXTOP += (after.y - before.y) * t_coordsperpixel;
        this._positionTiles({ "x": 0, "y": 0 }, false, t_setSource);
        this.map.style.display = t_display;
        this.initialized = true;
        this.notifymapMoved();
        this.refresh();
        this._createCustomLayer();
        this._createWMSLayer();

        this.top = 0;
        this.left = 0;

        for (var node = this.map; node; node = node.offsetParent) {
            this.top += node.offsetTop;
            this.left += node.offsetLeft;
        }
    },

    /**
    * Should be called on a browserwindow resize. Updates the map (screen & geocoords) coordinate system according to viewport placement.
    */
    fit: function() {

        if (!this.initialized) {
            return;
        }

        this.clear();

        var before = {
            'x': Math.floor(this.width / 2),
            'y': Math.floor(this.height / 2)
        };

        this._prepareTiles();

        var after = {
            'x': Math.floor(this.width / 2),
            'y': Math.floor(this.height / 2)
        };

        this._positionTiles();

        this.initialized = true;
        this.notifymapMoved();
        this.refresh();

        this.top = 0;
        this.left = 0;

        for (var node = this.map; node; node = node.offsetParent) {
            this.top += node.offsetTop;
            this.left += node.offsetLeft;
        }
    },

    /**
    * Cross-browser method for getting the Viewport Y-position relative to the page topY
    */
    getViewportScrollY: function() {
        var scrollY = 0;
        if (document.documentElement && document.documentElement.scrollTop) {
            scrollY = document.documentElement.scrollTop;
        }
        else if (document.body && document.body.scrollTop) {
            scrollY = document.body.scrollTop;
        }
        else if (window.pageYOffset) {
            scrollY = window.pageYOffset;
        }
        else if (window.scrollY) {
            scrollY = window.scrollY;
        }
        return scrollY;
    },

    /**
    * Resolve the coordinates from this mouse event by subtracting the
    * offset of the map in the browser window (or frame).
    */
    resolveCoordinates: function(e) {
        return { 'x': (e.clientX - this.left), 'y': (e.clientY - this.top) + this.getViewportScrollY() };

    },

    press: function(coords) {
        this.activate(true);
        this.mark = coords;
    },

    release: function(coords) {
        this.activate(false);
        var motion = {
            'x': (coords.x - this.mark.x),
            'y': (coords.y - this.mark.y)
        };
        if (this.navigate) {
            var t_coordsperpixel = g_zoomLevels[zoomLevel] / 256;
            this.BBOXLEFT -= (motion.x * t_coordsperpixel);
            this.BBOXTOP += (motion.y * t_coordsperpixel);

            this.x += motion.x;
            this.y += motion.y;
            this.mark = { 'x': 0, 'y': 0 };
            this._createCustomLayer();
            this._createWMSLayer();
        }
    },

    /**
    * Activate the map into motion depending on whether the mouse is pressed or
    * not pressed.  This method localizes the changes that must be made to the
    * layers.
    */
    activate: function(pressed) {
        this.pressed = pressed;
        //this.mouselayer.style.cursor = (pressed ? AJAXMAP.GRABBING_MOUSE_CURSOR : AJAXMAP.GRAB_MOUSE_CURSOR);
        this.mouselayer.onmousemove = AJAXMAP.mouseMovedHandler;
    },

    // QUESTION: where is the best place for this method to be invoked?
    resetSlideMotion: function() {
        if (this.slideMonitor != 0) {
            clearTimeout(this.slideMonitor);
            this.slideMonitor = 0;
        }
        this.slideAcceleration = 0;
    },

    toggleMapStyle: function() {
        //this.blank();
        /*
        if(this.wms == this.primaryServerHost + WMS){
        this.wms = NIB;
        }
        else{
        this.wms = this.primaryServerHost + WMS;
        }
        */
        if (this.mapScheme == 0) {
            this.mapScheme = 1;
        }
        else {
            this.mapScheme = 0;
        }
        this._positionTiles();
        //this.movemap({'x':0,'y':0});
        //this.refresh();
    },

    /**
    * Sets the map style. 0 = vector 1 = satellite/ vector
    */
    setMapStyle: function(mapStyle) {
        this.mapScheme = mapStyle;
        this._positionTiles();
    },

    /**
    * Returns the current map style as an integer
    */
    getMapStyle: function() {
        return this.mapScheme;
    },

    activateZoomSlider: function() {
        this.zoomSliderActive = true;
    },

    moveSlider: function() {

        this.zoomSliderYPosition = 145 + ((132 / g_zoomLevels.length) * zoomLevel);

        var ni = document.getElementById('sliderbar');
        if (ni) {
            ni.style.top = this.zoomSliderYPosition + 'px';
            var ni2 = document.getElementById('sliderbarshadow');
            ni2.style.top = this.zoomSliderYPosition + 'px';
        }
    },

    _setPrimaryWMSHost: function(host) {
        this.primaryServerHost = host;
    },

    addNoTileLayer: function(wmsString, moveWithMap) {
        this.noTileLayersWMSStrings.push(wmsString);
        this.noTileMoves.push(moveWithMap);
    },

    setSelectLayer: function(layer, cat) {
        this.selectedLayer = layer;
        this.selectedLayerWMS = cat;
    },

    setFeatureMap: function(layer) {
        this.featureMap = layer;
    },

    addWMSLayer: function(layer) {
        for (var i = 0; i < this.WMSLayers.length; i++) {
            if (this.WMSLayers[i].name == layer) {
                this.WMSLayers[i].visible = true;
                break;
            }
        }
    },

    removeWMSLayer: function(layer) {
        for (var i = 0; i < this.WMSLayers.length; i++) {
            if (this.WMSLayers[i].name == layer) {
                this.WMSLayers[i].visible = false;
                break;
            }
        }
    },

    addNavigationControls: function() {


        var ni = document.getElementById('mouselayer');
        t_newdiv = document.createElement('div');
        t_divIdName = 'sliderbackground';
        t_newdiv.setAttribute('id', t_divIdName);
        t_newdiv.innerHTML = '<div class="sliderbackground"></div>';
        ni.appendChild(t_newdiv);

        var ni = document.getElementById('mouselayer');
        t_newdiv = document.createElement('div');
        t_divIdName = 'sliderbarshadow';
        t_newdiv.setAttribute('id', t_divIdName);
        t_newdiv.innerHTML = '<div class="innershadow"></div>';
        ni.appendChild(t_newdiv);

        var ni = document.getElementById('mouselayer');
        t_newdiv = document.createElement('div');
        t_divIdName = 'sliderbar';
        t_newdiv.setAttribute('id', t_divIdName);
        t_newdiv.innerHTML = '<a href="javascript: void(0);" onmousedown="map.activateZoomSlider();return false;"  onclick="map.releaseZoomSlider();return false;"title="Zoom inn/ ut"><img src="../../Resource/Map/media/interface/transparent.gif" style="width: 48px; height: 36px;"/></a>';
        ni.appendChild(t_newdiv);

        this.moveSlider();

        var ni = document.getElementById('mouselayer');
        var t_newdiv = document.createElement('div');
        var t_divIdName = 'myDiv';
        t_newdiv.setAttribute('id', t_divIdName);

        t_newdiv.innerHTML = '<div class="rightArrow"><a href="javascript: void(0);" onclick="map.slideRight(500);"class="slideRight" title="Panorer mot venstre"><img src="../../Resource/Map/media/interface/transparent.gif" style="width: 23px; height: 23px;"/></a></div>';
        t_newdiv.innerHTML += '<div class="leftArrow"><a href="javascript: void(0);" onclick="map.slideLeft(500);"class="slideLeft" title="Panorer mot høyre"><img src="../../Resource/Map/media/interface/transparent.gif" style="width: 23px; height: 23px;"/></a></div>';
        t_newdiv.innerHTML += '<div class="upArrow"><a href="javascript: void(0);" onclick="map.slideUp(500);"class="slideUp" title="Panorer opp"><img src="../../Resource/Map/media/interface/transparent.gif" style="width: 23px; height: 23px;"/></a></div>';
        t_newdiv.innerHTML += '<div class="downArrow"><a href="javascript: void(0);" onclick="map.slideDown(500);"class="slideDown" title="Panorer ned"><img src="../../Resource/Map/media/interface/transparent.gif" style="width: 23px; height: 23px;"/></a></div>';
        t_newdiv.innerHTML += '<div class="zoomInButton"><a href="javascript: void(0);" onclick="map.zoomPlus(false);return false;"class="slideUp" title="Zoom inn"><img src="../../Resource/Map/media/interface/transparent.gif" style="width: 30px; height: 30px;"/></a></div>';
        t_newdiv.innerHTML += '<div class="zoomOutButton"><a href="javascript: void(0);" onclick="map.zoomMinus(false);return false;"class="slideUp" title="Zoom ut"><img src="../../Resource/Map/media/interface/transparent.gif" style="width: 30px; height: 30px;"/></a></div>';
        t_newdiv.innerHTML += '<div class="logo"><div id="none"><a href="http://www.webatlas.no" title="webatlas.no"><img src="../../Resource/Map/media/interface/transparent.gif" style="width: 260px; height: 34px;"/></a></div></div>';
        ni.appendChild(t_newdiv);
    },

    addMapControls: function() {
        var ni = document.getElementById('mouselayer');
        var t_newdiv = document.createElement('div');
        var t_divIdName = 'aerialDiv';
        t_newdiv.setAttribute('id', t_divIdName);
        t_newdiv.innerHTML = '<p class="aerial"><div class="aerialClickable"><a href="javascript: void(0);" onclick="map.toggleMapStyle();return false;" title="Bytt karttype"><img src="../../Resource/Map/media/interface/transparent.gif" style="width: 37px; height: 32px;"/></a></div></p>';

        ni.appendChild(t_newdiv);

        var ni = document.getElementById('mouselayer');
        var t_newdiv = document.createElement('div');
        var t_divIdName = 'measureDiv';
        t_newdiv.setAttribute('id', t_divIdName);
        //t_newdiv.innerHTML =  '<p class="aerial"><div class="aerialClickable"><a href="javascript: void(0);" onclick="map.toggleMapStyle();" title="Toggle Map Style"><img src="media/interface/transparent.gif" style="width: 23px; height: 23px;"/></a></div></p>';
        t_newdiv.innerHTML = '<div class="measure"><a href="javascript: void(0);" onclick="map.toggleCoordinateBox(); return false;" title="Målinger"><img src="../../Resource/Map/media/interface/transparent.gif" width="37px"/></a></div>';

        ni.appendChild(t_newdiv);
        //DEBUG
        var ni = document.getElementById('map');
        var t_newdiv = document.createElement('div');
        var t_divIdName = 'sidebar';
        t_newdiv.setAttribute('id', t_divIdName);
        t_newdiv.innerHTML = '';

        ni.appendChild(t_newdiv);

        var ni = document.getElementById('map');
        var t_newdiv = document.createElement('div');
        var t_divIdName = 'coordinatebox';
        t_newdiv.setAttribute('id', t_divIdName);
        t_newdiv.innerHTML = '';

        ni.appendChild(t_newdiv);

        var ni = document.getElementById('coordinatebox');
        var t_newdiv = document.createElement('div');
        var t_divIdName = 'distanceButton';
        t_newdiv.setAttribute('id', t_divIdName);
        ni.appendChild(t_newdiv);

        document.getElementById('coordinatebox').style.display = 'none';

        var ni = document.getElementById('map');
        //DEBUG
        document.getElementById('sidebar').style.display = 'none';
        var t_newdiv = document.createElement('div');
        var t_divIdName = 'rightmenu';
        t_newdiv.setAttribute('id', t_divIdName);
        t_newdiv.innerHTML = 'Menu';

        ni.appendChild(t_newdiv);
    },

    geoToScreenCoordinates: function(northing, easting) {
        pixelspercoord = 256 / g_zoomLevels[zoomLevel];
        //264136 6649119
        var x = (easting - this.BBOXLEFT) * pixelspercoord;
        var y = (this.BBOXTOP - northing) * pixelspercoord;
        this.markerPosX = x;
        this.markerPosY = y;
        return { 'x': x, 'y': y };
    },

    geoToScreen: function(t_Coordinate) {
        pixelspercoord = 256 / g_zoomLevels[zoomLevel];
        //264136 6649119
        var x = (t_Coordinate.x - this.BBOXLEFT) * pixelspercoord;
        var y = (this.BBOXTOP - t_Coordinate.y) * pixelspercoord;
        return { 'x': x, 'y': y };
    },

    placeMarkers: function() {
        for (var i = 0; i < this.distanceMarkers.length; i++) {
            t_marker = this.distanceMarkers[i];
            this.distanceMarkersA[i].style.display = 'block';
            // Do not show markers outside 
            /*
            if(t_marker.upperbound < zoomLevel || t_marker.lowerbound > zoomLevel){
            this.markersA[i].style.display = 'none';
            }else{
            this.markersA[i].style.display = 'block';
            } 
            */
            screenCoords = this.geoToScreenCoordinates(t_marker.northing, t_marker.easting);
            //t_marker.element.style.top  = screenCoords.y - 15 + 'px';
            //t_marker.element.style.left = screenCoords.x - 15 + 'px';

            t_marker.x = screenCoords.x;
            t_marker.y = screenCoords.y;

            t_marker.element.style.top = screenCoords.y + 'px';
            t_marker.y = screenCoords.y;

            t_marker.element.style.left = screenCoords.x + 'px';
            t_marker.x = screenCoords.x;
        }

        for (var i = 0; i < this.markers.length; i++) {
            t_marker = this.markers[i];
            // Do not show markers outside 
            if (t_marker.upperbound < zoomLevel || t_marker.lowerbound > zoomLevel) {
                this.markersA[i].style.display = 'none';
            } else {
                this.markersA[i].style.display = 'block';
            }
            screenCoords = this.geoToScreenCoordinates(t_marker.northing, t_marker.easting);
            //t_marker.element.style.top  = screenCoords.y - 15 + 'px';
            //t_marker.element.style.left = screenCoords.x - 15 + 'px';

            //t_marker.x = screenCoords.x - 15;
            //t_marker.y = screenCoords.y - 15;

            t_marker.element.style.top = screenCoords.y + t_marker.yOffset + 'px';
            t_marker.y = screenCoords.y + t_marker.yOffset;

            t_marker.element.style.left = screenCoords.x + t_marker.xOffset + 'px';
            t_marker.x = screenCoords.x + t_marker.xOffset;

        }


        //Place hotspot markers
        try {
            var i, length = this._hotspots.length;
            for (i = 0; i < length; i++) {
                var spot = this._hotspots[i];
                if (spot.upperbound < zoomLevel || spot.lowerbound > zoomLevel) {
                    this._hotspotDivs[i].style.display = 'none';
                } else {
                    this._hotspotDivs[i].style.display = 'block';
                }
                //if(i==0)alert([spot.northing, spot.easting, spot.x, spot.y]);
                var screenCoords = this.geoToScreenCoordinates(spot.northing, spot.easting);
                //spot.x = screenCoords.x - 15;
                //spot.y = screenCoords.y - 15;

                this._hotspotDivs[i].style.top = screenCoords.y + spot.yOffset + 'px';
                spot.y = screenCoords.y;

                this._hotspotDivs[i].style.left = screenCoords.x + spot.xOffset + 'px';
                spot.x = screenCoords.x;
            }
        }
        catch (e) {
            //ignore
        }
    },

    /**
    * Adds an annotation to the map
    */
    addMarker: function(icon, northing, easting, title, html, lb, ub, xOffset, yOffset) {
        //if(!icon){
        //    icon="marker.png";
        //}
        if (!xOffset) {
            xOffset = 0;
            yOffset = 0;
        }
        this.markerCount++;
        screenCoords = this.geoToScreenCoordinates(northing, easting);
        var a = document.createElement('a');
        a.href = "javascript: map.showDetails(" + this.markerCount + ");";

        //marker.onmouseover = AJAXMAP.zoomIn2Handler;
        a.title = title;
        var img = document.createElement('img');

        img.src = icon;
        img.alt = title;
        img.relativeSrc = icon;

        img.style.position = "absolute";
        img.style.top = screenCoords.y - 15 + 'px';
        img.style.left = screenCoords.x - 15 + 'px';

        var t_marker = {
            'element': img,
            'northing': northing,
            'easting': easting,
            'lowerbound': lb,
            'upperbound': ub,
            'yOffset': yOffset,
            'xOffset': xOffset,
            'x': screenCoords.x - 15 - this.x,
            'y': screenCoords.y - 15 - this.y,
            'relX': screenCoords.x - 15,
            'relY': screenCoords.y - 15,
            'html': html,
            'title': title
        };
        //marker.element.onmouseover = AJAXMAP.zoomIn2Handler;
        a.appendChild(img);

        this.mouselayer.appendChild(a);
        //this.mouselayer.appendChild(t_marker.element);
        this.markers.push(t_marker);
        this.markersA.push(a);
    },

    /**
    * Adds an annotation to the map
    */
    addHotspot: function(control, id, icon, lat, lon, enterCallback, exitCallback, lb, ub, xOffset, yOffset, t_type) {
        //if(!icon){
        //    icon="marker.png";
        //}
        //    	    setTimeout(
        //	        (function(control)
        //	        {
        //	            alert([control.currentStyle.hasLayout,
        //	                control.parentElement.currentStyle.hasLayout,
        //	                control.parentElement.parentElement.currentStyle.hasLayout,
        //	                Element.getHeight(control), 
        //	                Element.getHeight(control.parentElement), 
        //	                Element.getHeight(control.parentElement.parentElement)]);
        //	            
        //	        }).bind(this,control)
        //	        , 3000);
        var utm = decimalDegreesToUTM({ y: lat, x: lon }); //Transforming back from latlong to UTM.

        if (!xOffset) {
            xOffset = 0;
            yOffset = 0;
        }
        this.hotspotCount++;
        screenCoords = this.geoToScreenCoordinates(utm.y, utm.x);

        var div = $(document.createElement('div'));
        div.id = id;

        if (id == 'flag') {
            div.innerHTML = '<div style="color: white; background-color:black;font-style:bold;font-weight:bold;font-family:verdana;font-size:9pt;padding:5px">' + t_type + '</div>';
        }
        div.onmouseover = function() {
            enterCallback(this.id, this.style.left, this.style.top);
        } //"map.showDetails("+this.markerCount+");";
        div.onmouseout = function() {
            exitCallback(this.id);
        }

        //marker.onmouseover = AJAXMAP.zoomIn2Handler;
        //a.title=title;
        var img = $(document.createElement('img'));

        img.src = icon;
        //img.alt = title;
        img.relativeSrc = icon;

        //div.style.visibility = "hidden";
        Element.setStyle(div,
            {
                "position": "absolute",
                "top": parseInt(screenCoords.y + yOffset) + "px",
                "left": parseInt(screenCoords.x + xOffset) + "px"
            }
        );
        //        alert([screenCoords.y,screenCoords.x]);
        // 	    div.style.position = "absolute";
        //        div.style.top  = screenCoords.y -15 + 'px';
        //	    div.style.left = screenCoords.x -15 + 'px';
        if ((typeof ub != "undefined" && ub != null && ub < zoomLevel) || (typeof lb != "undefined" && lb != null && lb > zoomLevel)) {
            div.style.display = "none";
        }
        //div.style.border = "1px solid Red";

        var t_marker = {
            'id': id,
            'northing': utm.y,
            'easting': utm.x,
            'lowerbound': (typeof lb != "undefined" && lb != null) ? lb : 0,
            'upperbound': (typeof ub != "undefined" && ub != null) ? ub : 20,
            'yOffset': yOffset,
            'xOffset': xOffset,
            'x': parseInt(screenCoords.x) - this.x,
            'y': parseInt(screenCoords.y) - this.y,
            'relX': parseInt(screenCoords.x) - 15,
            'relY': parseInt(screenCoords.y) - 15,
            'type': t_type
        };
        //marker.element.onmouseover = AJAXMAP.zoomIn2Handler;

        //HACK: 
        if (id != 'flag')
            div.appendChild(img);
        //var t_height = Element.getHeight(control);
        control.appendChild(div);

        if (id == 'flag') {
            t_marker.xOffset = -Element.getWidth(div) / 2;
            t_marker.yOffset = -Element.getHeight(div) - 20;
            Element.setStyle(div,
            {
                "position": "absolute",
                "top": parseInt(screenCoords.y + t_marker.yOffset) + "px",
                "left": parseInt(screenCoords.x + t_marker.xOffset) + "px"
            }

        );
            div.innerHTML += '<div style="background-color:black;width:1px;height:10px;position:absolute;left:' + (-t_marker.xOffset) + 'px"></div>';
        }
        //Element.setStyle(control, {"height" : t_height})
        //alert([t_marker.northing,t_marker.easting,t_marker.yOffset,t_marker.xOffset, t_marker.x, t_marker.y, t_marker.relX, t_marker.relY]);

        this._hotspots.push(t_marker);
        this._hotspotDivs.push(div);
        //control.style.display = "block"; 
    },

    /**
    Function for removing hotspot from map. Requires prototype library.
    */
    removeHotspot: function(t_id) {
        //this._hotspots.length = 0;
        var t_spot = $(t_id);
        if (t_spot != null) {
            var i, t_length = this._hotspotDivs.length;
            var t_newArr = [];

            for (i = 0; i < t_length; i++) {
                if (!(this._hotspotDivs[i].id == t_id)) {
                    t_newArr.push(this._hotspotDivs[i]);
                }
            }
            this._hotspotDivs = t_newArr;

            //this._hotspotDivs = this._hotspotDivs.without(spot); //This one was slooooow.            

            var selectfunc = function(t_value) {
                return t_id != t_value.id;
            };

            Element.remove(t_spot);

            this._hotspots = this._hotspots.select(selectfunc);
            this.hotspotCount = this._hotspots.length;
        }
    },

    /**
    HACK: Show and hide are needed in order to hide hotspot when map switches to VE
    */
    hideHotspots: function() {
        var i, length = this._hotspotDivs.length;
        for (i = 0; i < length; i++) {
            this._hotspotDivs[i].style.display = "none";
        }
    },

    showHotspots: function() {
        var i, length = this._hotspotDivs.length;
        for (i = 0; i < length; i++) {
            this._hotspotDivs[i].style.display = "block";
        }
    },

    /**
    * Adds an annotation to the map
    */
    addDistanceMarker: function(northing, easting) {
        this.distanceMarkerCount++;
        screenCoords = this.geoToScreenCoordinates(northing, easting);
        var a = document.createElement('a');
        //a.href = "javascript: map.enablePointMove("+this.distanceMarkerCount+");";
        //a.innerHTML = "<a href=\"#box\" onclick=\"alert(\'onclick\')></a>";
        //a.onmouseover = AJAXMAP.zoomIn2Handler;
        var img = document.createElement('img');

        img.src = 'Resource/Map/images/gfx2/poi/measPoint.gif';
        //img.relativeSrc = 'http://www.webatlas.no/tiledmap/zettmedia/interface/measPoint.gif';

        img.style.position = "absolute";
        img.style.top = screenCoords.y - 4 + 'px';
        img.style.left = screenCoords.x - 4 + 'px';

        var t_marker = {
            'element': img,
            'northing': northing,
            'easting': easting,
            'x': screenCoords.x - this.x,
            'y': screenCoords.y - this.y,
            'relX': screenCoords.x,
            'relY': screenCoords.y
        };

        a.appendChild(img);

        this.mouselayer.appendChild(a);
        this.distanceMarkers.push(t_marker);
        this.distanceMarkersA.push(a);

        this.redrawMeasures();
    },

    movePoint: function() {
        /*
        if(this.selectedPointId != null){
        var t_marker = this.distanceMarkers[this.selectedPointId];
        t_marker.x = this.mouseCoords.x - this.x;
        t_marker.y = this.mouseCoords.y - this.y;
        t_marker.relX = this.mouseCoords.x;
        t_marker.relY = this.mouseCoords.y ;
        t_marker.element.style.left = t_marker.relX -4 + 'px';
        t_marker.element.style.top  = t_marker.relY -4 + 'px';

        t_marker.northing = this.mouseMapCoords.y;
        t_marker.easting = this.mouseMapCoords.x;
        
        this._drawToolLine();
        
        }*/
    },

    enablePointMove: function(pointId) {
        /*
        this.selectedPointId = pointId -1;
        if(!this.pointMove){
        this.pointMove = true;
        this.allowNavigation(false);
        }
        else{
        this.pointMove = false;
        this.allowNavigation(true);
        }
        //this.allowNavigation(false);
        */
    },
    /*
    addPlacedMarker : function(icon, yOffset, xOffset, northing, easting, title, html,lb,ub){
    this.markerCount++;
    screenCoords = this.geoToScreenCoordinates(northing, easting);
    var a = document.createElement('a');
    a.href = "javascript: map.showDetails("+this.markerCount+");";
    a.title=title;
    var img = document.createElement('img');
    img.src = icon;
    img.alt = title;
    img.relativeSrc = icon;

 	    img.style.position = "absolute";
    img.style.top  = screenCoords.y + yOffset + 'px';
    img.style.left = screenCoords.x + xOffset + 'px';

		var marker = {
    'element' : img,
    'northing' : northing,
    'easting' : easting,
    'lowerbound' : lb,
    'upperbound' : ub,
    'yOffset' : yOffset,
    'xOffset' : xOffset,
    'x' : screenCoords.x-15 - this.x,
    'y' : screenCoords.y-15 - this.y,
    'relX' : screenCoords.x-15,
    'relY' : screenCoords.y-15,
    'html' : '<div id="bubblecontent">'+html+'</div>'
    };

		a.appendChild(img);
	    
    this.mouselayer.appendChild(a);
    this.markers.push(marker);
    this.markersA.push(a);
    },
    */
    /**
    * Clears all annotations from the map
    */
    clearAnnotations: function() {
        for (var i = 0; i < this.markers.length; i++) {
            this.mouselayer.removeChild(this.markersA[i]);
        }
        this.markers = [];
        this.markersA = [];
    },

    /**
    * Adds annotations from a xml file. Uses the geoRSS standard. FIXME: IE7 support!
    */
    _addAnnotationsFromXML: function() {
        var x = xmlDoc.getElementsByTagName('item');

        for (i = 0; i < x.length; i++) {
            var icon = "/Resource/Map/media/icons/newsfire-icon.png";
            for (j = 0; j < x[i].childNodes.length; j++) {
                if (x[i].childNodes[j].nodeType != 1) { continue; }
                if (x[i].childNodes[j].tagName == 'title') { var title = x[i].childNodes[j].firstChild.nodeValue; }
                if (x[i].childNodes[j].tagName == 'description') { var description = x[i].childNodes[j].firstChild.nodeValue; }
                if (x[i].childNodes[j].tagName == 'icon') { icon = x[i].childNodes[j].firstChild.nodeValue; }
                if (x[i].childNodes[j].tagName == 'geo:lat') { var geoLat = x[i].childNodes[j].firstChild.nodeValue; }
                if (x[i].childNodes[j].tagName == 'geo:long') { var geoLon = x[i].childNodes[j].firstChild.nodeValue; }
                var coords = { 'x': Number(geoLon), 'y': Number(geoLat) };
                // FIXME: uncomment to enable wgs84coords
                var newCoords = decimalDegreesToUTM(coords);

            }
            map.addMarker(icon, newCoords.y, newCoords.x, title, description);
        }
    },

    /**
    * Displays a small window with information pertaining to the selected annotation
    */
    showDetails: function(id) {
        var ni = document.getElementById('bubble');
        var ni2 = document.getElementById('bubblecontent');
        var ni3 = document.getElementById('bubbleheader');
        if (!this.detailsShown || this.selectedMarker != this.markers[id - 1]) {
            this.selectedMarker = this.markers[id - 1];
            ni2.innerHTML = this.selectedMarker.html;
            ni3.innerHTML = '<b>' + this.selectedMarker.title + '</b>';
            if (this.selectedMarker.relY - 250 < 0 || this.selectedMarker.relX - 250 < 0 || this.selectedMarker.relX + 250 > this.width) {
                this.resetSlideMotion();
                this._recenter({ 'x': this.selectedMarker.relX, 'y': this.selectedMarker.relY - 50 }, false);
            }

            ni2.style.top = this.selectedMarker.relY - 250 + 'px';
            ni2.style.left = this.selectedMarker.relX - 150 + 'px';
            ni.style.top = this.selectedMarker.relY - 250 + 'px';
            ni.style.left = this.selectedMarker.relX - 150 + 'px';
            ni.style.display = "block";
            this.detailsShown = true;
        }
        else {
            ni.style.display = "none";
            this.detailsShown = false;
        }
    },

    /**
    * Hide the information box.
    */
    hideDetails: function() {
        var ni = document.getElementById('bubble');
        ni.style.display = "none";
        this.detailsShown = false;
    },

    _initDojoSurface: function() {
        container = dojo.byId("paintlayer");
        this.group = dojo.gfx.createSurface(container, 2000, 2000);
        //this.group = surface.createGroup();
    },

    _drawToolLine: function() {

        if (this.mouseCoords != null) {
            if (this.line2 != null) {
                this.group.remove(this.line2);
                this.group.remove(this.line);
                this.group.remove(this.line3);
            }
            this.points = [];
            closingPoints = [];
            for (var i = 0; i < this.distanceMarkers.length; i++) {
                var t_marker = this.distanceMarkers[i];
                //points[points.length] = {'x': this.mouseCoords.x,'y':this.mouseCoords.y};//this.mouseCoords; 
                //var point2 = this.geoToScreenCoordinates(t_marker.northing,t_marker.easting);
                //if(t_marker.relY > 0){
                this.points.push({ 'x': t_marker.relX, 'y': t_marker.relY });
                //}
                //points = [{x: 100, y: 100}, {x: 45, y: 34}, {x: 12, y: 43}, {x: 65, y: 342}, {x: 345, y: 290}];
                //points[points.length - 1] = ({x: 345, y: 500});
            }

            closingPoints[0] = this.points[0];
            closingPoints[1] = this.points[this.points.length - 1];

            if (this.points.length > 1) {
                this.line = this.group.createPolyline(this.points).applyTransform(dojo.gfx.matrix.identity).setStroke({ color: "black", width: 8, cap: "round", join: "bevel" });
                this.line2 = this.group.createPolyline(this.points).applyTransform(dojo.gfx.matrix.identity).setStroke({ color: "white", width: 6, cap: "round", join: "bevel" });

                this.line3 = this.group.createPolyline(closingPoints).setStroke({ color: [255, 255, 255, 0.5], width: 8, cap: "round", join: "bevel" }).applyTransform(dojo.gfx.matrix.identity);
                if (this.points.length > 10) {
                    this.points.splice(0, 100);
                }
            }
        }
    },

    /**
    * Add a polyLine to the array of polyLines
    */
    addPolyLine: function(points, width) {
        this.polyLines.push(points);
    },

    /*
    * Draws all polylines 
    */
    drawPolyLines: function() {

    },

    /**
    * Parses an XML and extract path information
    */
    loadPath: function(xmlD) {
        //FIXME: proper parsing
        var x = xmlD.getElementsByTagName('FindShortestPathResult')[0].firstChild.data;
        x = x.substr(x.indexOf('<Coordinates>') + 13, x.indexOf('</Coordinates>') - 27);
        x = x.split(' ');
        //document.write(x);
        var icon = "media/icons/waypoint.png";
        for (i = 0; i < x.length; i++) {
            var tmp = x[i].split(',');
            map.addMarker(icon, tmp[1], tmp[0], "Easting:  " + tmp[0], "Northing:  " + tmp[1] + "   Easting:  " + tmp[0]);
        }
    },

    /**
    * Load up a GeoRSS file asyncronously
    */
    loadGeoRSS: function(url) {
        if (document.implementation && document.implementation.createDocument) {
            xmlDoc = document.implementation.createDocument("", "", null);
            xmlDoc.async = "false";
            xmlDoc.onload = this._addAnnotationsFromXML;
        } else if (document.documentElement && typeof document.documentElement.style.maxHeight != "undefined") {
            var xmlIsland = document.getElementById("xmlI");
            xmlIsland.async = false;
            xmlIsland.load(url);
            xmlDoc = xmlIsland;
            this._addAnnotationsFromXML();
            return;
        }
        else if (window.ActiveXObject) {
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async = "false";
            xmlDoc.onreadystatechange = this._addAnnotationsFromXML();
        } else {
            alert('Your browser can\'t handle this script');
            return;
        }
        xmlDoc.load(url);
    },

    /**
    * Sets the sliderbar to the correct y-position
    */
    //    fixZoomSliderPosition : function() {
    //        var ni = document.getElementById('sliderbar');
    //        var ni2 = document.getElementById('sliderbarshadow');
    //	    var tmpSliderPos = this.mouseCoords.y - 17;
    //	    if(tmpSliderPos < 145){
    //	        this.zoomSliderYPosition = 145;
    //	        ni.style.top = this.zoomSliderYPosition + 'px';
    //	        ni2.style.top = this.zoomSliderYPosition + 'px';
    //	    }else if(tmpSliderPos > 145 + ((132 / g_zoomLevels.length) * (g_zoomLevels.length - 1))){
    //	        this.zoomSliderYPosition = 145 + ((132 / g_zoomLevels.length) * (g_zoomLevels.length - 1));
    //	        ni.style.top = this.zoomSliderYPosition + 'px';
    //	        ni2.style.top = this.zoomSliderYPosition + 'px';
    //	    }else{
    //	        this.zoomSliderYPosition = this.mouseCoords.y -17;
    //	        ni.style.top = this.zoomSliderYPosition  + 'px';
    //	        ni2.style.top = this.zoomSliderYPosition  + 'px';
    //	    }
    //    },

    /**
    * Called when the zoomslider is released. Zooms to the released level
    */
    releaseZoomSlider: function() {
        this.zoomSliderActive = false;
        newLevel = parseInt((this.zoomSliderYPosition - 145) / (130 / g_zoomLevels.length));
        if (newLevel < g_zoomLevels.length) {
            this.zoomToLevel(newLevel, true);
        }
    },


    /**
    * Disables or enables navigation.
    */
    allowNavigation: function(allow) {
        this.navigate = allow;
    },

    /**
    * Returns the last clicked coordinate
    */
    getClickedCoords: function() {
        return this.mouseClickedMapCoords;
    },
    // FIXME: use an array
    getClickedCoordsOld: function() {
        return this.mouseClickedMapCoordsOld;
    },

    /**
    * Returns a lat/lon value for a given pixel coordinate
    */
    getPixelLatLon: function(pixel) {
        var t_coordsperpixel = g_zoomLevels[zoomLevel] / 256;
        utm = { 'lon': (this.BBOXLEFT + (pixel.x * t_coordsperpixel)), 'lat': (this.BBOXTOP - (pixel.y * t_coordsperpixel)) };
        //latLon = UTMToLatLon(utm.y, utm.x);

        //return latLon;   
        return utm;
    },

    /**
    * Returns an object containing the center coordinate in UTM.
    */
    getCenterUTM: function() {
        easting = this.BBOXLEFT + (g_zoomLevels[zoomLevel] / 256) * this.width / 2;
        northing = this.BBOXTOP - (g_zoomLevels[zoomLevel] / 256) * this.height / 2;

        return { 'x': easting, 'y': northing };
    },

    getCenter: function() {
        var center = this.getCenterUTM();
        return UTMToLatLon(center.y, center.x, 33);
    },

    /**
    * Returns the current zoomlevel
    */
    getZoomLevel: function() {
        return zoomLevel;
    },

    /**
    * Returns an integer representing the distance in meters between two points in the map
    * TODO: return full decimal number, and do the rounding outside this function. 
    */
    getStraightLineDistance: function(points) {
        var t = 0.0;
        for (var i = 0; i < points.length - 1; i++) {
            var point1 = points[i];
            var point2 = points[i + 1];
            var distance = Math.sqrt((point2.x - point1.x) * (point2.x - point1.x) + (point1.y - point2.y) * (point1.y - point2.y));
            t += distance;
        }
        return roundit(t, 0);
    },
    /**
    * TODO: return full decimal number, and do the rounding outside this function.
    */
    getCircuit: function(points) {
        var t = 0.0;

        if (points.length > 2) {
            for (var i = 0; i < points.length - 1; i++) {
                var point1 = points[i];
                var point2 = points[i + 1];
                var distance = Math.sqrt((point2.x - point1.x) * (point2.x - point1.x) + (point1.y - point2.y) * (point1.y - point2.y));
                t += distance;
            }
        }

        if (points.length > 2) {
            var distance = Math.sqrt((points[points.length - 1].x - points[0].x) * (points[points.length - 1].x - points[0].x) + (points[0].y - points[points.length - 1].y) * (points[0].y - points[points.length - 1].y));
            t += distance;
        }

        return roundit(t, 0);
    },

    /**
    * TODO: return full decimal number, and do the rounding outside this function. 
    */
    getArea: function(points) {
        var t = 0.0;

        if (points.length > 2) {
            var numPoints = points.length;
            t = (points[points.length - 1].x * points[0].y) - (points[0].x * points[points.length - 1].y);
            for (var i = 0; i < numPoints - 1; i++) {
                t = t + (points[i].x * points[i + 1].y) - (points[i + 1].x * points[i].y);
            }
            t = t / 2;

        }
        if (t < 0) {
            t = -t;
        }

        return roundit(t, 0);
    },

    clearDistanceMarkers: function() {

        for (var i = 0; i < this.distanceMarkers.length; i++) {
            this.mouselayer.removeChild(this.distanceMarkersA[i]);
        }

        this.distanceMarkers = [];
        this.distanceMarkersA = [];
        //this._drawToolLine();
        //this.fillCoordinateBox();
        this.redrawMeasures();

    },

    getMeasureState: function() {
        return this.navigate;
    },

    getState: function() {
        return this.state;
    },

    setState: function(state) {
        if (state) {
            this.state = state;
            $('controllerNavigationPane').style.cursor = "default";
        }
        this.pointMove = !this.pointMove;
        this.navigate = !this.navigate;
        /*if(this.navigate == false)
        $('navigationMenu').style.display = "none";
        else
        $('navigationMenu').style.display = "block";
        */
        this.clearDistanceMarkers();
        if (this.navigate == true) {
            this.state = 'navigate';
            $('controllerNavigationPane').style.cursor = "move";
        }
        //this._drawToolLine();
    }
};

AJAXMAP.mousePressedHandler = function(e) {
	e = e ? e : window.event;
	// only grab on left-click
	var self = this.backingBean;
	if (e.button < 2) {
		//var self = this.backingBean;
		if  (!self.zoomSliderActive)    {
		    var coords = self.resolveCoordinates(e);
	        self.press(coords);
	        //self.toggleMenu(false); //Kommentert ut i forbindelse med 1881 (kaster exception)
	        //self.fillSideBar();
	        //self.fillCoordinateBox(); //Kommentert ut i forbindelse med 1881
	        return false;
		}
	}

    
	//if ( e.button == 2){
	//    self.toggleMenu(true);
	//}
	// NOTE: MANDATORY! must return false so event does not propagate to tilelayer!
	return false;
};

AJAXMAP.nocontextMenuhandler = function(e) {
    event.cancelBubble = true;
    event.returnValue = false;
    return false;
};

AJAXMAP.mouseReleasedHandler = function(e) {
	e = e ? e : window.event;
	var self = this.backingBean;
	if (self.pressed) {
		// OPTION: could decide to move map only on release, right here
		self.release(self.resolveCoordinates(e));
		self._positionTiles();
	}
	return false;
};

AJAXMAP.mouseUpHandler = function(e) {
    e = e ? e : window.event;
	var self = this.backingBean;
	
	if(self.zoomSliderActive){
	    self.releaseZoomSlider();
	    return;
	}
	if (self.pressed) {
		// OPTION: could decide to move map only on release, right here
		self.movemap(self.resolveCoordinates(e));
		self.release(self.resolveCoordinates(e));
		self.mouseClickedMapCoordsOld = self.mouseClickedMapCoords;
		self.mouseClickedMapCoords = self.mouseMapCoords;	
	}
	if (self.pointMove){
		//self.addDistanceMarker(self.getClickedCoords().y, self.getClickedCoords().x);
		//self._drawToolLine();
		//self.fillCoordinateBox();
	}
	return false;
};

AJAXMAP.mouseMovedHandler = function(e) {
	e = e ? e : window.event;
	var self = this.backingBean;
	if(this.toolTipTimer != null){
	    clearTimeout(this.toolTipTimer)
	}
	//this.toolTipTimer = setTimeout("map.fetchLoypeInfo()",2000);
	//self.mouseCoords = self.resolveCoordinates(e);
	
	//if(!self.zoomSliderActive){
	if(self.pressed && !self.pointMove){
	    self.moveCount++;
	    if (self.moveCount % AJAXMAP.MOVE_THROTTLE == 0) {
	        //self.mouseCoords = self.resolveCoordinates(e);
	        if(self.navigate){
	
		        self.movemap(self.resolveCoordinates(e));
		        return false;
		    }
	    }
	    return false;
	}
	else if(self.pointMove){ 
		    var t_coordsperpixel = g_zoomLevels[zoomLevel]/256;
	    self.mouseCoords = self.resolveCoordinates(e);
        self.mouseMapCoords = {'x' : (self.BBOXLEFT + (self.mouseCoords.x * t_coordsperpixel)), 'y' : (self.BBOXTOP - (self.mouseCoords.y * t_coordsperpixel)) };
	    //self.movePoint();    
	    return false;   
    }
	else{
	    var t_coordsperpixel = g_zoomLevels[zoomLevel]/256;
	    self.mouseCoords = self.resolveCoordinates(e);
	    self.mouseMapCoords = {'x' : (self.BBOXLEFT + (self.mouseCoords.x * t_coordsperpixel)), 'y' : (self.BBOXTOP - (self.mouseCoords.y * t_coordsperpixel)) };

        //self.setStatus("BBOXLEFT: " + self.BBOXLEFT + ', ' + "BBOXTOP: " + self.BBOXTOP + ', ' + (self.BBOXLEFT + (self.mouseCoords.x * t_coordsperpixel)) + ', ' + (self.BBOXTOP - (self.mouseCoords.y * t_coordsperpixel))+ ', ' + self.height + ', ' + self.width + ', MOUSECOORDSX: ' + self.mouseCoords.x + ', ' + self.mouseCoords.y );

        }
   // }
    
//    if(self.zoomSliderActive){
//    	var t_coordsperpixel = g_zoomLevels[zoomLevel]/256;
//	    self.mouseCoords = self.resolveCoordinates(e);
//	    self.mouseMapCoords = {'x' : (self.BBOXLEFT + (self.mouseCoords.x * t_coordsperpixel)), 'y' : (self.BBOXTOP - (self.mouseCoords.y * t_coordsperpixel))};

//        //self.setStatus("BBOXLEFT: " + self.BBOXLEFT + ', ' + "BBOXTOP: " + self.BBOXTOP + ', ' + (self.BBOXLEFT + (self.mouseCoords.x * t_coordsperpixel)) + ', ' + (self.BBOXTOP - (self.mouseCoords.y * t_coordsperpixel))+ ', ' + self.height + ', ' + self.width + ', MOUSECOORDSX: ' + self.mouseCoords.x + ', ' + self.mouseCoords.y );

//        self.fixZoomSliderPosition();
//	    }
	    //self.fillSideBar();
	    //self.fillCoordinateBox();
	    return false;
};


AJAXMAP.zoomOutHandler = function(e) {
	e = e ? e : window.event;
	var self = this.parentNode.parentNode.backingBean;
	self.zoom(-1);
	return false;
};

AJAXMAP.WMSHandler = function(e) {
	e = e ? e : window.event;
	var self = this.parentNode.parentNode.backingBean;
	if(WMS == GEOMAT){
		WMS = NIB;
	}
	else{
		WMS = GEOMAT;
	}
	self._positionTiles();
	return false;
};

AJAXMAP.zoomIn2Handler = function(e) {
	e = e ? e : window.event;
	var self = this.parentNode.parentNode.backingBean;
	self.zoomIn(false);
	return false;
};

AJAXMAP.zoomOut2Handler = function(e) {
	e = e ? e : window.event;
	var self = this.parentNode.parentNode.backingBean;
	self.zoomOut(false);
	return false;
};

AJAXMAP.slideRightHandler = function(e) {
	e = e ? e : window.event;
	var self = this.parentNode.parentNode.backingBean;

	self.resetSlideMotion();
	self.slideRight();
	return false;
};

AJAXMAP.slideLeftHandler = function(e) {
	e = e ? e : window.event;
	var self = this.parentNode.parentNode.backingBean;
	self.resetSlideMotion();
	self.slideLeft();
	return false;
};

AJAXMAP.slideUpHandler = function(e) {
	e = e ? e : window.event;
	var self = this.parentNode.parentNode.backingBean;
	self.resetSlideMotion();
	self.slideUp();
	return false;
};

AJAXMAP.slideDownHandler = function(e) {
	e = e ? e : window.event;
	var self = this.parentNode.parentNode.backingBean;
	self.resetSlideMotion();
	self.slideDown();
	return false;
};

// FIXME: Double click disabled for now
AJAXMAP.doubleClickHandler = function(e) {
/*
	e = e ? e : window.event;
	var self = this.backingBean;
	coords = self.resolveCoordinates(e);
	self.resetSlideMotion();
	self._recenter(coords);
	*/
	return false;
};

/**
 * Handler for move events. 
 */
AJAXMAP.MoveEvent = function(x, y) {
	this.x = x;
	this.y = y;
};

/**
 * Handler for maximizeevent
 */
AJAXMAP.maximizeHandler = function(e) {
    var self = this.parentNode.parentNode.backingBean;
	if (self.maximized) {
		// HACK: remove auto-fit to window (this needs to be a function)
		self.border = -1;
		//document.body.style.padding = '10px';
		document.getElementById('header').style.display = 'block';
		document.getElementById('footer').style.display = 'block';
		document.getElementById('map').style.width = '800px';
		document.getElementById('map').style.height = '400px';
		self.height = 400;
		self.width = 800;
	}
	else {
		document.body.style.padding = '0';
		document.getElementById('header').style.display = 'none';
		document.getElementById('footer').style.display = 'none';
		// HACK allow auto-fit to window (this needs to be a function)
		self.border = 0;

		self.resize();
	}

	self.maximized = !self.maximized;
};

/**
 * Handle wheel events
 */
function handle(delta) {
	if (delta < 0){

		map.zoomOut(false);
		}
	else{
		map.zoomIn(true);
		}
		map.moveSlider();
}

/**
 * Handle wheel events
 */
function wheel(event){
	var delta = 0;
	if (!event){
	    event = window.event;
	}
	if (event.wheelDelta) {
		delta = event.wheelDelta/120;
		if (window.opera){
		    delta = -delta;
		}
	} else if (event.detail) {
		delta = -event.detail/3;
	}
	if (delta){
		handle(delta);
	}
    if (event.preventDefault){
        event.preventDefault();
    }
    event.returnValue = false;
}

/**
 * Returns the first element of a style class
 * FIXME: ugly. should return all elements
 */
function getElementByStyleClass (className) {
  var all = document.all ? document.all :
    document.getElementsByTagName('*');
  var elements = new Array();
  for (var e = 0; e < all.length; e++){
    if (all[e].className == className){
      elements[elements.length] = all[e];
      break;
      }
  }
  return elements[0];
}

function getElementTop(Elem) {
		if(document.getElementById) {	
			var elem = document.getElementById(Elem);
		} else if (document.all) {
			var elem = document.all[Elem];
		}
		yPos = elem.offsetTop;
		tempEl = elem.offsetParent;
		while (tempEl != null) {
  			yPos += tempEl.offsetTop;
	  		tempEl = tempEl.offsetParent;
  		}
		return yPos;
}

/**
 * Converts from latitude/ longitude decimal degrees to UTM coordinates.
 * returns object {'x': UTMEasting,'y':UTMNorthing}
 */
function decimalDegreesToUTM(coords) {
    var Long = coords.x;
    var Lat  = coords.y;

    var PI = 3.14159265;
    var FOURTHPI = PI / 4;
    var deg2rad = PI / 180;
    var rad2deg = 180.0 / PI;

    var a = 6378137;
    var eccSquared = 0.00669438;
    var k0 = 0.9996;
    var LongOrigin;
    var eccPrimeSquared;
    var N;
    var T;
    var C;
    var A;
    var M;

    //Make sure the longitude is between -180.00 .. 179.9
    var LongTemp = (Long + 180) - parseInt((Long + 180) / 360) * 360 - 180; // -180.00 .. 179.9;
    var LatRad = Lat * deg2rad;
    var LongRad = LongTemp * deg2rad;
    var LongOriginRad;
    var ZoneNumber; //cast to integer
    ZoneNumber = parseInt((LongTemp + 180) / 6) + 1;

    //if (Lat >= 56.0 && Lat < 64.0 && LongTemp >= 3.0 && LongTemp < 12.0)
    ZoneNumber = 33; //should be set dynamically, but set to 33 as our wms server only uses that

    LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3;  //+3 puts origin in middle of zone
    LongOriginRad = LongOrigin * deg2rad;

    eccPrimeSquared = (eccSquared) / (1 - eccSquared);

    N = a / Math.sqrt(1 - eccSquared * Math.sin(LatRad) * Math.sin(LatRad));
    T = Math.tan(LatRad) * Math.tan(LatRad);
    C = eccPrimeSquared * Math.cos(LatRad) * Math.cos(LatRad);
    A = Math.cos(LatRad) * (LongRad - LongOriginRad);

    M = a * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * LatRad
        - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(2 * LatRad)
        + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(4 * LatRad)
        - (35 * eccSquared * eccSquared * eccSquared / 3072) * Math.sin(6 * LatRad));

    var UTMEasting = (k0 * N * (A + (1 - T + C) * A * A * A / 6
        + (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120)
        + 500000.0);

    var UTMNorthing = (k0 * (M + N * Math.tan(LatRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24
        + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720)));

    return {'x': UTMEasting,'y':UTMNorthing};
}

/**
 * Converts UTM coordinates to latitude/ longitude coordinates.
 * returns object {'lat' : Lat, 'lon' : Long}
 */
function UTMToLatLon(UTMNorthing, UTMEasting, sone) {
    var PI = 3.14159265;
    var FOURTHPI = PI / 4;
    var deg2rad = PI / 180;
    var rad2deg = 180.0 / PI;
    
	var k0 = 0.9996;
	var a = 6378137;
	var eccSquared = 0.00669438;
	var eccPrimeSquared;
	var e1 = (1-Math.sqrt(1-eccSquared))/(1+Math.sqrt(1-eccSquared));
	var N1, T1, C1, R1, D, M;
	var LongOrigin;
	var mu, phi1, phi1Rad;
	var x, y;
	var ZoneNumber = (typeof sone != "undefined") ? sone : 33;
	var NorthernHemisphere; //1 for northern hemispher, 0 for southern

	x = UTMEasting - 500000.0; //remove 500,000 meter offset for longitude
	y = UTMNorthing;

	if(ZoneNumber >= 0){
		NorthernHemisphere = 1;//point is in northern hemisphere
	}
	else
	{
		NorthernHemisphere = 0;//point is in southern hemisphere
		y -= 10000000.0;//remove 10,000,000 meter offset used for southern hemisphere
	}

	LongOrigin = (ZoneNumber - 1)*6 - 180 + 3;  //+3 puts origin in middle of zone

	eccPrimeSquared = (eccSquared)/(1-eccSquared);

	M = y / k0;
	mu = M/(a*(1-eccSquared/4-3*eccSquared*eccSquared/64-5*eccSquared*eccSquared*eccSquared/256));

	phi1Rad = mu + (3*e1/2-27*e1*e1*e1/32)*Math.sin(2*mu) 
				+ (21*e1*e1/16-55*e1*e1*e1*e1/32)*Math.sin(4*mu)
				+(151*e1*e1*e1/96)*Math.sin(6*mu);
	phi1 = phi1Rad*rad2deg;

	N1 = a/Math.sqrt(1-eccSquared*Math.sin(phi1Rad)*Math.sin(phi1Rad));
	T1 = Math.tan(phi1Rad)*Math.tan(phi1Rad);
	C1 = eccPrimeSquared*Math.cos(phi1Rad)*Math.cos(phi1Rad);
	R1 = a*(1-eccSquared)/Math.pow(1-eccSquared*Math.sin(phi1Rad)*Math.sin(phi1Rad), 1.5);
	D = x/(N1*k0);

	Lat = phi1Rad - (N1*Math.tan(phi1Rad)/R1)*(D*D/2-(5+3*T1+10*C1-4*C1*C1-9*eccPrimeSquared)*D*D*D*D/24
					+(61+90*T1+298*C1+45*T1*T1-252*eccPrimeSquared-3*C1*C1)*D*D*D*D*D*D/720);
	Lat = Lat * rad2deg;

	Long = (D-(1+2*T1+C1)*D*D*D/6+(5-2*C1+28*T1-3*C1*C1+8*eccPrimeSquared+24*T1*T1)
					*D*D*D*D*D/120)/Math.cos(phi1Rad);
	Long = LongOrigin + Long * rad2deg;
	
	return({'lat' : Lat, 'lon' : Long});
}

function roundit(Num, Places) {
   if (Places > 0) {
      if ((Num.toString().length - Num.toString().lastIndexOf('.')) > (Places + 1)) {
         var Rounder = Math.pow(10, Places);
         return Math.round(Num * Rounder) / Rounder;
      }
      else return Num;
   }
   else return Math.round(Num);
}

function WAPICanvas(){
    // The canvas element and associated styles
    var t_newdiv = document.createElement('canvas');
    t_newdiv.setAttribute('width',100);
    t_newdiv.setAttribute('height',100);
    t_newdiv.style.position = "absolute";
    t_newdiv.style.top = "0px";
    t_newdiv.style.left = "0px";
    t_newdiv.style.width = "100%";
    t_newdiv.style.height = "100%";
    t_newdiv.style.zindex = 1000;

    this.element = t_newdiv;
    this.surface = null; // The wrapped canvas
    this.lines = []; // PolyLines
    this.parent = null; // WAPIMap parent
    this.t_clipMin = {'X':0,'Y':0};
    this.t_clipMax = {'X':200,'Y':200};

    //Event.observe(document, 'map:resized', this.redraw.bindAsEventListener(this));
    //Event.observe(document, 'map:moved', this.redraw.bindAsEventListener(this));
    //Event.observe(document, 'map:zoomed', this.redraw.bindAsEventListener(this));
}

WAPICanvas.prototype = {
    addPolyLine : function(t_polyline){
        this.lines.push(t_polyline);
        this.redraw();
    },
    
    redraw : function(){
        this.surface.clearRect(0,0,this.element.width,this.element.height);
       	this.t_clipMin = {'X':0,'Y':0};
        this.t_clipMax = {'X':this.parent.getWidth(),'Y':this.parent.getHeight()};
        
        for(var i = 0; i < this.lines.length; i++){
            this.surface.beginPath();
        	this.surface.strokeStyle = this.lines[i].rgba;
		    this.surface.lineWidth = this.lines[i].lineWidth;
		    this.surface.lineCap = 'round';
		    
		    var t_tmpPoints = [];
		    for(var j = 0; j < this.lines[i].coordinates.length; j++){
               var t_SC = this.parent.geoToScreen(this.lines[i].coordinates[j]);   
               t_tmpPoints.push(t_SC);
            }
            
            for(var j = 0; j < t_tmpPoints.length; j++){
            
                if(j != t_tmpPoints.length-1){
                    var t_SC = t_tmpPoints[j];
                    var t_SC2 = t_tmpPoints[j+1];
                   
                    var lineSegment = {'Start' : {'X':parseInt(t_SC.x),'Y' :parseInt(t_SC.y)}, 'End' : {'X':parseInt(t_SC2.x), 'Y':parseInt(t_SC2.y)}};
                    lineSegment.Dy = lineSegment.End.Y - lineSegment.Start.Y;
                    lineSegment.Dx = lineSegment.End.X - lineSegment.Start.X;   
                    var intersects = this.clipLine(lineSegment);

                    if(intersects == true){
                        this.surface.moveTo(lineSegment.Start.X, lineSegment.Start.Y);
                        this.surface.lineTo(lineSegment.End.X, lineSegment.End.Y);
                    }
                }
            }
            this.surface.stroke();    
        }
    },
    
    clear : function(){
        this.surface.clearRect(0,0,this.element.width,this.element.height);
        this.lines = [];
    },
    
    clipStartTop : function(line) {
        line.Start.X += line.Dx * (this.t_clipMin.Y - line.Start.Y) / line.Dy;
        line.Start.Y = this.t_clipMin.Y;
    },
 
    clipStartBottom : function(line) {
        line.Start.X += line.Dx * (this.t_clipMax.Y - line.Start.Y) / line.Dy;
        line.Start.Y = this.t_clipMax.Y;
    },
 
    clipStartRight : function(line) {
        line.Start.Y += line.Dy * (this.t_clipMax.X - line.Start.X) / line.Dx;
        line.Start.X = this.t_clipMax.X;
    },
 
    clipStartLeft : function(line) {
        line.Start.Y += line.Dy * (this.t_clipMin.X - line.Start.X) / line.Dx;
        line.Start.X = this.t_clipMin.X;
    },
 
    clipEndTop : function(line) {
        line.End.X += line.Dx * (this.t_clipMin.Y - line.End.Y) / line.Dy;
        line.End.Y = this.t_clipMin.Y;
    },
 
    clipEndBottom : function(line) {
        line.End.X += line.Dx * (this.t_clipMax.Y - line.End.Y) / line.Dy;
        line.End.Y = this.t_clipMax.Y;
    },
 
    clipEndRight : function(line) {
        line.End.Y += line.Dy * (this.t_clipMax.X - line.End.X) / line.Dx;
        line.End.X = this.t_clipMax.X;
    },
 
    clipEndLeft : function(line) {
        line.End.Y += line.Dy * (this.t_clipMin.X - line.End.X) / line.Dx;
        line.End.X = this.t_clipMin.X;
    },
    
	clipLine : function(line)
	{
	    var lineCode = 0;
	    
        if (line.End.Y < this.t_clipMin.Y) lineCode += 8;
        else if (line.End.Y > this.t_clipMax.Y) lineCode += 4;
 
        if (line.End.X > this.t_clipMax.X) lineCode += 2;
        else if (line.End.X < this.t_clipMin.X) lineCode += 1;
 
        if (line.Start.Y < this.t_clipMin.Y) lineCode += 128;
        else if (line.Start.Y > this.t_clipMax.Y) lineCode += 64;
 
        if (line.Start.X > this.t_clipMax.X) lineCode += 32;
        else if (line.Start.X < this.t_clipMin.X) lineCode += 16;
        
        //alert(lineCode);
        //alert(line.Start.X);
        //alert(line.Start.Y);
        //num = parseInt("0x0A",16);
        //aler(num);
        // 9 - 8 - A
        // |   |   |
        // 1 - 0 - 2
        // |   |   |
        // 5 - 4 - 6
        switch (lineCode) {
            // center
            case 0:
                return true;
 
            case 1:
                this.clipEndLeft(line);
                return true;
 
            case 2:
                this.clipEndRight(line);
                return true;
 
            case 4:
                this.clipEndBottom(line);
                return true;
 
            case 5:
                this.clipEndLeft(line);
                if (line.End.Y > this.t_clipMax.Y) this.clipEndBottom(line);
                return true;
 
            case 6:
                this.clipEndRight(line);
                if (line.End.Y > this.t_clipMax.Y) this.clipEndBottom(line);
                return true;
 
            case 8:
                this.clipEndTop(line);
                return true;
 
            case 9:
                this.clipEndLeft(line);
                if (line.End.Y < this.t_clipMin.Y) this.clipEndTop(line);
                return true;
 
            case 10:
                this.clipEndRight(line);
                if (line.End.Y < this.t_clipMin.Y) this.clipEndTop(line);
                return true;
 
            // left
            case 16:
                this.clipStartLeft(line);
                return true;
 
            case 18:
                this.clipStartLeft(line);
                this.clipEndRight(line);
                return true;
 
            case 20:
                this.clipStartLeft(line);
                if (line.Start.Y > this.t_clipMax.Y) return false;
                this.clipEndBottom(line);
                return true;
 
            case 22:
                this.clipStartLeft(line);
                if (line.Start.Y > this.t_clipMax.Y) return false;
                this.clipEndBottom(line);
                if (line.End.X > this.t_clipMax.X) this.clipEndRight(line);
                return true;
 
            case 24:
                this.clipStartLeft(line);
                if (line.Start.Y < this.t_clipMin.Y) return false;
                this.clipEndTop(line);
                return true;
 
            case 26:
                this.clipStartLeft(line);
                if (line.Start.Y < this.t_clipMin.Y) return false;
                this.clipEndTop(line);
                if (line.End.X > this.t_clipMax.X) this.clipEndRight(line);
                return true;
 
            // right
            case 32:
                this.clipStartRight(line);
                return true;
 
            case 33:
                this.clipStartRight(line);
                this.clipEndLeft(line);
                return true;
 
            case 36:
                this.clipStartRight(line);
                if (line.Start.Y > this.t_clipMax.Y) return false;
                this.clipEndBottom(line);
                return true;
 
            case 37:
                this.clipStartRight(line);
                if (line.Start.Y > this.t_clipMax.Y) return false;
                this.clipEndBottom(line);
                if (line.End.X < this.t_clipMin.X) this.clipEndLeft(line);
                return true;
 
            case 40:
                this.clipStartRight(line);
                if (line.Start.Y < this.t_clipMin.Y) return false;
                this.clipEndTop(line);
                return true;
 
            case 41:
                this.clipStartRight(line);
                if (line.Start.Y < this.t_clipMin.Y) return false;
                this.clipEndTop(line);
                if (line.End.X < this.t_clipMin.X) this.clipEndLeft(line);
                return true;
 
            // bottom
            case 64:
                this.clipStartBottom(line);
                return true;
 
            case 65:
                this.clipStartBottom(line);
                if (line.Start.X < this.t_clipMin.X) return false;
                this.clipEndLeft(line);
                if (line.End.Y > this.t_clipMax.Y) this.clipEndBottom(line);
                return true;
 
            case 66:
                this.clipStartBottom(line);
                if (line.Start.X > this.t_clipMax.X) return false;
                this.clipEndRight(line);
                return true;
 
            case 72:
                this.clipStartBottom(line);
                this.clipEndTop(line);
                return true;
 
            case 73:
                this.clipStartBottom(line);
                if (line.Start.X < this.t_clipMin.X) return false;
                this.clipEndLeft(line);
                if (line.End.Y < this.t_clipMin.Y) this.clipEndTop(line);
                return true;
 
            case 74:
                this.clipStartBottom(line);
                if (line.Start.X > this.t_clipMax.X) return false;
                this.clipEndRight(line);
                if (line.End.Y < this.t_clipMin.Y) this.clipEndTop(line);
                return true;
 
            // bottom-left
            case 80:
                this.clipStartLeft(line);
                if (line.Start.Y > this.t_clipMax.Y) this.clipStartBottom(line);
                return true;
 
            case 82:
                this.clipEndRight(line);
                if (line.End.Y > this.t_clipMax.Y) return false;
                this.clipStartBottom(line);
                if (line.Start.X < this.t_clipMin.X) this.clipStartLeft(line);
                return true;
 
            case 88:
                this.clipEndTop(line);
                if (line.End.X < this.t_clipMin.X) return false;
                this.clipStartBottom(line);
                if (line.Start.X < this.t_clipMin.X) this.clipStartLeft(line);
                return true;
 
            case 90:
                this.clipStartLeft(line);
                if (line.Start.Y < this.t_clipMin.Y) return false;
                this.clipEndRight(line);
                if (line.End.Y > this.t_clipMax.Y) return false;
                if (line.Start.Y > this.t_clipMax.Y) this.clipStartBottom(line);
                if (line.End.Y < this.t_clipMin.Y) this.clipEndTop(line);
                return true;
 
            // bottom-right
            case 96:
                this.clipStartRight(line);
                if (line.Start.Y > this.t_clipMax.Y) this.clipStartBottom(line);
                return true;
 
            case 97:
                this.clipEndLeft(line);
                if (line.End.Y > this.t_clipMax.Y) return false;
                this.clipStartBottom(line);
                if (line.Start.X > this.t_clipMax.X) this.clipStartRight(line);
                return true;
 
            case 104:
                this.clipEndTop(line);
                if (line.End.X > this.t_clipMax.X) return false;
                this.clipStartRight(line);
                if (line.Start.Y > this.t_clipMax.Y) this.clipStartBottom(line);
                return true;
 
            case 105:
                this.clipEndLeft(line);
                if (line.End.Y > this.t_clipMax.Y) return false;
                this.clipStartRight(line);
                if (line.Start.Y < this.t_clipMin.Y) return false;
                if (line.End.Y < this.t_clipMin.Y) this.clipEndTop(line);
                if (line.Start.Y > this.t_clipMax.Y) this.clipStartBottom(line);
                return true;
 
            // top
            case 128:
                this.clipStartTop(line);
                return true;
 
            case 129:
                this.clipStartTop(line);
                if (line.Start.X < this.t_clipMin.X) return false;
                this.clipEndLeft(line);
                return true;
 
            case 130:
                this.clipStartTop(line);
                if (line.Start.X > this.t_clipMax.X) return false;
                this.clipEndRight(line);
                return true;
 
            case 132:
                this.clipStartTop(line);
                this.clipEndBottom(line);
                return true;
 
            case 133:
                this.clipStartTop(line);
                if (line.Start.X < this.t_clipMin.X) return false;
                this.clipEndLeft(line);
                if (line.End.Y > this.t_clipMax.Y) this.clipEndBottom(line);
                return true;
 
            case 134:
                this.clipStartTop(line);
                if (line.Start.X > this.t_clipMax.X) return false;
                this.clipEndRight(line);
                if (line.End.Y > this.t_clipMax.Y) this.clipEndBottom(line);
                return true;
 
            // top-left
            case 144:
                this.clipStartLeft(line);
                if (line.Start.Y < this.t_clipMin.Y) this.clipStartTop(line);
                return true;
 
            case 146:
                this.clipEndRight(line);
                if (line.End.Y < this.t_clipMin.Y) return false;
                this.clipStartTop(line);
                if (line.Start.X < this.t_clipMin.X) this.clipStartLeft(line);
                return true;
 
            case 148:
                this.clipEndBottom(line);
                if (line.End.X < this.t_clipMin.X) return false;
                this.clipStartLeft(line);
                if (line.Start.Y < this.t_clipMin.Y) this.clipStartTop(line);
                return true;
 
            case 150:
                this.clipStartLeft(line);
                if (line.Start.Y > this.t_clipMax.Y) return false;
                this.clipEndRight(line);
                if (line.End.Y < this.t_clipMin.Y) return false;
                if (line.Start.Y < this.t_clipMin.Y) this.clipStartTop(line);
                if (line.End.Y > this.t_clipMax.Y) this.clipEndBottom(line);
                return true;
 
            // top-right
            case 160:
                this.clipStartRight(line);
                if (line.Start.Y < this.t_clipMin.Y) this.clipStartTop(line);
                return true;
 
            case 161:
                this.clipEndLeft(line);
                if (line.End.Y < this.t_clipMin.Y) return false;
                this.clipStartTop(line);
                if (line.Start.X > this.t_clipMax.X) this.clipStartRight(line);
                return true;
 
            case 164:
                this.clipEndBottom(line);
                if (line.End.X > this.t_clipMax.X) return false;
                this.clipStartRight(line);
                if (line.Start.Y < this.t_clipMin.Y) this.clipStartTop(line);
                return true;
 
            case 165:
                this.clipEndLeft(line);
                if (line.End.Y < this.t_clipMin.Y) return false;
                this.clipStartRight(line);
                if (line.Start.Y > this.t_clipMax.Y) return false;
                if (line.End.Y > this.t_clipMax.Y) this.clipEndBottom(line);
                if (line.Start.Y < this.t_clipMin.Y) this.clipStartTop(line);
                return true;
        }
 
        return false;
    }

};

function PolyLine(t_coords, t_options){
    this.coordinates = t_coords ? t_coords : [];
    if(t_options){
        this.rgba = t_options.rgba ? t_options.rgba : "rgba(0,0,0,1.0)";
        this.lineWidth = t_options.lineWidth ? t_options.lineWidth : 2;
    }else{
        this.rgba = "rgba(0,0,0,1.0)";
        this.lineWidth = 2;    
    }
}

PolyLine.prototype = {
    addPoint : function(t_coord){
        this.coordinates.push(t_coord);
    }
};

function Coordinate(t_x, t_y, t_srs){
    this.x = t_x;
    this.y = t_y;
    this.srs = t_srs ? t_srs : 'EPSG:32633';
}
Coordinate.prototype = {
      
};

