// arrays to hold copies of the markers and html used by the sidebar
// because the function closure trick doesnt work there
var gmarkers = new Array();
var gbound = new Array();
var glines = new Array();
var gcolors = new Array();
var gsearches = new Array();
var overlayimeis = new Array();
var searches = false;
var IMEI = null;

// other global variables
var request = GXmlHttp.create();
var icons = new Array();
var trigger = true;
var firstload = true;
var secondload = true;
var contentId = 0;
var updater = null;
var Bound = null;

// create the map
var map = null;
var minimap = null;
var TypeControl = null;
var ZoomControl = null;
var mini = null;

//visibles for toggling groups from the sidebar
var visibles = new Array(2);
visibles[0] = new Array(); //show on map
visibles[1] = new Array(); //expand on sidebar

function floats2WGS(x, y) {
	var tmp = x > 0 ? x+"&#176;N " : (x*-1)+"&#176;S ";
	tmp += y > 0 ? y+"&#176;E " : (y*-1)+"&#176;W ";
	tmp += "- WGS84";
	return tmp;
}

function showTimezone(utc) {
	if(utc == 0) {
		utc = "+/- 0";
	} else if(utc > 0) {
		utc = "+"+utc;
	}

	return LANG_UTC_FORMAT+utc;
}

/*
 * starts the whole service
 */
function GPSplayer() {
	if(!GBrowserIsCompatible()) {
		alert('Ihr Browser wird nicht unterstuetzt');
	}
	map = new GMap(document.getElementById('map'));
	map.addMapType(G_PHYSICAL_MAP);
	minimap = new GOverviewMapControl(new GSize(170, 130));
	TypeControl = new GHierarchicalMapTypeControl();
	ZoomControl = new DragZoomControl({}, { 
          buttonStartingStyle: {display:'none',color:'black',background:'white',width:'7em',textAlign:'center',
          fontFamily:'Verdana',fontSize:'12px',fontWeight:'bold',border:'1px solid gray',paddingBottom:'1px',cursor:'pointer'},
          buttonHTML: '',
          buttonZoomingHTML: LANG_ZOOM_ZOOMING,
          buttonZoomingStyle: {background:'yellow'},
          backButtonHTML: LANG_ZOOM_BACK,  
          backButtonStyle: {display:'none',marginTop:'3px',background:'#FFFFC8'},
          backButtonEnabled: true
        }, {}), new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(7,39));

	map.setCenter(new GLatLng(user.lat, user.lng), 2);
	map.addControl(ZoomControl);
	map.addControl(new GScaleControl(200));
	map.enableContinuousZoom();
	map.enableDoubleClickZoom();
	map.addControl(minimap);
	mini = minimap.getOverviewMap();

	//Zoom, Center, Go
	GMap.prototype.centerAndZoomOnBounds = function(bounds) {
		var bound = new GLatLngBounds();
		bound.extend(new GLatLng(bounds.left, bounds.bottom));
		bound.extend(new GLatLng(bounds.right, bounds.top));
		var zoomlevel = map.getBoundsZoomLevel(bound);
		zoomlevel = zoomlevel > user['zoomlevel'] ? user['zoomlevel'] : zoomlevel;
		map.setCenter(new GLatLng(bounds.centerx, bounds.centery), zoomlevel);
	}
	
	GEvent.addListener(map, "maptypechanged", function() {
		//Localization???
		switch(map.getCurrentMapType().getName()) {
			case 'Satellit':
				user_map = G_SATELLITE_MAP;
				form_maptype('G_SATELLITE_MAP');
			break;
			case 'Karte':
				user_map = G_NORMAL_MAP;
				form_maptype('G_NORMAL_MAP');
			break;
			case 'Hybrid':
				user_map = G_HYBRID_MAP;
				form_maptype('G_HYBRID_MAP');
			break;
		}
	});
	
	//Shows the buttons to switch between map view types
	GEvent.addListener(map, "mouseover", function(){
		map.addControl(TypeControl);
	});
	
	//Hides the buttons to switch between map view types
	GEvent.addListener(map, "mouseout", function(){
		map.removeControl(TypeControl);
	});
	
	//Show the Coordinates of the Mousepointer
	GEvent.addListener(map, "mousemove", function(point){
		document.getElementById('position').innerHTML = floats2WGS(point.y.toFixed(4), point.x.toFixed(4));
	});
	
	//Show the Bounce of the current view
	GEvent.addListener(map, "dragend", function(){
		//trigger = true;
	});
	
	//Show the Bounce of the current view
	GEvent.addListener(map, "zoomend", function(){
		if(!firstload) {
			//cleanmarkers();
			//cleanlines();
		}
		if(firstload)trigger = true;
	});
	
	updater = window.setTimeout("startUpdater()", 10);
}

