function geodistance(ya, xa, yb, xb)
{
    var bya = ya * pi180;
    var byb = yb * pi180;
    var cosd = Math.sin(bya) * Math.sin(byb) + Math.cos(bya) * Math.cos(byb) * Math.cos((xa-xb)* pi180);
    var l = Math.acos(cosd) * 6370;
    return l;
}

function getXMLData(script, params) {

  var zoom = map.getZoom();
  if (window.XMLHttpRequest) {
    httpreq = new XMLHttpRequest();
  } else if (window.ActiveXObject) {
    httpreq = new ActiveXObject("Microsoft.XMLHTTP");
  }
  if (httpreq != null) {
    httpreq.open("GET", script+"?west="+map.getBounds().getSouthWest().lng()+"&east="+map.getBounds().getNorthEast().lng()+"&north="+map.getBounds().getNorthEast().lat()+"&south="+map.getBounds().getSouthWest().lat()+'&zoom='+zoom+params, true);
    httpreq.onreadystatechange = output;
    httpreq.send(null);
  }
  if (document.getElementById('ProgressBar')) document.getElementById('ProgressBar').style.display = 'block';
}

function getJSON(selectedWebService, x, y, lang, siz) {
  var latlng = new GLatLng(y + 0, x + 0);
  var script = document.createElement('script');
  document.body.appendChild(script);
  script.src = 'http://ws.geonames.org/' + selectedWebService + 'JSON?lat=' + latlng.lat() + '&lng=' + latlng.lng() + '&lang=' + lang + '&maxRows=' + siz + '&callback=loadJSON';
}

function getJSONBound(selectedWebService) {
  var script = document.createElement('script');
  document.body.appendChild(script);
  script.src = 'http://ws.geonames.org/' + selectedWebService + 'JSON?west='+map.getBounds().getSouthWest().lng()+"&east="+map.getBounds().getNorthEast().lng()+"&north="+map.getBounds().getNorthEast().lat()+"&south="+map.getBounds().getSouthWest().lat()+'&maxRows=25&lang=de&callback=loadJSONBounds';
}

// === functions that perform the context menu options ===
function zoomIn() {
        // perform the requested operation
        map.zoomIn();
        // hide the context menu now that it has been used
        contextmenu.style.visibility="hidden";
}      
function zoomOut() {
        // perform the requested operation
        map.zoomOut();
        // hide the context menu now that it has been used
        contextmenu.style.visibility="hidden";
}      
function zoomInHere() {
        // perform the requested operation
        var point = map.fromContainerPixelToLatLng(clickedPixel)
        map.zoomIn(point,true);
        // hide the context menu now that it has been used
        contextmenu.style.visibility="hidden";
}      
function zoomOutHere() {
        // perform the requested operation
        var point = map.fromContainerPixelToLatLng(clickedPixel)
        map.setCenter(point,map.getZoom()-1); // There is no map.zoomOut() equivalent
        // hide the context menu now that it has been used
        contextmenu.style.visibility="hidden";
}      
function centreMapHere() {
        // perform the requested operation
        var point = map.fromContainerPixelToLatLng(clickedPixel)
        map.setCenter(point);
        // hide the context menu now that it has been used
        contextmenu.style.visibility="hidden";
}

var wikiLayer;
function addWiki() {
  if (!wikiLayer) {
    wikiLayer = new GLayer("org.wikipedia.de");
    map.addOverlay(wikiLayer);
  } else {
    map.removeOverlay(wikiLayer);
    wikiLayer = null;
  }
}

var panoLayer;
function addPano() {
  if (!panoLayer) {
    panoLayer = new GLayer("com.panoramio.all");
    map.addOverlay(panoLayer);
  } else {
    map.removeOverlay(panoLayer);
    panoLayer = null;
  }
}

UTF8 = {
	encode: function(s){
		for(var c, i = -1, l = (s = s.split("")).length, o = String.fromCharCode; ++i < l;
			s[i] = (c = s[i].charCodeAt(0)) >= 127 ? o(0xc0 | (c >>> 6)) + o(0x80 | (c & 0x3f)) : s[i]
		);
		return s.join("");
	},
	decode: function(s){
		for(var a, b, i = -1, l = (s = s.split("")).length, o = String.fromCharCode, c = "charCodeAt"; ++i < l;
			((a = s[i][c](0)) & 0x80) &&
			(s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ?
			o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = "")
		);
		return s.join("");
	}
};


function ProgressbarMapControl(map, width) {
 this.map_ = map;
 this.width_ = width;
}

/**
 * @private
 */
ProgressbarMapControl.prototype = new GControl(true, false);


/**
 * @private
 * @desc Initializes the GControl. Creates the HTML and styles.
 * @return {Element}
 */
ProgressbarMapControl.prototype.initialize = function () {
 var container_ = document.createElement('div');
 container_.innerHTML = '<div style="position:absolute;width:100%;border:5px;'
 + 'text-align:center;vertical-align:bottom;" id="geo_progress_text"></div>'
 + '<div style="background-color:green;height:100%;" id="geo_progress"></div>';
 container_.id = "geo_progress_container";
 container_.style.display = "none";
 container_.style.width = this.width_ + "px";
 container_.style.fontSize = "0.8em";
 container_.style.height = "1.3em";
 container_.style.border = "1px solid #555";
 container_.style.backgroundColor = "white";
 container_.style.textAlign = "left";
 this.map_.getContainer().appendChild(container_);
 return container_;
};


/**
 * @private
 * @desc Return the default position for the control
 * @return {GControlPosition}
 */
ProgressbarMapControl.prototype.getDefaultPosition = function () {
 return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(30, 56));
};


/**
 * Creates a progress bar control on the given map, with the given options.
 *
 * @constructor
 * @param {GMap2} Map object
 * @param {ProgressbarOptions} opt_opts
 */
function ProgressbarControl(map, opt_opts) {
 this.options_ = opt_opts || {};

 this.width_ = this.options_.width || 176;
 this.loadstring_ = this.options_.loadstring || 'Loading...';

 this.control_ = new ProgressbarMapControl(map, this.width_);
 this.map_ = map;
 this.map_.addControl(this.control_);
 this.div_ = document.getElementById('geo_progress');
 this.text_ = document.getElementById('geo_progress_text');
 this.container_ = document.getElementById('geo_progress_container');

 this.operations_ = 0;
 this.current_ = 0;
}


/**
 * @desc Start the progress bar.
 * @param {Number} operations Total amount of operations that will be executed.
 */
ProgressbarControl.prototype.start = function (operations) {
 this.div_.style.width = '0%';
 this.operations_ = operations || 0;
 this.current_ = 0;
 this.text_.style.color = "#111";
 this.text_.innerHTML = this.loadstring_;
 this.container_.style.display = "block";
};


/**
 * @desc Update the progress with specified number of operations.
 * @param {Number} step Number of operations to add to bar.
 */
ProgressbarControl.prototype.updateLoader = function (step) {
 this.current_ += step;
 if (this.current_ > 0) {
 var percentage_ = Math.ceil((this.current_ / this.operations_) * 100);
 if (percentage_ > 100) {
 percentage_ = 100;
}
this.div_.style.width = percentage_ + '%';
 this.text_.innerHTML = this.current_ + ' / ' + this.operations_;
 }
};


/**
 * @desc Remove control.
 */
ProgressbarControl.prototype.remove = function () {
 this.container_.style.display = 'none';
};
