var tempmarkers = new Array();

function LoadMap() {
	sizeMapDiv(102);
	$('loading').style.display ="block";
	Berlin = new Subway($('map'));
}

/* global because we call it before initializing the map, related to ie resize puzzle */
function sizeMapDiv(offset){
/*	'offset' is the amount of virtical pixels taken up by a top bar and/or footer, to make things more flexible we pass it as an arguement */
	    var w = getWindowSize();
			$("map").style.height = (w.height - offset) + 'px';
			$('bitright').style.height = (w.height - offset) + 'px';
}

function getWindowSize(){
	    var e = new Object();
	    if(window.self && self.innerWidth)
	    {
		    e.width = self.innerWidth;
		    e.height = self.innerHeight;
	    }
	    else if(document.documentElement && document.documentElement.clientHeight)
	    {
		    e.width = document.documentElement.clientWidth;
		    e.height = document.documentElement.clientHeight;
	    }else
	    {
		    e.width = document.body.clientWidth;
		    e.height = document.body.clientHeight;
	    }
	    return e;
}

var resizingInterval = null;
var resizingFlag = false;

function setNewListeners(){
    window.onresize = function()
    {
			sizeMapDiv(72);
        resizingFlag = true;
			if(resizingInterval==null)
		    	resizingInterval = setInterval("checkResizeEnd()", 100);
    };
}

function checkResizeEnd(){
	if(!resizingFlag)
	{
		Berlin.map.checkResize();
		Berlin.updateMarkers();
		clearInterval(resizingInterval);
		resizingInterval = null;
	}
	resizingFlag = false;
}

/* still global since we use them in non subway class functions */
//stations icon
var icon = new GIcon();
icon.image = "http://www.onnyturf.com/google/images/clear2.png";
icon.shadow = "http://www.onnyturf.com/google/images/clear2.png";
icon.iconSize = new GSize(14, 14);
icon.shadowSize = new GSize(14, 14);
icon.iconAnchor = new GPoint(10, 10);
icon.infoWindowAnchor = new GPoint(10, 10);

//green icon
var addicon = new GIcon();
addicon.image = "http://www.uberbahn.com/images/yel_none.png";
addicon.shadow = "http://www.google.com/mapfiles/shadow50.png";
addicon.iconSize = new GSize(20, 34);
addicon.shadowSize = new GSize(37, 34);
addicon.iconAnchor = new GPoint(9, 34);
addicon.infoWindowAnchor = new GPoint(9, 2);			
addicon.infoShadowAnchor = new GPoint(18, 25);

var orgicon = new GIcon();
orgicon.image = "http://www.onnyturf.com/subway/images/turfcrzy3.png";
orgicon.shadow = "http://www.google.com/mapfiles/shadow50.png";
orgicon.iconSize = new GSize(20, 34);
orgicon.shadowSize = new GSize(37, 34);
orgicon.iconAnchor = new GPoint(9, 34);
orgicon.infoWindowAnchor = new GPoint(9, 2);			
orgicon.infoShadowAnchor = new GPoint(18, 25);


function Subway (mapdiv){
	this.lMessage = $('lMessage');
	this.loadingID = $('loading');
	this.bounds;
	this.xmax;
	this.xmin;
	this.ymax;
	this.ymin;
	this.markers = [];
	this.markercounter = 1; //time delay for updating markers
	this.markertimers = []; //list of markers to update
	this.tempmarkers = [];
	this.map = new GMap2(mapdiv, {draggableCursor: 'default'});

/*
	this.map.mapTypes[0].baseUrls = [];
	this.map.mapTypes[0].baseUrls[0] = "http://mt.google.com/mt?v=ap.6&";
	this.map.mapTypes[1].baseUrls = [];
	this.map.mapTypes[1].baseUrls[0] = "http://kh.google.com/kh?n=404&v=6&";

	this.metro = this.copy_obj(this.map.mapTypes[0]);
	this.metro.baseUrls = [];
	this.metro.baseUrls[0] = "/tiles/metro.php?";
	this.metro.getLinkText = function() { return 'S & U'; }

	this.tram = this.copy_obj(this.map.mapTypes[0]);
	this.tram.baseUrls = [];
	this.tram.baseUrls[0] = "/tiles/tram.php?";
	this.tram.getLinkText = function() { return 'Straßen'; }

	// Register the new mapType with the running google map.
	this.map.mapTypes[this.map.mapTypes.length] = this.metro;
	this.map.mapTypes[this.map.mapTypes.length] = this.tram;

	this.map.setMapType(this.map.mapTypes[this.map.mapTypes.length-2]);
*/
	this.map.addControl(new GMapTypeControl());
	this.map.addControl(new GSmallZoomControl());
	//Center the map
	this.map.setCenter(new GLatLng(52.5217, 13.411), 13);
	this.defaultmap = this.addMapType();
	this.map.setMapType(this.defaultmap);
	this.checkBounds();
	doSimpleXMLHttpRequest("berlin_stops.xml").addCallback( bind(this.mapBerlin, this) );
	var ref = this;
	GEvent.addListener(this.map, "moveend", function() { ref.updateMarkers(); });
	GEvent.addListener(this.map, "click", function(overlay, point){ if (overlay){ if (overlay.my_html){ overlay.openInfoWindowHtml(overlay.my_html); } } });
	setNewListeners();	
}


