var map;
var overlayTable = {};
var timerID = 0;
var redrawTimerID = 0;
var redrawDetailsTimerID = 0;
var amShowingDetails = 0;
var views = new Array();
var prevCloud = "";
var nextRedrawTimeout = 300;
var nextDetailsRedrawTimeout = 300;
var arrowHeight = 14;
var arrowX1 = 10;
var arrowX2 = 32;
var detailsHeight = 16;
var offsetRadius = 2;
var lineWidth = 2;
var content_container_;
var detailsGradeApplied_ = -2;
var shadediv_;
var linediv_;
var centergraydiv_;
var centerdiv_;
var detailsdiv_;
var map_canvas_;
var mapshadediv_;
var nextZoomIndex_ = 0;
var topRect_ = 0;
var currentPage_ = 1;
var extraArgs_ = "";
var callback_;
var centerDetails = 0;
var amMovingMap = 0;
var sortOrder_ = 'timestamp';
var detailsCache = { };
var selectedElement_;
var selectedID_;
var initialMinimized_ = false;
var xmlRequest;
var xmlRequestShowURL;
var stopCalled = false;

var shadeStyle = {'gradient-start-color': 0xCCCCCC,
	              'gradient-end-color': 0xCCCCCC,
	              'border-radius': 6};
var lineStyle = {'gradient-start-color': 0x9F9F9F,
	              'gradient-end-color': 0x9F9F9F,
	              'border-radius': 6};
var centerGrayStyle = {'gradient-start-color': 0xCCCCCC,
	              'gradient-end-color': 0xCCCCCC,
	              'border-radius': 6};
var centerStyle = {'gradient-start-color': 0xFFFFFF,
	              'gradient-end-color': 0xFFFFFF,
	              'border-radius': 6};
var centerSelectedStyle = {'gradient-start-color': 0xddeff6,
	              'gradient-end-color': 0xddeff6,
	              'border-radius': 6};

var loadPageName_ = '';
var autoLoad_ = false;
var useDetailsURL_ = false;

function createDiv(className) {
	var div = document.createElement("div");
	div.className = className;
	div.style.position = "absolute";
	
	return div;
}	

function observeEvent(element, name, observer, useCapture) {
    if (!this.observers) this.observers = [];
    if (element.addEventListener) {
      element.addEventListener(name, observer, useCapture);
    } else if (element.attachEvent) {
      element.attachEvent('on' + name, observer);
    }
}

function stopObservingEvent(element, name, observer, useCapture) {
    element = $(element);
    useCapture = useCapture || false;

    if (element.removeEventListener) {
      element.removeEventListener(name, observer, useCapture);
    } else if (element.detachEvent) {
      try {
        element.detachEvent('on' + name, observer);
      } catch (e) {}
    }
}

function Region(position, position1, id) {
  this.position_ = position;
  this.position1_ = position1;
  this.anchor_ = '4';
  this.id_ = id;
}

Region.prototype = new GOverlay();

// Creates the DIV representing this rectangle.
Region.prototype.initialize = function(map) {
	// Create the DIV representing our rectangle
	var div = createDiv("");
	div.innerHTML = '<div style="width:100%; height:100%" class="region transp40"></div>';
	this.div_ = div;

	// Our rectangle is flat against the map, so we add our selves to the
	// MAP_PANE pane, which is at the same z-index as the map itself (i.e.,
	// below the marker shadows)
	map.getPane(G_MAP_MAP_PANE).appendChild(this.div_);
}

// Remove the main DIV from the map pane
Region.prototype.remove = function() {
	this.div_.parentNode.removeChild(this.div_);
}

// Copy our data to a new Rectangle
Region.prototype.copy = function() {
    return new Region(this.position_, this.position1_, this.id_);
}

// Redraw the rectangle based on the current projection and zoom level
Region.prototype.redraw = function(force) {
	// We only need to redraw if the coordinate system has changed
	if (!force) return;
	
	setLocation(this);
}

Region.prototype.minimize = function(state) {
}

function Rectangle(position, width, height, content, anchor, cssClass, detailsUrl, id, parameterName) {
  this.position_ = position;
  this.width_ = width;
  this.height_ = height;
  this.content_ = content;
  this.anchor_ = anchor;
  this.cssClass_ = cssClass;
  this.gradeApplied_ = -1;
  this.detailsUrl_ = detailsUrl;
  this.oldX_ = 0;
  this.oldY_ = 0;
  this.id_ = id;
  this.parameterName_ = parameterName;
  this.minimized_ = initialMinimized_;
}

Rectangle.prototype = new GOverlay();

// Creates the DIV representing this rectangle.
Rectangle.prototype.initialize = function(map) {
	// Create the DIV representing our rectangle
	var div = createDiv("");
	div.innerHTML = this.content_
	if (div.firstChild) {
	    div.firstChild.style.paddingBottom = '3px';
    }
	this.div_ = div;
		
	if (this.width_ < 0) div.style.minWidth = (-this.width_) + "px";
	if (this.height_ < 0) div.style.minHeight = (-this.height_) + "px";

	this.shadediv_ = createDiv("transp60");
	this.linediv_ = createDiv("");
	this.centergraydiv_ = createDiv("");
	this.centerdiv_ = createDiv("");
	this.shadearrowdiv_ = createDiv("transp60");
	this.arrowdiv_ = createDiv("");
	this.detailsdiv_ = createDiv("");
	this.minimizedDisplay_ = createDiv("");
	
	this.minimizedDisplay_.innerHTML = '<img src="' + getIconName(this.parameterName_) + '" onclick="bringForward(event);" style="cursor: pointer"/>';
	var url = 'javascript:showID(\'' + this.id_ + 'details\');';
	var minimizeLink = '';
	if (useDetailsURL_) {
	    url = 'javascript:showURL(\'' + this.detailsUrl_ + '\');';
	}
	else {
	    minimizeLink = '<a style="color: #666666; float: right" href="javascript:minimizeID(\'' + this.id_ + '\')"><img style="border:none; margin-right: 4px;" src="images/minimize.png" title="Minimize"/></a>'
	}
    this.detailsdiv_.innerHTML = '<div class="minisnippet" style="width: 100%; margin-top: 3px; line-height: 100%">' + minimizeLink + '&nbsp;<a style="color: #666666;" href="' + url + '"><img style="border:none" src="images/showdetailicon.png"/>&nbsp;</a><a class="minisnippet" style="color: #666666;" href="' + url + '">Details</a></div>';
	    
	this.detailsdiv_.style.backgroundColor='#CCCCCC';

	this.jgs_ = new jsGraphics(this.shadearrowdiv_);		
	this.jg_ = new jsGraphics(this.arrowdiv_);		
	
	this.gradeApplied_ = -1;
	
    this.add();
}    	