/**
 * refresh
 */
function refresh() {
	secondload = true;
	trigger = true;
}

/**
 * calls the ajax function to update the json file
 */
function startUpdater() {
	if(!form_login(0, 0, 0))
		return;

	document.getElementById('status').style.color = '#ffffff';

	if(trigger) {
		trigger = false;
		ajax();
		map.setMapType(user_map);
		if(mini!=null)mini.setMapType(user_minimap);
		document.getElementById('status').innerHTML = new Date().toLocaleString()+"<!--<br />"+
			"<a href=\"json.php?login="+login+"&user_id="+user['id']+"&limit="+limit+"&user_pw="+user['pw']+"&size="+map.getSize()+"&bounds="+map.getBounds()+"&firstload="+firstload+"&modus="+(travellermodus)+"&utc="+utctime+"\">size="+map.getSize()+"&bounds="+map.getBounds()+"</a>//-->";
		document.getElementById('status').style.color = '#ff0000';

		if(contentId == 5)
			content(5,0);
	}
	updater = window.setTimeout("startUpdater()", 1300);
}

/**
 * stops the recursive update process and the image loading
 */
function stopPlayer() {
	window.clearTimeout(updater);
	stop();
}


/*
 * cleans all overlays and global array (after change of zoom)
 */
function cleanmarkers() {
	for(var i in gmarkers) {
		for(var j in gmarkers[i])
			for(var k in gmarkers[i][j])
				map.removeOverlay(gmarkers[i][j][k]);
	}
	gmarkers = new Array();
}


/*
 * cleans line overlays
 */
function cleanlines() {
	for(var i in glines) {
		for(var j in glines[i])
			map.removeOverlay(glines[i][j]);
	}
	glines = new Array();
}


/**
 * menue toggle (visibility)
 * @param group -> group (IMEI)
 * @param sub -> subgroup (date)
 * @param html -> html button to be changed
 */
function showHide(group, sub, html) {
	if(visibles[0][group][sub]) {
		for(var j in gmarkers[group][sub]) 
			map.removeOverlay(gmarkers[group][sub][j]);
	
	        if(glines[group] != null && glines[group][sub] != null)
			map.removeOverlay(glines[group][sub]);

		html.innerHTML = 'O';
		visibles[1][group][sub] = false;
		document.getElementById('sidebar-'+group+'-'+sub).style.display = 'none';
	} else {
		if(html == null)
			html = document.getElementById('c-'+group+'-'+sub);

		for(var j in gmarkers[group][sub]) 
			map.addOverlay(gmarkers[group][sub][j]);
		
		html.innerHTML = 'X';
		if(glines[group] != null && glines[group][sub] != null) {
			try {
				map.addOverlay(glines[group][sub]);
			} catch(e) {
				window.defaultStatus = 'Fehler gefangen';
			}
		}
	}
	visibles[0][group][sub] = !visibles[0][group][sub];
}

/**
 * menue toggle (visibility)
 * @param group -> Group (IMEI)
 * @param sub -> Subgroup (date)
 */