Subway.prototype.checkBounds = function(){
	this.bounds = this.map.getBounds();
	this.xmax = this.bounds.getNorthEast().lat();
	this.xmin = this.bounds.getSouthWest().lat();
	this.ymax = this.bounds.getNorthEast().lng();
	this.ymin = this.bounds.getSouthWest().lng();
}

Subway.prototype.compareBounds = function(p){
	if (p.lat() < this.xmin || p.lat() > this.xmax ||
		p.lng() < this.ymin || p.lng() > this.ymax) {
		return false;
	}else{
		return true;
	}
}



Subway.prototype.addMapType = function(){
	// create copyright
	var copyright = new GCopyright(1,
						  new GLatLngBounds( new GLatLng( -90,-180 ), new GLatLng( 90,180 ) ),
						  0,
						  "&copy;2007 Uberbahn, Map data &copy;2007 Tele Atlas");

	//add to copyright collection
	var copyrightCollection = new GCopyrightCollection();
	copyrightCollection.addCopyright(copyright);

	// create GTileLayer
	GetMetroUrl=function(a, b){
		var c = 17 - b;
		if (b < 12){
			return "http://mt.google.com/mt?n=404&v=ap.5&x="+a.x+"&y="+a.y+"&zoom="+c;
		}else{
			return "/tiles/metro.php?x="+a.x+"&y="+a.y+"&zoom="+c;
		}
	}

	// create GTileLayer
	GetTramUrl=function(a, b){
		var c = 17 - b;
		if (b < 12){
			return "http://mt.google.com/mt?n=404&v=ap.5&x="+a.x+"&y="+a.y+"&zoom="+c;
		}else{
			return "/tiles/tram.php?x="+a.x+"&y="+a.y+"&zoom="+c;
		}
	}

	var metrolayers = [];
	metrolayers.push( new GTileLayer( copyrightCollection, 0, 17 ) );
	metrolayers[0].getTileUrl = GetMetroUrl;
	metrolayers[0].isPng = function(){return false;};
	var metromap = new GMapType(metrolayers, G_NORMAL_MAP.getProjection(), "S & U", {errorMessage:"no maps here"});

	var tramlayers = [];
	tramlayers.push( new GTileLayer( copyrightCollection, 0, 17 ) );
	tramlayers[0].getTileUrl = GetTramUrl;
	tramlayers[0].isPng = function(){return false;};
	var trammap = new GMapType(tramlayers, G_NORMAL_MAP.getProjection(), "Straßen", {errorMessage:"no maps here"});

	//add it to the map
	this.map.addMapType(metromap);
	this.map.addMapType(trammap);
	
	return metromap;
}


Subway.prototype.show = function(o){
	o.style.display = 'block';
}

Subway.prototype.hide = function(o){
	o.style.display = 'none';
}

Subway.prototype.copy_obj = function(o) {var c = new Object(); for (var e in o) { c[e] = o[e]; } return c;}

Subway.prototype.loopOver = function(arr, fnc){
	var iIterations = arr.length;
	var iLoopCount = Math.ceil(iIterations / 8);
	var iTestValue = iIterations % 8;
	var n = 0;
	do {
		switch (iTestValue) {
			case 0: fnc(n++);
			case 7: fnc(n++);
			case 6: fnc(n++);
			case 5: fnc(n++);
			case 4: fnc(n++);
			case 3: fnc(n++);
			case 2: fnc(n++);
			case 1: fnc(n++);
		}
		iTestValue = 0;
	} while (--iLoopCount > 0);
}