Rectangle.prototype.add = function() {
    var pane = map.getPane(G_MAP_MAP_PANE);
    if (this.minimized_) {
        pane.appendChild(this.minimizedDisplay_);
    }
    else {
	    // Our rectangle is flat against the map, so we add our selves to the
	    // MAP_PANE pane, which is at the same z-index as the map itself (i.e.,
	    // below the marker shadows)
	    pane.appendChild(this.shadediv_);
	    pane.appendChild(this.linediv_);
	    pane.appendChild(this.centergraydiv_);
	    pane.appendChild(this.centerdiv_);
	    pane.appendChild(this.shadearrowdiv_);
	    pane.appendChild(this.arrowdiv_);
	    pane.appendChild(this.detailsdiv_);
	    pane.appendChild(this.div_);
	}
}

// Remove the main DIV from the map pane
Rectangle.prototype.remove = function() {
    if (this.minimized_) {
        this.minimizedDisplay_.parentNode.removeChild(this.minimizedDisplay_);
    }
    else {
	    this.div_.parentNode.removeChild(this.div_);
	    this.shadediv_.parentNode.removeChild(this.shadediv_);
	    this.linediv_.parentNode.removeChild(this.linediv_);
	    this.centergraydiv_.parentNode.removeChild(this.centergraydiv_);
	    this.centerdiv_.parentNode.removeChild(this.centerdiv_);
	    this.shadearrowdiv_.parentNode.removeChild(this.shadearrowdiv_);
	    this.arrowdiv_.parentNode.removeChild(this.arrowdiv_);
	    this.detailsdiv_.parentNode.removeChild(this.detailsdiv_);
	}
}

// Copy our data to a new Rectangle
Rectangle.prototype.copy = function() {
    return new Rectangle(this.position_, this.width_, this.heigth_, this.content_, this.anchor_, this.cssClass_, this.detailsUrl_ ,this.id_, this.parameterName_);
}

// Redraw the rectangle based on the current projection and zoom level
Rectangle.prototype.redraw = function(force) {
	// We only need to redraw if the coordinate system has changed
	if (!force) return;
	
	setLocation(this);
}

Rectangle.prototype.minimize = function(state) {
    if (this.minimized_ != state) {
        this.remove();
        this.minimized_ = state;
        this.add();
        setLocation(this);
    }
}

function setLocation(rect) {
    // Calculate the DIV coordinates of two opposite corners of our bounds to
    // get the size and position of our rectangle
    var c1 = map.fromLatLngToDivPixel(rect.position_);
    
    if (rect.minimized_) {
        rect.minimizedDisplay_.style.left = (c1.x - getIconOffsetX(rect.parameterName_)) + "px";
        rect.minimizedDisplay_.style.top = (c1.y - getIconOffsetY(rect.parameterName_)) + "px";
    }
    else {
	    var left = 0
	    var top = 0
	    var markerleft = 0
	    var markertop = 0
        switch (parseInt(rect.anchor_)) {
            case 4:
		        rect.div_.style.left = c1.x + "px";
		        rect.div_.style.top = c1.y + "px";
                var c2 = map.fromLatLngToDivPixel(rect.position1_);
                rect.div_.style.width = (c2.x - c1.x) + "px";
                rect.div_.style.height = (c2.y - c1.y) + "px";
                return;
                
	        case 0:
                markerleft = c1.x;
                markertop = c1.y;
                
		        left = c1.x + offsetRadius + lineWidth;
		        top = c1.y + arrowHeight + offsetRadius + lineWidth - 1;
		        break;
	        case 1:
		        markerleft = c1.x - 40;
		        markertop = c1.y;

		        left = c1.x - rect.div_.clientWidth - offsetRadius - lineWidth;
		        top = c1.y + arrowHeight + offsetRadius + lineWidth - 1;
		        break;
	        case 2:
		        markerleft = c1.x - 40;
		        markertop = c1.y - arrowHeight;

		        left = c1.x - rect.div_.clientWidth - offsetRadius - lineWidth;
		        top = c1.y - rect.div_.clientHeight - arrowHeight - offsetRadius - detailsHeight;
		        break;
	        case 3:
		        markerleft = c1.x;
		        markertop = c1.y - arrowHeight;

		        left = c1.x + offsetRadius + lineWidth;
		        top = c1.y - rect.div_.clientHeight - arrowHeight - offsetRadius - detailsHeight;
		        break;
        }

  	    if ((rect.gradeApplied_ != (rect.div_.clientWidth * rect.div_.clientHeight)) || (left != rect.oldX_) || (top != rect.oldY_)) {
  		    width = rect.div_.clientWidth;
  		    height = rect.div_.clientHeight;
      		
  		    rect.oldX_ = left;
  		    rect.oldY_ = top;

		    rect.div_.style.left = left + "px";
		    rect.div_.style.top = top + "px";
    	
	        rect.shadediv_.style.left = (left - offsetRadius - lineWidth + 4) + "px";
	        rect.shadediv_.style.top = (top - offsetRadius - lineWidth + 4) + "px";
	        rect.shadediv_.style.width = (width + (offsetRadius * 2) + (lineWidth*2)) + "px";
	        rect.shadediv_.style.height = (height + (offsetRadius * 2) + (lineWidth*2) + detailsHeight) + "px";
    	
	        rect.linediv_.style.left = (left - offsetRadius - lineWidth) + "px";
	        rect.linediv_.style.top = (top - offsetRadius - lineWidth) + "px";
	        rect.linediv_.style.width = (width + (offsetRadius * 2) + (lineWidth*2)) + "px";
	        rect.linediv_.style.height = (height + (offsetRadius * 2) + (lineWidth*2) + detailsHeight) + "px";
    	
	        rect.centergraydiv_.style.left = (left - offsetRadius) + "px";
	        rect.centergraydiv_.style.top = (top - offsetRadius) + "px";
	        rect.centergraydiv_.style.width = (width + (offsetRadius * 2)) + "px";
	        rect.centergraydiv_.style.height = (height + (offsetRadius * 2) + detailsHeight) + "px";
    	
	        rect.centerdiv_.style.left = (left - offsetRadius) + "px";
	        rect.centerdiv_.style.top = (top - offsetRadius) + "px";
	        rect.centerdiv_.style.width = (width + (offsetRadius * 2)) + "px";
	        rect.centerdiv_.style.height = (height + (offsetRadius * 2) + detailsHeight - 10) + "px";
    	
	        rect.detailsdiv_.style.left = (left - offsetRadius) + "px";
	        rect.detailsdiv_.style.top = (top + height) + "px";
	        rect.detailsdiv_.style.width = (width + (offsetRadius * 2)) + "px";
	        rect.detailsdiv_.style.height = detailsHeight + "px";
    	
	        rect.arrowdiv_.style.left = (markerleft) + "px";
	        rect.arrowdiv_.style.top = (markertop) + "px";
	        rect.arrowdiv_.style.width = 40 + "px";
	        rect.arrowdiv_.style.height = 40 + "px";
    	
	        rect.shadearrowdiv_.style.left = (markerleft + 4) + "px";
	        rect.shadearrowdiv_.style.top = (markertop + 4) + "px";
	        rect.shadearrowdiv_.style.width = 40 + "px";
	        rect.shadearrowdiv_.style.height = 40 + "px";
    	
	  	    if (rect.gradeApplied_ != (rect.div_.clientWidth * rect.div_.clientHeight)) {
	  	        OSGradient.removeGradient(rect.shadediv_);
	  	        OSGradient.removeGradient(rect.linediv_);
	  	        OSGradient.removeGradient(rect.centergraydiv_);
	  	        OSGradient.removeGradient(rect.centerdiv_);
	  	        rect.gradeApplied_ = rect.div_.clientWidth * rect.div_.clientHeight;
    	
	            OSGradient.applyGradient(shadeStyle, rect.shadediv_);
	            OSGradient.applyGradient(lineStyle, rect.linediv_);
	            OSGradient.applyGradient(centerGrayStyle, rect.centergraydiv_);
	            OSGradient.applyGradient(centerStyle, rect.centerdiv_);
	        }
	    }
	}
}    	