function expand(group, sub) {
	visibles[1][group][sub] = !visibles[1][group][sub];
	var style = document.getElementById('sidebar-'+group+'-'+sub).style;
	style.display = visibles[1][group][sub] ? 'block' : 'none';
}


/**
 * changes the view of the overview map
 * @param type -> google constant
 */
function setMinimapType(type) {
	user_minimap = type;
	minimap.setMapType(user_minimap);
}

/**
 * changes the view of the map
 */
function setMapType(type) {
	map.setMapType(type);
}

/**
 * color of the icon
 * @param iconColor -> color of the icon
 * @param size -> size of the marker
 */
function createIcon(iconColor, size) {
	if(!icons[size+iconColor]) {
		icons[size+iconColor] = new GIcon();
		if(size == 20) {
			//icons[size+iconColor].shadow = "iconsets/mm_20_shadow.png";
			icons[size+iconColor].iconSize = new GSize(12, 20);
			//icons[size+iconColor].shadowSize = new GSize(22, 20);
			icons[size+iconColor].iconAnchor = new GPoint(6, 20);
		} else {
			icons[size+iconColor].iconSize = new GSize(10, 10);
			icons[size+iconColor].iconAnchor = new GPoint(5,5);
		}
		icons[size+iconColor].infoWindowAnchor = new GPoint(5, 1);
		icons[size+iconColor].image = "iconsets/mm_"+ size +"_"+ iconColor +".png";
	}
	return icons[size+iconColor];
}

/**
 * zooms in
 */
function z() {
	map.zoomIn();
	map.zoomIn();
}

/**
 * A function to create a tabbed marker and set up the event window
 * This version accepts a variable number of tabs, passed in the arrays htmls[] and labels[]
 * @param point
 * @param label
 * @param tab
 * @param icon
 * @param group -> group (IMEI)
 * @param sub -> subgroup (date)
 * @param size
 */
function createMarker(point, label, tab, icon, group, sub, size, labeled) {
	// Overwrite proprietary tabs to GMaps Tabs
	var position = floats2WGS(point.y, point.x);
	tab[0].text = '<b>'+group+'</b>: '+label+' '+showTimezone(utctime)+'<br /><font color="#595959">Position: '+position+'</font>'+
		'<br /><font color="#afafaf">'+LANG_HEIGHT+': '+tab[0].text+' '+LANG_HEIGHT_METRIC+'</font>';
	if(icon != 'yellow') {
		tab[0].text += "<br/>"+LANG_STATUS+": "+LANG_STATUS_MAP[icon];
	}
	tab[0].text += '<br /><a href="#" onclick="z()"><img src="iconsets/zoom.gif" align="left" /> '+LANG_ZOOM_HERE+'</a>';

	for(var i=0; i<tab.length; i++) {
		tab[i] = new GInfoWindowTab(tab[i].title, tab[i].text);
	}
	
	var baseIcon = new Array("http://www.easy-coding.de/wcf/icon/g-map/marker0000.png", 50, -16, -9);

	// options: basic
	var opts = {
		"icon": icon,
		"clickable": true,
		"labelOffset": new GSize(baseIcon[2], baseIcon[3])
	};
	opts.labelText = "label";
	//var marker = new LabeledMarker(point, opts);

	// Extend the global Marker Array
	var marker = new GMarker(point, createIcon(icon, size));
	marker.tabs = tab;

	if(group == uncategorized && sub == serps) {
		searches = true;
		gsearches[label] = marker;
		var ob = gsearches[label];
	} else {
		gmarkers[group][sub][label] = marker;
		gmarkers[group][sub][label].color = icon;
		var ob = gmarkers[group][sub][label];
	}

	// Add Clickevent
	GEvent.addListener(ob, "click", function() {
		marker.openInfoWindowTabsHtml(ob.tabs);
	});

	if(visibles[0][group][sub] == true)
		map.addOverlay(ob);
}