Subway.prototype.firstAdd = function(){
	var point = new GLatLng( parseFloat(bMarker.lat), parseFloat(bMarker.lon) );
	bMarker.tip = "<div class='fav_tip'>" + bMarker.title + "</div>";

	if (bMarker.marker_id != null){
		var val = bMarker.marker_id;
		var linkpath = "http://www.onnyturf.com/subway/?marker_id=" + val;
	}else{
		var esctitle = bMarker.title.replace(/ /g, "+");
		var linkpath = "http://www.onnyturf.com/subway/?address=" + esctitle;
	}
	var addlink = "<a href='" + linkpath + "'>Link to Here</a>";
	var email = "<a href='mailto:?body="+linkpath+"'>Email Link</a>";

	bMarker.marker = new GxMarker(point, addicon, bMarker.tip);
  var aHTML = ["<div class='fav_window'><h1 class='fav_title'>", bMarker.title, "</h1><p>", bMarker.parsed_data, "</p><p>", addlink, "&nbsp;&nbsp;", email, "</p></div>"];
  bMarker.marker.my_html = aHTML.join("");
	this.map.addOverlay(bMarker.marker);
	bMarker.marker.openInfoWindowHtml(bMarker.marker.my_html);
}

Subway.prototype.OLDcreateMarker = function(p, tx, i, t) {
	var m = new GxMarker(p, i, t);
	var n = this.markers.length;
	this.markers[n] = {};
	this.markers[n].n = n;
	var bounds = this.map.getBoundsLatLng(); 
	var xmax = bounds.maxX, xmin = bounds.minX, ymax = bounds.maxY, ymin = bounds.minY;
	if (p.x < xmin || p.x > xmax ||
		p.y < ymin || p.y > ymax) {
		this.markers[n].added = 0;
	} else {
		this.map.addOverlay(m);
		this.markers[n].added = 1;
	}

	GEvent.addListener(m, "click", function() {
		m.openInfoWindowHtml(tx);
	});

	this.markers[n].marker = m;
}


Subway.prototype.createMarker = function(point, text, icon, tip) {
	var p = point;
	var i = icon;
	var t = tip;
	var n = this.markers.length;
	this.markers[n] = {};
	this.markers[n].n = n;
	this.markers[n].marker = new GxMarker(p, i, t);
	this.markers[n].marker.my_html = text;

	if ( this.compareBounds(p) ){
		this.map.addOverlay( this.markers[n].marker );
		this.markers[n].added = 1;
	}else{
		this.markers[n].added = 0;
	}
}


Subway.prototype.OLDupdateMarkers = function(){
	var ref = this;
	this.loopOver(this.markers, function(i){ref.updateMarker(i);});
}


Subway.prototype.updateMarkers = function(){
	this.markercounter = 1;
	this.markertimers = [];
	this.checkBounds();
	var ref = this;
	this.loopOver(this.markers, function(i){ref.updateMarker(i);});
	var count = this.markertimers.length;
	for (var n = 0; n < count; n++){ this.markertimers[n](); }
}


Subway.prototype.OLDupdateMarker = function(i){
	var bounds = this.map.getBoundsLatLng();
	var xmax = bounds.maxX, xmin = bounds.minX, ymax = bounds.maxY, ymin = bounds.minY;

	var p = this.markers[i].marker.point;
	if (p.x < xmin || p.x > xmax || p.y < ymin || p.y > ymax) {
		/*
		if (markers[i].added) {
    	map.removeOverlay(markers[i]);
			markers[i].added = 0;
		}
		*/
	} else {
		if (!this.markers[i].added) {
			this.map.addOverlay(this.markers[i].marker);
			this.markers[i].added = 1;
		}
	}
}


Subway.prototype.updateMarker = function(i){
	var o = this.markers[i];
	var m = o.marker;
	var p = m.getPoint();
	var ref = this;
	if ( this.compareBounds(p) ){
		if ( !o.added ) {
			this.markertimers.push( function() {
						ref.map.addOverlay( m ); 
						o.added = 1;
			});
		}
	} else if (o.added) {
			this.markertimers.push( function() { 
						ref.map.removeOverlay( m ); 
						o.added = 0;
			});
	}
}




Subway.prototype.mapBerlin = function(rslt){
	this.stations = rslt.responseXML.documentElement.getElementsByTagName('station');
	var ref = this;
	this.loopOver(this.stations, function(i){ref.addSubMarker(i);});

	//Update the loading message
	this.hide(this.loadingID);

	// Monitor the window resize event and let the map know when it occurs
		sizeMapDiv(72);
		this.map.checkResize();
}