function minimizeAll() {
	for (var n in overlayTable) {
		overlayTable[n].minimize(true);
	}
	initialMinimized_ = true;
}

function maximizeAll() {
	for (var n in overlayTable) {
		overlayTable[n].minimize(false);
	}
	initialMinimized_ = false;
}

function redrawAll() {
   	if (redrawTimerID) {
      	clearTimeout(redrawTimerID);
      	redrawTimerID = 0;
   	}		
	for (var n in overlayTable) {
		setLocation(overlayTable[n]);
	}
	if (nextRedrawTimeout < 30000) nextRedrawTimeout = nextRedrawTimeout * 1.3;
    redrawTimerID = setTimeout("redrawAll()", nextRedrawTimeout);
}

function setOverlayCallback(callback) {
    callback_ = callback;
}

function getContent(element) {
    var content = '';
    if (element.firstChild) {
        content = element.firstChild.textContent;
        if (!content) content = element.firstChild.nodeValue;
    }
    return content;
}

function paintArrow(rect, isSelected) {
    if (!rect.minimized_) {
	    var XSpoints;
	    var YSpoints;
	    var Xpoints;
	    var Ypoints;
	    var color;
        switch (parseInt(rect.anchor_)) {
	        case 0:
			    Xpoints = new Array(arrowX1,0,arrowX2);
			    Ypoints = new Array(arrowHeight,0,arrowHeight);
			    color = '#FFFFFF';
			    if (isSelected) color = "#ddeff6";
		        break;
	        case 1:
			    Xpoints = new Array(40-arrowX1,36,40 - arrowX2);
			    Ypoints = new Array(arrowHeight,0,arrowHeight);
			    color = '#FFFFFF';
			    if (isSelected) color = "#ddeff6";
		        break;
	        case 2:
			    Xpoints = new Array(40-arrowX1,40,40 - arrowX2);
			    Ypoints = new Array(0,arrowHeight,0);
			    color = '#CCCCCC';
		        break;
	        case 3:
			    Xpoints = new Array(arrowX1,0,arrowX2);
			    Ypoints = new Array(0,arrowHeight,0);
			    color = '#CCCCCC';
		        break;
        }

	    rect.jgs_.clear();		
	    rect.jgs_.setColor("#CCCCCC"); 
	    rect.jgs_.fillPolygon(Xpoints,Ypoints);	
	    rect.jgs_.paint();

	    rect.jg_.clear();
	    rect.jg_.setColor(color); 
	    rect.jg_.fillPolygon(Xpoints,Ypoints);	
	    rect.jg_.setColor("#9F9F9F"); 
	    rect.jg_.setStroke(2)
	    rect.jg_.drawPolyline(Xpoints,Ypoints);	
	    rect.jg_.paint();
    }	    
}