/**
 * This function picks up the click and opens the corresponding info window
 * @param i
 * @param group
 * @param sub
 */
function show(i, group, sub) {
	if(!visibles[0][group][sub]) {
		showHide(group, sub, null);
	}

	GEvent.trigger(gmarkers[group][sub][i], "click");
}

/**
 * GeoCoder Search
 */
function searchAddress() {
	var query = document.getElementById("search_street").value + " " + document.getElementById("search_city").value + " " +
			document.getElementById("search_country").value;

	var geo = new GClientGeocoder();
	geo.getLocations(query, function (result) {
		var geostatus=[];
		geostatus[G_GEO_SUCCESS]            = LANG_MY_SUCCESS;
		geostatus[G_GEO_MISSING_ADDRESS]    = LANG_MY_MISSING_ADDRESS;
		geostatus[G_GEO_UNKNOWN_ADDRESS]    = LANG_MY_UNKNOWN_ADDRESS;
		geostatus[G_GEO_UNAVAILABLE_ADDRESS]= LANG_MY_UNAVAILABLE_ADDRESS;
		geostatus[G_GEO_BAD_KEY]            = LANG_MY_BAD_KEY;
		geostatus[G_GEO_TOO_MANY_QUERIES]   = LANG_MY_TOO_MANY_QUERIES;
		geostatus[G_GEO_SERVER_ERROR]       = LANG_SERVER_ERROR;

		// check status code
		if(result.Status.code != G_GEO_SUCCESS) {
			alert(geostatus[result.Status.code]);
			return;
		}

		if(visibles[0][uncategorized] == null) visibles[0][uncategorized] = new Array();
		if(visibles[0][uncategorized][serps] == null) visibles[0][uncategorized][serps] = new Array();
		if(visibles[1][uncategorized] == null) visibles[1][uncategorized] = new Array();
		if(visibles[1][uncategorized][serps] == null) visibles[1][uncategorized][serps] = new Array();

		var point = new GLatLng(result.Placemark[0].Point.coordinates[1], result.Placemark[0].Point.coordinates[0]);
		var zoomlevel = 4* (result.Placemark[0].address.split(",").length);		
		var tab = new Array(2);
		tab[0] = new Object();
		tab[0].title = 'Info';
		tab[0].text = '';
		tab[1] = new Object();
		tab[1].title = 'Ergebnis';
		tab[1].text = result.Placemark[0].address;
		
		map.setZoom(zoomlevel);
		map.panTo(point);
		createMarker(point, query, tab, 'yellow', uncategorized, serps, 20, false);
		visibles[0][uncategorized][serps][query] = true;
		visibles[1][uncategorized][serps][query] = true; //expand in sidebar
		GEvent.trigger(gsearches[query], "click");
	});
}

/**
 * Reads the data from xml file
 */
function ajax() {
	try {
		request.open("POST", "json.php");
		request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		request.onreadystatechange = processJSON;
		request.send("login="+login+"&limit="+limit+"&user_id="+user['id']+"&user_pw="+user['pw']+"&size="+map.getSize()+"&bounds="+map.getBounds()+"&firstload="+firstload+"&modus="+(travellermodus)+"&utc="+utctime);
	} catch(e) {
//		alert('CONNECTION ERROR');
		trigger = true;
	}
}

function smallmarker(pos) {
	var icon = new GIcon();
	icon.image = "iconsets/station.png";
	icon.iconSize = new GSize(14, 14);
	icon.iconAnchor = new GPoint(7, 7);
	icon.infoWindowAnchor = new GPoint(7, 4);

	return new GMarker(pos, {icon: icon, clickable: "true", labelOffset: new GSize(0, 0)});
}

/**
 * Handle the XML File and build the gmarkers Array
 */