Subway.prototype.addSubMarker = function(i){
	// create a point
	var latlng = this.stations[i].getElementsByTagName('point');
	var p = new GLatLng(parseFloat(latlng[0].getAttribute("lat")), parseFloat(latlng[0].getAttribute("lng")));
	// get station name
	var add = this.stations[i].getElementsByTagName('address')[0].firstChild.nodeValue;
	var aText = ["<div id='infowindow' style='white-space: nowrap;'><span class='stationname'>", add, "</span><br/>"];
	var aTip = ["<div class='stationtip'><span class='stationname_sm'>", add, "</span><br/>"];
	// get line images
	var mysub = this.stations[i].getElementsByTagName('line');
	var count = mysub.length;
	for (k=0;k<count; k++){
		var lineid = mysub[k].firstChild.nodeValue;;
		aText.push('<img style="border:none; padding-top:2px;" src="/images/', lineid, '.png" alt="', lineid, '">');
		aTip.push('<img style="border:none; padding-top:2px;" src="/images/', lineid, '.png" alt="', lineid, '">');
	}
	aText.push("</div>");
	aTip.push("<br/></div>");
	this.createMarker(p, aText.join(""), icon, aTip.join(""));
}


/* Address lookup - todo: also add this to the Subway Class Someday */
Subway.prototype.loadXMLDoc = function(){
  var street = $("street").value;
  var city = $("city").value;
//	$('notice').innerHTML = "Looking up Address!";
	$('notice').innerHTML = "Adresse wird gesucht...";
	var str = "get_address.php?street="+street+"&city="+city;

//$('notice').innerHTML = str;

	doSimpleXMLHttpRequest(str).addCallback( bind(this.xmlhttpChange, this) ); 
}

Subway.prototype.xmlhttpChange = function(rslt){
	var xml = rslt.responseXML;
//	$('notice').innerHTML = "Plotting Address";
	$('notice').innerHTML = "Adresse wird eingezeichnet...";
	// getting lng & lat from response text
	var lat = xml.documentElement.getElementsByTagName('lat')[0].firstChild.nodeValue;
	var lng = xml.documentElement.getElementsByTagName('lng')[0].firstChild.nodeValue;
	var title = $("street").value;

  // Your Map Code HERE
	if (lng != 'fail'){
		lat = parseFloat(lat);
		lng = parseFloat(lng);
		this.plotAdd(lng, lat, title);
		this.hide(this.loadingID);
		if (!window.attachEvent){ sizeMapDiv(72); };
	}else{
//		$('loading').innerHTML = "<b>We're Sorry!</b> <i>The address you entered could not be found.</i> Please try again.";
		$('loading').innerHTML = "<p style='font-size:.7em;'><b>Es tut uns leid!</b> <i>Die gesuchte Adresse konnte nicht im Raum Berlin gefunden werden.</i> Bitte versuchen Sie es erneut.</p>";
		this.show(this.loadingID);	
		if (!window.attachEvent){ sizeMapDiv(102); }
		$('notice').innerHTML = '<a href="javascript:Berlin.loadXMLDoc()"><b>Suchen Sie erneut!</b></a>';  //HARDCODED - update this
	}
}

Subway.prototype.plotAdd = function(lon, lat, title) {
	var n = tempmarkers.length;
	tempmarkers[n] = [];

	var p = new GLatLng(parseFloat(lat), parseFloat(lon));
	tempmarkers[n].marker = new GMarker(p, addicon);
	tempmarkers[n].address = title;

	var esctitle = title.replace(/ /g, "+");
	var linkpath = "/?address=" + esctitle;
//	var aHTML = ["<div id='infowindow' style='white-space: nowrap; padding-right:16px;'><span style='font-size:16px; font-weight:bold; font-family:arial;'>", title, "</span><br/><br/><a href='", linkpath, "'>Link to Here</a>&nbsp;&nbsp;<a href='mailto:?body=", linkpath, "'>Email Link</a>&nbsp;&nbsp;<a href='javascript:addToFav(",n,")'>Add to Favorites</a>", "</div>"];
	var aHTML = ["<div id='infowindow' style='white-space: nowrap; padding-right:16px;'><span style='font-size:16px; font-weight:bold; font-family:arial;'>", title, "</span></div>"];
	tempmarkers[n].marker.my_html = aHTML.join("");

	this.map.addOverlay(tempmarkers[n].marker);
	this.map.panTo(p);
	tempmarkers[n].marker.openInfoWindowHtml(tempmarkers[n].marker.my_html);

	if('notice'){document.getElementById('notice').innerHTML=('<a href="javascript:Berlin.loadXMLDoc()"><b>Suche!</b></a>');};  //HARDCODED update this
}