function processResults(data, responseCode) {
    if (stopCalled) return;
    try {
        // stop redrawing
   	    if (redrawTimerID) {
      	    clearTimeout(redrawTimerID);
      	    redrawTimerID = 0;
        }

        // make sure selection disappears
        unselectDetails();

        // parse XML        
  	    var xml = GXml.parse(data);

  	    // find all regions
  	    var markers = xml.documentElement.getElementsByTagName("Region");
  	    // copy old list of rectangles, create new list
  	    var oldTable = overlayTable;
  	    var oldTopRect_ = topRect_;
  	    topRect_ = null;
  	    overlayTable = {};
  	    // iterate over rectangles
  	    nextZoomIndex_ = markers.length;
  	    for (var i = 0; i < markers.length; i++) {
		    // get id		  		
    	    var id = markers[i].getAttribute("id");
    	    var rect;
    	    // if existing rectangle then reuse
    	    if (oldTable[id]) {
    		    rect = oldTable[id];
    		    overlayTable[id] = rect;
    		    delete oldTable[id];
    	    }
    	    // else create new region
    	    else {
	    	    var position = new GLatLng(parseFloat(markers[i].getAttribute("lat1")), parseFloat(markers[i].getAttribute("lon1")));
	    	    var position1 = new GLatLng(parseFloat(markers[i].getAttribute("lat2")), parseFloat(markers[i].getAttribute("lon2")));

	    	    rect = new Region(position, position1, id);
        	    map.addOverlay(rect);
    		    overlayTable[id] = rect;
    	    }

            rect.div_.overlayRect = rect;
    	    setLocation(rect);
  	    }

  	    // find all rectangles
  	    markers = xml.documentElement.getElementsByTagName("Rectangle");
  	    // iterate over rectangles
  	    nextZoomIndex_ = markers.length;
  	    for (var i = 0; i < markers.length; i++) {
		    // get id		  		
    	    var id = markers[i].getAttribute("id");
    	    var rect;
    	    // if existing rectangle then reuse
    	    if (oldTable[id]) {
    		    rect = oldTable[id];
    		    overlayTable[id] = rect;
    		    delete oldTable[id];

	    	    rect.anchor_ = markers[i].getAttribute("anc");
	    	    rect.gradeApplied_ = -1;
    	    }
    	    // else create new rectangle
    	    else {
	    	    var position = new GLatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lon")));
	    	    var width = markers[i].getAttribute("w");
	    	    var height = markers[i].getAttribute("h");
	    	    var anchor = markers[i].getAttribute("anc");
	    	    var content = markers[i].firstChild.firstChild.textContent;
	    	    if (!content) content = markers[i].firstChild.firstChild.nodeValue;
	    	    var detailsUrl = markers[i].firstChild.nextSibling.firstChild.textContent;
	    	    if (!detailsUrl) detailsUrl = markers[i].firstChild.nextSibling.firstChild.nodeValue;
	    	    var id = markers[i].getAttribute("id");
	    	    var cssClass = markers[i].getAttribute("css");
                if (!cssClass) cssClass = "transp80";
	    	    var parameterName = markers[i].getAttribute("type");

	    	    rect = new Rectangle(position, width, height, content, anchor, cssClass, detailsUrl, id, parameterName);
        	    map.addOverlay(rect);
    		    overlayTable[id] = rect;
    	    }
//        		rect.div_.className = rect.cssClass_;

            rect.div_.overlayRect = rect;
            rect.minimizedDisplay_.overlayRect = rect;
            var zoomIndex = i;
            if (rect == oldTopRect_) {
                topRect_ = rect;
                zoomIndex = nextZoomIndex_;
                nextZoomIndex_ = nextZoomIndex_ + 1;
            }
			rect.div_.style.zIndex = 9 + zoomIndex * 10;
			rect.shadediv_.style.zIndex = 0 + zoomIndex * 10;
			rect.linediv_.style.zIndex = 1 + zoomIndex * 10;
			rect.centergraydiv_.style.zIndex = 2 + zoomIndex * 10;
			rect.centerdiv_.style.zIndex = 3 + zoomIndex * 10;
			rect.shadearrowdiv_.style.zIndex = 0 + zoomIndex * 10;
			rect.arrowdiv_.style.zIndex = 2 + zoomIndex * 10;
			rect.detailsdiv_.style.zIndex = 6 + zoomIndex * 10;
			
			observeEvent(rect.div_, 'click', bringForward, false);
			
			paintArrow(rect, false);
			
    	    setLocation(rect);
  	    }

  	    // remove old unused rectangles from map
	    for (var n in oldTable) {
		    map.removeOverlay(oldTable[n]);
      	    if (oldTable[n].shadediv_) {

		  	    OSGradient.removeGradient(oldTable[n].shadediv_);
		  	    OSGradient.removeGradient(oldTable[n].linediv_);
		  	    OSGradient.removeGradient(oldTable[n].centergraydiv_);
		  	    OSGradient.removeGradient(oldTable[n].centerdiv_);

			    stopObservingEvent(oldTable[n].div_, 'click', bringForward, false);

                oldTable[n].minimizedDisplay_.overlayRect = null;
                oldTable[n].minimizedDisplay_ = null;
                oldTable[n].div_.overlayRect = null;
			    oldTable[n].div_ = null;
			    oldTable[n].shadediv_ = null;
			    oldTable[n].linediv_ = null;
			    oldTable[n].centergraydiv_ = null;
			    oldTable[n].centerdiv_ = null;
			}
	    }


	    // get cloud
  	    var clouds = xml.documentElement.getElementsByTagName("Cloud");
	    if (clouds.length > 0) {
    	    var content = getContent(clouds[0]);
	        if (prevCloud != content) {
		        document.getElementById("map_cloud").innerHTML = content;
		        prevCloud = content;
	        }
	    }
		
	    // get html
  	    var htmls = xml.documentElement.getElementsByTagName("Html");
  	    if (document.getElementById("map_html_list")) {
            
            var totalContent = '<table cellspacing="0" cellpadding="0" style="width: 600px;">';
  	        for (var i = 0; i < htmls.length; i++) {
    	        var contentID = htmls[i].getAttribute("cID");
    	        var idList = htmls[i].getAttribute("ids");
    	        var paramName = htmls[i].getAttribute("pNm");
    	        var canDelete = htmls[i].getAttribute("cDel");
    	        var comments = htmls[i].getAttribute("cmts");
    	        var ownerId = htmls[i].getAttribute("own");
                totalContent = totalContent + getDetailsArea(contentID, getContent(htmls[i]), paramName, idList, canDelete, comments, ownerId);
	        }
  	        document.getElementById("map_html_list").innerHTML = totalContent + '</table>';
            executeEmbeddedScripts(document.getElementById("map_html_list"));
	    }
	    
	    // get nav
  	    var navs = xml.documentElement.getElementsByTagName("Nav");
	    if (navs.length > 0) {
  	        var content = getContent(navs[0]);
		    document.getElementById("map_nav_pre").innerHTML = content;
		    if (htmls.length == 0) {
		        // no results
		        document.getElementById("map_nav_post").innerHTML = '';
		    }
		    else {
		        document.getElementById("map_nav_post").innerHTML = content;
		    }
	    }

	    // get message
  	    var messages = xml.documentElement.getElementsByTagName("Message");
	    if (messages.length > 0) {
  	        var content = getContent(messages[0]);
		    document.getElementById("map_message").innerHTML = content;
	    }

	    // get map message
  	    var mapmessages = xml.documentElement.getElementsByTagName("MapMessage");
	    if (mapmessages.length > 0) {
  	        var content = getContent(mapmessages[0]);
    	    centerDetails = 1;
		    showHTML(content, 'hidden');
	    }
        else { // else is here so map isn't moved if map message is shown
	        // get map bounding box
  	        var bboxes = xml.documentElement.getElementsByTagName("BBox");
	        if (bboxes.length > 0) {
  	            var content = getContent(bboxes[0]);
  	            var values = content.split(";");
            	
        	    var bounds = new GLatLngBounds(new GLatLng(parseFloat(values[0]), parseFloat(values[1])), new GLatLng(parseFloat(values[2]), parseFloat(values[3])));
        	    amMovingMap = 1;
	            map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
	            amMovingMap = 0;
	        }
	    }

	    // schedule redraw, when all div-sizes have been computed
        nextRedrawTimeout = 300;
        redrawTimerID = setTimeout("redrawAll()", nextRedrawTimeout);

	    if (autoLoad_ == true) {
		    // schedule timer
	    	timerID = setTimeout("loadOverlays()", 5000);
	    }
	    
	    if (callback_) callback_();
	}
	catch (e) {
//	    alert(e);
	}
}
	