function processJSON() {
	if(request.readyState == 4) {
		if(request.status != 200 && request.status != 304) {
		        alert("JSON Object not available");
		        return;
		}
		// Get JSON Object	
		var JSON = eval("(" + request.responseText + ")");
		var gcolors = JSON.color;
		utctime = JSON.utc;
		IMEI = JSON.I;
		Bound = JSON.bounds['9*7*5*3*1'];
		
		// update display timezone
		document.getElementById('timezone').innerHTML = showTimezone(utctime);
		
		//zoom, zoom, zoom
		if(firstload) {
			map.centerAndZoomOnBounds(Bound);
			firstload = false;
			return;
		}
		
		if(!secondload) //UPDATE: Wir verhindern das Nachladen
			return;

		// reset all
		cleanlines();
		cleanmarkers();
		visibles = new Array(2);
		visibles[0] = new Array(); //show on map
		visibles[1] = new Array(); //expand on sidebar

		// clear static data
		map.clearOverlays();
		
		// we never change overlay + static markers
		if(overlayimeis.length == 0 || true) {
			//overlays
		        for(var imei in JSON['overlay']) {
		                if(overlayimeis.length == 0) overlayimeis.push(new Array(JSON['overlay'][imei]['imei'], JSON['overlay'][imei]['name']));
		                myline = new GPolyline.fromEncoded({color: "#"+JSON['overlay'][imei]['color'], weight:JSON['overlay'][imei]['strength'], opacity:0.9, points: JSON['overlay'][imei]['points'], levels: JSON['overlay'][imei]['levels'],zoomFactor:2,numLevels: 18});
		                map.addOverlay(myline);
		        }
	
			//labels
			for(var imei in JSON['labels']) {
				for(var x in JSON['labels'][imei]) {
					var label924 = new TLabel();
					label924.id = 'label'+x;
					label924.anchorLatLng = new GLatLng(JSON['labels'][imei][x].lat, JSON['labels'][imei][x].lng);
					map.addOverlay(smallmarker(label924.anchorLatLng));
					label924.anchorPoint = 'bottomLeft';
					label924.content = "<div style='background-color:#ffffff'>"+JSON['labels'][imei][x].txt+"</div>";
					//label924.percentOpacity = 70;
					map.addTLabel(label924);
				}
			}
		}

		var xxx=0;
		//Iterate through groups/imeis
		for(var G in JSON['P']) {
			if(gbound[G] == null) gbound[G] = JSON.bounds[G];
			if(gmarkers[G] == null) gmarkers[G] = new Array();
			if(glines[G] == null) glines[G] = new Array();
			if(visibles[0][G] == null) visibles[0][G] = new Array();
			if(visibles[1][G] == null) visibles[1][G] = new Array();

			//Iterate through subgroups/days
			for(var D in JSON['P'][G]) {
				var X = D.replace(/\./g, "");
				//Set visibles for new Days
				if(visibles[0][G][D] == null) {
					visibles[0][G][D] = secondload || travellermodus != 'default' ? true : false;
				}
				
				//Create group if it does not exist
				if(gmarkers[G][D] == null) gmarkers[G][D] = new Array();
				
				//Add points
				for(var m in JSON['P'][G][D]['labels']) {
					var P = JSON['P'][G][D]['labels'][m];
					var point = new GLatLng(P.lat, P.lng);
					if(!gmarkers[G][D][P.label]) createMarker(point, P.label, P.tab, P.icon, G, D, P.size, true);
				}

				//Add line
				if(JSON['P'][G][D]['points'] != '') {
					glines[G][D] = new GPolyline.fromEncoded({color: "#"+JSON['P'][G][D]['color'], weight: '4', opacity:0.9, points: JSON['P'][G][D]['points'], levels: JSON['P'][G][D]['levels'],zoomFactor:2,numLevels: 18});
					if(visibles[0][G][D] == true) {
	//					try {
						map.addOverlay(glines[G][D]);
	//					} catch(e) {
	//					}
					}
				}
				
				secondload = false;
			}
		}

		if(contentId == 0) content(0,0);
	}
}