function loadOverlays() {
   	if (redrawTimerID) {
      	clearTimeout(redrawTimerID);
      	redrawTimerID = 0;
   	}		
   	if (timerID) {
      	clearTimeout(timerID);
      	timerID = 0;
   	}		

	// dynamically load data, add time= to make sure no caching
	var bounds = map.getBounds();
	var noCloudArgs = '';
    var n = 0;
    var nci = 0;
    while (n < views.length) {
	    var label = views[n].label;
	    if (label) {
            noCloudArgs = noCloudArgs + '&nocloud' + nci + '=' + label;
            nci = nci + 1;
        }
	    n = n + 1;
    }

    if (stopCalled) return;

	xmlRequest = DownloadURLText(loadPageName_ + "?time=" + new Date().getTime() + "&width=" + map.getSize().width + "&height=" + map.getSize().height + "&swlat=" + bounds.getSouthWest().lat() + "&swlng=" + bounds.getSouthWest().lng() + "&nelat=" + bounds.getNorthEast().lat() + "&nelng=" + bounds.getNorthEast().lng() + "&currentPage=" + currentPage_ + "&sortOrder=" + sortOrder_ + noCloudArgs + extraArgs_, processResults);
	extraArgs_ = "";
}

function bringForward(evt) {
    var element = evt.target || evt.srcElement;
    while ((element) && (!(element.overlayRect))) {
        element = element.parentNode;
    }
    topRect_ = null;
    if (element) {
        element.overlayRect.minimize(false);
        bringRectForward(element.overlayRect);
    }
    nextZoomIndex_ = nextZoomIndex_ + 1;
}    

function bringRectForward(rect) {
    topRect_ = null;
    if (rect.minimized_) {
        if (rect.minimizedDisplay_) {
            rect.minimizedDisplay_.style.zIndex = 9 + nextZoomIndex_ * 10;
        }
    }
    else {
        if (rect.div_) {
	        rect.div_.style.zIndex = 9 + nextZoomIndex_ * 10;
	        rect.shadediv_.style.zIndex = 0 + nextZoomIndex_ * 10;
	        rect.linediv_.style.zIndex = 1 + nextZoomIndex_ * 10;
	        rect.centergraydiv_.style.zIndex = 2 + nextZoomIndex_ * 10;
	        rect.centerdiv_.style.zIndex = 3 + nextZoomIndex_ * 10;
	        rect.shadearrowdiv_.style.zIndex = 0 + nextZoomIndex_ * 10;
	        rect.arrowdiv_.style.zIndex = 2 + nextZoomIndex_ * 10;
	        rect.detailsdiv_.style.zIndex = 6 + nextZoomIndex_ * 10;
    	    
	        topRect_ = rect;
	    }
	}
    nextZoomIndex_ = nextZoomIndex_ + 1;
}    

function initialize(autoLoad, loadPage, useDetailsURL) {
	loadPageName_ = loadPage;
	autoLoad_ = autoLoad;
	useDetailsURL_ = useDetailsURL;
  	if ((GBrowserIsCompatible()) && (document.getElementById("map_canvas"))) {
        map = new GMap2(document.getElementById("map_canvas"));
        map.setCenter(new GLatLng(0,0), 1, G_NORMAL_MAP);
        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());

        if (autoLoad_) {
    		// load overlays for first timeout
	    	loadOverlays();
        }
        else {
            // allow minimize
            map.addControl(new MiniViewControl());
        }

	    GEvent.addListener(map, "moveend", function() {
	        if (amMovingMap == 0) {
                hideHTML();
	            loadOverlays();
	        }
	    });

	    GEvent.addListener(map, "zoomend", function() {
	  	    if (amMovingMap == 0) {
                hideHTML();
	  	        loadOverlays();
	  	    }
	    });
  	}
    generateMapBack();
    
    var links = document.getElementsByTagName('A');
	for(i=0; i<links.length; i++) {
	    if (links[i].className) {
            if (links[i].className.indexOf('TabMenu2Item') >= 0) {
                links[i].onclick = stopClick;
            }
            if (links[i].className.indexOf('TabMenuItem') >= 0) {
                links[i].onclick = stopClick;
            }
        }
	}
}

function stopClick() {
    stop();
    return true;
}

function stop() {
    stopCalled = true;
   	if (timerID) {
      	clearTimeout(timerID);
      	timerID = 0;
   	}		
   	try {if (xmlRequest) xmlRequest.abort(); } catch (e) {}
   	try {if (xmlRequestShowURL) xmlRequestShowURL.abort(); } catch (e) {}
	GUnload();
}

function generateMapBack() {
	var mapBack = document.getElementById("map_back");
	if (mapBack) {
        var s = 'You are here: ';
        mapBack.style.visibility = "visible";
	    if (views.length == 0) {
            s = s + '<A href="javascript:toView(0)">World</a>';
	    }
	    else {
	        var n = 0;
	        var nextLabel = 'World';
            while (n < views.length) {
                if (n > 0) s = s + ' > ';
		        var label = views[n].label;
		        if (label) {
		            s = s + '<A href="javascript:toView(' + n + ')">' + nextLabel + '</a>';
		            nextLabel = label;
	            }
	            n = n + 1;
	        }	
            if (n > 0) s = s + ' > ';
            s = s + nextLabel;
	    }
        mapBack.innerHTML = s;
    }
}

function show(label, minLat, maxLat, minLng, maxLng) {
	var view = {};
	view.label = label;
	view.center = map.getCenter();
	view.zoom = map.getZoom();
	
	views.push(view);
	generateMapBack();

	var bounds = new GLatLngBounds(new GLatLng(minLat, minLng), new GLatLng(maxLat, maxLng));
	map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
}

function redrawDetailsAll() {
    if (redrawDetailsTimerID) {
  	    clearTimeout(redrawDetailsTimerID);
  	    redrawDetailsTimerID = 0;
    }		
    
    if (amShowingDetails > 0) {
    	redrawDetailsNew(0, map_canvas_, content_container_, linediv_, centergraydiv_, centerdiv_, detailsdiv_, detailsGradeApplied_, '', shadediv_);
    
    	if (nextDetailsRedrawTimeout < 30000) nextDetailsRedrawTimeout = nextDetailsRedrawTimeout * 4 / 3;
        redrawDetailsTimerID = setTimeout("redrawDetailsAll()", nextDetailsRedrawTimeout);
    }
}

function redrawDetailsNew(resize_container, map_canvas, content_container, linediv, centergraydiv, centerdiv, detailsdiv, detailsGradeApplied, id, shadediv) {
    if (detailsGradeApplied == -1) {
        try {
            if (content_container.detailsGradeApplied) {
                detailsGradeApplied = content_container.detailsGradeApplied;
            }
        }
        catch (e) {
            // ignored
        }
    }
    
    var localDetailsHeight = 0;
    if (detailsdiv.style.visibility == "visible") {
        localDetailsHeight = detailsHeight;
    }
    
	var top = map_canvas.offsetTop + 5 + lineWidth + offsetRadius;
	var left = map_canvas.offsetLeft + 5 + lineWidth + offsetRadius;
   	if (resize_container != 0) {
        map_canvas.style.width = (content_container.clientWidth + (offsetRadius * 2) + (lineWidth*2)) + "px";
        map_canvas.style.height = (content_container.clientHeight + (offsetRadius * 2) + (lineWidth*2) + localDetailsHeight + 10) + "px";
        
        top = linediv.offsetTop + lineWidth + offsetRadius;
        left = linediv.offsetLeft + lineWidth + offsetRadius;
   	}
   	
    if (centerDetails != 0) {
        top = 200 - (content_container.clientHeight / 2) + top;
    }
    
    content_container.style.left = left + "px";
    content_container.style.top = top + "px";

    if (shadediv) {
        shadediv.style.left = (left - offsetRadius - lineWidth + 4) + "px";
        shadediv.style.top = (top - offsetRadius - lineWidth + 4) + "px";
    }

    linediv.style.left = (left - offsetRadius - lineWidth) + "px";
    linediv.style.top = (top - offsetRadius - lineWidth) + "px";

    centergraydiv.style.left = (left - offsetRadius) + "px";
    centergraydiv.style.top = (top - offsetRadius) + "px";

    centerdiv.style.left = (left - offsetRadius) + "px";
    centerdiv.style.top = (top - offsetRadius) + "px";

    if (detailsdiv) {
        detailsdiv.style.left = (left - offsetRadius) + "px";
        detailsdiv.style.top = (top + content_container.clientHeight) + "px";
    }

    if (shadediv) {
        shadediv.style.width = (content_container.clientWidth + (offsetRadius * 2) + (lineWidth*2)) + "px";
        shadediv.style.height = (content_container.clientHeight + (offsetRadius * 2) + (lineWidth*2) + localDetailsHeight) + "px";
    }
    
    linediv.style.width = (content_container.clientWidth + (offsetRadius * 2) + (lineWidth*2)) + "px";
    linediv.style.height = (content_container.clientHeight + (offsetRadius * 2) + (lineWidth*2) + localDetailsHeight) + "px";

    centergraydiv.style.width = (content_container.clientWidth + (offsetRadius * 2)) + "px";
    centergraydiv.style.height = (content_container.clientHeight + (offsetRadius * 2) + localDetailsHeight) + "px";

    centerdiv.style.width = (content_container.clientWidth + (offsetRadius * 2)) + "px";
    cdoffset = localDetailsHeight - 10;
    if (cdoffset < 0) cdoffset = 0;
    centerdiv.style.height = (content_container.clientHeight + (offsetRadius * 2) + cdoffset) + "px";

    if (detailsdiv) {
        detailsdiv.style.width = (content_container.clientWidth + (offsetRadius * 2)) + "px";
        detailsdiv.style.height = localDetailsHeight + "px";
    }

  	if (detailsGradeApplied != (content_container.clientWidth * content_container.clientHeight)) {
  	    OSGradient.removeGradient(linediv);
  	    OSGradient.removeGradient(centergraydiv);
  	    OSGradient.removeGradient(centerdiv);
  	    
  	    if (shadediv) {
  	        OSGradient.removeGradient(shadediv);
      	    detailsGradeApplied_ = content_container.clientWidth * content_container.clientHeight;
            OSGradient.applyGradient(shadeStyle, shadediv);
        }
        else {
            content_container.detailsGradeApplied = content_container.clientWidth * content_container.clientHeight;
        }
        
        OSGradient.applyGradient(lineStyle, linediv);
        OSGradient.applyGradient(centerGrayStyle, centergraydiv);
        OSGradient.applyGradient(centerStyle, centerdiv);
    }
}