/**
 * creates the alternative sidebar for travellers (without days)
 */
function alternativesidebar() {
       var sidebar = "", count2, tmp, tmp2="", color="";
       var firstMarker = new Array(0,0,0);

	if(searches == true) {
		gmarkers[uncategorized] = new Array();
		gmarkers[uncategorized][serps] = gsearches;
	}

        for(var group in gmarkers) {
		count2 = 0;
		tmp2="";
	
		for(var sub in gmarkers[group]) {
	                tmp="";
	                count3=0;
	
			//Positions
			for(var pos in gmarkers[group][sub]) {
				if(count2==0 && count3++ == 0) {
					color = gmarkers[group][sub][pos].color;
					firstMarker = new Array(pos,group,sub);
				}
				tmp += (count2>0?'<br />':'')+
					'<a href="#" onclick="show(\'' +pos+ '\', \'' +group+ '\', \'' +sub+ '\')">' + pos + '</a>';
				++count2;
			}
			tmp2 += tmp;
		}
		
		//subgroup (there are no subgroups - just for div outside)
		tmp2 = '<div id="s'+group+'" class="sideblock" style="'+(count2>9?'height:100px':'')+ '">'+tmp2+'</div>';

		//Group
		sidebar += '<b><a href="#" style="color:'+color+'" onclick="map.centerAndZoomOnBounds(gbound[\''+group+'\']);show(\'' +firstMarker[0]+ '\', \'' +firstMarker[1]+ '\', \'' +firstMarker[2]+ '\')">'+ group +'</a></b> (<i>'+count2+'</i>)<br />'+tmp2+'<br />';
		
        }
	return sidebar;
}


/**
 * creates the sidebar
 */
function sidebar() {
	if(travellermodus != 'default')
		return alternativesidebar();

        var sidebar = "", count, count2, tmp, tmp2="", color="";
        var firstMarker = new Array(0,0,0);

	if(searches == true) {
		gmarkers[uncategorized] = new Array();
		gmarkers[uncategorized][serps] = gsearches;
	}

        for(var group in gmarkers) {
		count2 = 0;
		tmp2="";
	
		for(var sub in gmarkers[group]) {
	                count = 0;
	                tmp="";
	
			//Positions
			for(var pos in gmarkers[group][sub]) {
				if(count == 0 && count2==0) {
					color = gmarkers[group][sub][pos].color;
					firstMarker = new Array(pos,group,sub);
				}
				tmp += (count>0?'<br />':'')+
					'<a href="#" onclick="show(\'' +pos+ '\', \'' +group+ '\', \'' +sub+ '\')">' + pos + '</a>';
				++count;
				++count2;
			}

			//subgroup = days
			tmp2 += '&raquo; <a href="#" onclick="expand(\'' +group+ '\', \'' +sub+ '\')">' +sub+ '</a> ('+ count +') '+
					'<a href="#" id="c-' +group+ '-' +sub+ '" onclick="showHide(\'' +group+ '\', \'' +sub+ '\', this)">'+ (visibles[0][group][sub]?'X':'O') +'</a><br />'+
					'<div id="sidebar-' +group+ '-' +sub+ '" class="sideblock" '+
					'style="display:' +(visibles[1][group][sub]?'block':'none')+(count>9?';height:100px':'')+ '">'+
					tmp+'</div>';
		}

		//Group = devives
		sidebar += '<b><a href="#" style="color:'+color+'" onclick="map.centerAndZoomOnBounds(gbound[\''+group+'\']);show(\'' +firstMarker[0]+ '\', \'' +firstMarker[1]+ '\', \'' +firstMarker[2]+ '\')">'+ group +'</a></b> (<i>'+count2+'</i>)<br />'+tmp2+'<br />';
		
        }
	return sidebar;
}