function showHTML(html,hidevisibility) {
    if (!hidevisibility) hidevisibility = 'visible';
	content_container_ = $("content_container");
    shadediv_= $("shadediv");
    linediv_= $("linediv");
    centergraydiv_= $("centergraydiv");
    centerdiv_= $("centerdiv");
    detailsdiv_= $("detailsdiv");
    map_canvas_ = $("map_canvas");
    mapshadediv_ = $("mapshadediv");
	
	content_container_.innerHTML = html;
	amShowingDetails = 1;
	detailsGradeApplied_ = -2;
	nextDetailsRedrawTimeout = 300;
	
	content_container_.style.visibility="visible";
	shadediv_.style.visibility="visible";
	linediv_.style.visibility="visible";
	centergraydiv_.style.visibility=hidevisibility;
	centerdiv_.style.visibility="visible";
	detailsdiv_.style.visibility=hidevisibility;
	mapshadediv_.style.visibility=hidevisibility;
	
	detailsHeight = 16;
	if (hidevisibility == 'hidden') detailsHeight = 0;
    
	redrawDetailsAll();
}

function showURL(url) {
    // check if query is running
    if ((xmlRequestShowURL) && (xmlRequestShowURL.readyState != 4)) return;
    xmlRequestShowURL = DownloadURLText(url, function(data, responseCode) {	showHTML(data) });
}

function unselectDetails() {
    if ((selectedElement_) && (selectedElement_.className == "selectedDetails")) {
        selectedElement_.className = "";
        if ((selectedID_) && (overlayTable[selectedID_])) {
            OSGradient.removeGradient(overlayTable[selectedID_].centerdiv_);
            OSGradient.applyGradient(centerStyle, overlayTable[selectedID_].centerdiv_);
            paintArrow(overlayTable[selectedID_], false);
        }
    }
}

function showID(id) {
    unselectDetails();
    element = $(id);

    while (element.nodeName != 'TABLE') {
        element = element.parentNode;
    }
    selectedElement_ = element;
    element.className = "selectedDetails";
    element.scrollIntoView(false);
}

function showMapID(id) {
    unselectDetails();
    selectedID_ = id;
    overlayTable[id].minimize(false);
    selectedElement_ = overlayTable[id].div_;
    overlayTable[id].div_.className = "selectedDetails";
    OSGradient.removeGradient(overlayTable[id].centerdiv_);
    OSGradient.applyGradient(centerSelectedStyle, overlayTable[id].centerdiv_);
    overlayTable[id].minimize(false);
    bringRectForward(overlayTable[id]);
    paintArrow(overlayTable[id], true);
    document.getElementById("map_canvas").scrollIntoView(true);
}

function deleteID(paramName, idList) {
    var values = idList.split(",");
    var message = 'Do you really want to delete this item?';
    if (values.length > 1) {
        message = 'You are about to delete ' + values.length + ' items. Are you sure?';
    }
    if (window.confirm(message)) {
    	GDownloadUrl('ExecuteMethod.aspx?method=Delete&paramName=' + paramName + '&idList=' + idList, processDeleteResult);
    }
}

function processDeleteResult(data, responseCode) {
    try {
        // parse xml
  	    var xml = GXml.parse(data);
	    // get message
  	    var messages = xml.documentElement.getElementsByTagName("Message");
	    if (messages.length > 0) {
  	        var content = getContent(messages[0]);
		    alert(content);
	    }
	    // reload page
  	    loadOverlays();
  	}
  	catch (e) {
  	}
}

function mayOffendID(paramName, idList) {
    if (window.confirm('Do you want to notify the administrator that this item may offend?')) {
        var values = idList.split(",");
	    GDownloadUrl('ExecuteMethod.aspx?method=ContextMayOffend&paramName=' + paramName + '&idList=' + idList, processMayOffendResult);
	}
}

function processMayOffendResult(data, responseCode) {
    try {
        // parse xml
  	    var xml = GXml.parse(data);
	    // get message
  	    var messages = xml.documentElement.getElementsByTagName("Message");
	    if (messages.length > 0) {
  	        var content = getContent(messages[0]);
		    alert(content);
	    }
  	}
  	catch (e) {
  	}
}

function minimizeID(id) {
    overlayTable[id].minimize(true);
}

function hideHTML() {
	amShowingDetails = 0;
	centerDetails = 0;
	detailsHeight = 16;
	if (content_container_) {
	    content_container_.style.visibility="hidden";
	    shadediv_.style.visibility="hidden";
	    linediv_.style.visibility="hidden";
	    centergraydiv_.style.visibility="hidden";
	    centerdiv_.style.visibility="hidden";
	    detailsdiv_.style.visibility="hidden";
	    mapshadediv_.style.visibility="hidden";
	}
}

function toView(index) {
	var view;
	while (views.length > index) {
	    view = views.pop();
    }
    if (view) {
    	map.setCenter(view.center, view.zoom);
    }
    else {
        map.setCenter(new GLatLng(0,0), 1);
    }
    generateMapBack();
}

function setCurrentPage(currentPage) {
    currentPage_ = currentPage;
}

function setExtraArgs(extraArgs) {
    extraArgs_ = extraArgs;
}

function loadPage(page) {
    setCurrentPage(page);
    hideHTML();
    loadOverlays();
}

function setSortOrder(order) {
    sortOrder_ = order;
}    

function showAddComment(paramName, idList, ownerId) {
    $('addCommentTextArea').paramName = paramName;
    $('addCommentTextArea').idList = idList;
    $('addCommentTextArea').ownerId = ownerId;
    $('addCommentTextArea').value = '';

	GDownloadUrl('ExecuteMethod.aspx?method=ListComments&id=' + idList + '&paramName=' + paramName + '&ownerId=' + ownerId, processListCommentsResult);
}

function processListCommentsResult(data, responseCode) {
    try {
        // parse xml
  	    var xml = GXml.parse(data);
	    // get message
  	    var messages = xml.documentElement.getElementsByTagName("Message");
  	    var s = '';
  	    for (var i = 0; i < messages.length; i++) {
    	    s = s + getContent(messages[i]);
    	}
    	$('commentsDiv').innerHTML = s;
        $find('AddCommentPanelPopupExtender').show();
  	}
  	catch (e) {
  	}
}

function addComment() {
    var commentTextArea = document.getElementById('addCommentTextArea');
	GDownloadUrl('ExecuteMethod.aspx?method=AddComment&id=' + commentTextArea.idList + '&paramName=' + commentTextArea.paramName + '&ownerId=' + commentTextArea.ownerId + '&comment=' + URLEncode(commentTextArea.value), processAddCommentResult);
}

function processAddCommentResult(data, responseCode) {
    try {
        // parse xml
  	    var xml = GXml.parse(data);
	    // get message
  	    var messages = xml.documentElement.getElementsByTagName("Message");
	    if (messages.length > 0) {
  	        var content = getContent(messages[0]);
		    alert(content);
	    }
	    // reload 
	    loadOverlays();
  	}
  	catch (e) {
  	}
}

function getDetailsArea(contentID, content, paramName, idList, canDelete, comments, ownerId) {
    var id = 'unknown';
    if (contentID) id = contentID;
    var urlDelete = "javascript:deleteID('" + paramName + "','" + idList + "');";
    var urlOffend = "javascript:mayOffendID('" + paramName + "','" + idList + "');";
    var urlComments = paramName + "/" + idList + "/comments";
   	var result = '<table cellpadding="0" cellspacing="0" style="margin-bottom: 12px">' +
  		'<tr>' +
  			'<td style="height:8px; width: 8px; background-image: url(images/tl.gif);"><img src="images/pixel.gif"></td>' +
  			'<td style="height:8px; width: 584px; background-image: url(images/t.gif);"><img src="images/pixel.gif"></td>'+
  			'<td style="height:8px; width: 8px; background-image: url(images/tr.gif);"><img src="images/pixel.gif"></td>' +
  		'</tr>' +
  		'<tr>' +
  			'<td style="width: 8px; background-image: url(images/l.gif);"><img src="images/pixel.gif"></td>' +
  			'<td style="width: 584px;"><div id="' + id + 'details" style="width: 584px; overflow: hidden">' + content + '</div></td>' +
  			'<td style="width: 8px; background-image: url(images/r.gif);"><img src="images/pixel.gif"></td>' +
  		'</tr>' +
  		'<tr>' +
  			'<td style="height:14px; margin: 0px 0px 0px 0px; width: 8px; background-image: url(images/ls.gif);"><img src="images/pixel.gif"></td>' +
  			'<td style="height:14px; margin: 0px 0px 0px 0px; width: 584px; background-color: #CCCCCC;"><div style="width:584px; height: 14px; margin-top: 4px; line-height: 100%; position: absolute">';
  	if (canDelete == 'true') {
  	    result = result +
  			        '<span style="float:right"><a style="color: #666666;" href="' + urlDelete + '"><img alt="Delete" style="border:none" src="images/trashbin.png" title="Delete"/>&nbsp;</a></span>';
  	}
    result = result +
  			        '<span style="float:right; margin-right: 5px"><a style="color: #666666;" href="' + urlOffend + '"><img alt="May offend" style="border:none" src="images/eye.png" title="May offend"/>&nbsp;</a></span>';
  	if (contentID) {
        var url = "javascript:showMapID('" + contentID + "');";
  	    result = result + 
  			        '<span style="float:left"><a style="color: #666666;" href="' + url + '"><img title="Show on map" alt="Show on map" style="border:none" src="images/backtomapicon.png"/>&nbsp;</a>' +
  			        '<a style="color: #666666;" href="' + url + '">Show on map</a></span>';
    }
    if (comments) {
        if ((idList.split(",").length == 1) && (ownerId)) {
            var urlAddComment = "javascript:showAddComment('" + paramName + "','" + idList + "','" + ownerId + "');";
            result = result + '<span style="float:right; margin-right: 4px;"><a style="color: #666666;" href="' + urlAddComment + '"><img alt="Add comment" title="Add comment" src="images/12/note12.png" style="border:none"/>&nbsp;</a></span>';
        }
        result = result + '<span style="float:right; margin-right: 4px;"><a target="_blank" style="color: #666666;" href="' + urlComments + '">' + comments + ' comment';
        if (comments != 1) result = result + 's';
        result = result + '</a>&nbsp;</span>';
    }
    result = result + 
            '</div></td>' +
  			'<td style="height:14px; margin: 0px 0px 0px 0px; width: 8px; background-image: url(images/rs.gif);"><img src="images/pixel.gif"></td>' +
  		'</tr>' +
  		'<tr>' +
  			'<td style="height:8px; width: 8px; background-image: url(images/bls.gif);"><img src="images/pixel.gif"></td>' +
  			'<td style="height:8px; width: 584px; background-image: url(images/bs.gif);"><img src="images/pixel.gif"></td>' +
  			'<td style="height:8px; width: 8px; background-image: url(images/brs.gif);"><img src="images/pixel.gif"></td>' +
  		'</tr>';
    return result + '</table>';
}

function MiniViewControl() {
}
MiniViewControl.prototype = new GControl();

MiniViewControl.prototype.initialize = function(map) {
  var container = document.createElement('div');
  container.innerHTML = '<a style="background-color: white; border: none; padding-left: 2px; padding-right: 2px;" href="javascript:minimizeAll()"><img style="border:none" src="images/minimize.png"/>&nbsp;minimize all</a>&nbsp;<a style="background-color: white; border: none; padding-left: 2px; padding-right: 2px;" href="javascript:maximizeAll()"><img style="border:none" src="images/expand.png"/>&nbsp;maximize all</a>';
  map.getContainer().appendChild(container);
  return container;
}

MiniViewControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(65, 0));
}
