// -------- GReverseGeocoder ----------------------------------------
	function onGReverseGeocoderLoad(placemark) {
		var point = new GLatLng(placemark.RequestPoint.coordinates[1], placemark.RequestPoint.coordinates[0]);
		if(tripStepDecode > -1){
 		  var tmp = placemark.address.split(', ');
		  if(tripSteps[tripStepDecode]){
				tripSteps[tripStepDecode][3] = tmp[1]+', '+tmp[0];
			} else {
			  tripStepDecodeTxt = tmp[1]+', '+tmp[0];
			}
			writeSteps();
			tripStepDecode = -1;
			return 0;
		}
		if(tripBegin[3] == 1){
		  tripBegin[0] = '<div style="width:170px;text-align:left" class="fright">'+placemark.address+'</div><span class="bold">Z:</span><div class="clearfix"></div><span class="col_gray">@['+point.lat().toFixed(8)+',&nbsp;'+point.lng().toFixed(8)+']</span><br/>';
		  var tmp = placemark.address.split(', ');
		  tripBegin[5] = tmp[1]+', '+tmp[0];
			document.getElementById("trasainfo").innerHTML = tripBegin[0]+'<br/>'+tripEnd[0];
			document.getElementById('print_ti').getElementsByTagName('span')[0].innerHTML = placemark.address;
			document.trasa.fromi.value = tripBegin[5];
			tripBegin[3] = 0;		
		}
		if(tripEnd[3] == 1){
		  tripEnd[0] = '<div style="width:160px;text-align:left" class="fright">'+placemark.address+'</div><span class="bold">Do:</span><div class="clearfix"></div><span class="col_gray">@['+point.lat().toFixed(8)+',&nbsp;'+point.lng().toFixed(8)+']</span><br/>';
		  var tmp = placemark.address.split(', ');
		  tripEnd[5] = tmp[1]+', '+tmp[0];
			document.getElementById("trasainfo").innerHTML = tripBegin[0]+'<br/>'+tripEnd[0];
			document.getElementById('print_ti').getElementsByTagName('span')[1].innerHTML = placemark.address;
			document.trasa.toi.value = tripEnd[5];
			tripEnd[3] = 0;		
		}
	}

	function onGReverseGeocoderError() {
		var point;
		if(clickedPixel) point = map.fromContainerPixelToLatLng(clickedPixel);
		else point = dropPoint;
		if(tripStepDecode > -1){
		  if(tripSteps[tripStepDecode]){
				tripSteps[tripStepDecode][3] = 'Nieznana ulica';
			} else {
			  tripStepDecodeTxt = 'Nieznana ulica';
			}
			writeSteps();
			tripStepDecode = -1;
			return 0;
		}
		if(tripBegin[3] == 1){
		  tripBegin[0] = '<div style="width:170px;text-align:left" class="fright">Nieznana ulica</div><span class="bold">Z:</span><div class="clearfix"></div><span class="col_gray">@['+point.lat().toFixed(8)+',&nbsp;'+point.lng().toFixed(8)+']</span><br/>';
		  tripBegin[5] = 'Nieznana ulica';
			document.getElementById("trasainfo").innerHTML = tripBegin[0]+'<br/>'+tripEnd[0];
			document.getElementById('print_ti').getElementsByTagName('span')[0].innerHTML = 'Nieznana ulica';
			document.trasa.fromi.value = 'Nieznana ulica';
			tripBegin[3] = 0;		
		}
		if(tripEnd[3] == 1){
		  tripEnd[0] = '<div style="width:160px;text-align:left" class="fright">Nieznana ulica</div><span class="bold">Do:</span><div class="clearfix"></div><span class="col_gray">@['+point.lat().toFixed(8)+',&nbsp;'+point.lng().toFixed(8)+']</span><br/>';
			tripEnd[5] = 'Nieznana ulica';
			document.getElementById("trasainfo").innerHTML = tripBegin[0]+'<br/>'+tripEnd[0];
			document.getElementById('print_ti').getElementsByTagName('span')[1].innerHTML = 'Nieznana ulica';
			document.trasa.toi.value = 'Nieznana ulica';
			tripEnd[3] = 0;		
		}
  }
// -------- GReverseGeocoder ----------------------------------------	
	
// -------- GDirections ----------------------------------------------
	function onGDirectionsLoad(){ 
		//polyline = gdir.getPolyline();
		var points = []; 
  	var poly = gdir.getPolyline();
		for (var i = 0; i < poly.getVertexCount(); i++) {
			points[i] = poly.getVertex(i);
	  }
	  polyline = new GPolyline(points, "#0C337E", 4, 1); 		
		if(polyline){
		  tripBegin[1] = polyline.getVertex(0);
  		tripBegin[4].setLatLng( tripBegin[1] );
			tripEnd[1] = polyline.getVertex( polyline.getVertexCount()-1 );
  		tripEnd[4].setLatLng( tripEnd[1] );
			map.addOverlay(tripBegin[4]);
			map.addOverlay(tripEnd[4]);
		  var xx = polyline.getVertex(0);
			var minx = maxx = xx.lat();
			var miny = maxy = xx.lng();
			for(var i=1;i<polyline.getVertexCount();i++){
			  xx = polyline.getVertex(i);
				if(minx > xx.lat()) minx = xx.lat();
				if(maxx < xx.lat()) maxx = xx.lat();
				if(miny > xx.lng()) miny = xx.lng();
				if(maxy < xx.lng()) maxy = xx.lng();
			}
			if(changeZoomLvl)	map.setCenter(new GLatLng( minx+(maxx-minx)/2, miny+(maxy-miny)/2 ), map.getBoundsZoomLevel(new GLatLngBounds( new GLatLng(minx,miny), new GLatLng(maxx,maxy) )));
			//else map.setCenter(new GLatLng( minx+(maxx-minx)/2, miny+(maxy-miny)/2 ));
			map.addOverlay(polyline);
			//polyline.setStrokeStyle({color: '#4F821B', opacity:1});
			GEvent.addListener(polyline, 'mouseover', onPolylineMouseMove);
			GEvent.addListener(polyline, 'mouseout', onPolylineMouseOut);
			if(changePoint > -1){
			  tripSteps[changePoint][0] = findClosestPoint(polyline, tripSteps[changePoint][0]);
				tripSteps[changePoint][1].setLatLng(tripSteps[changePoint][0]);
				changePoint = -1;
			}
			var lt = gdir.getDistance().html.split('&nbsp;');
			tripLength = parseFloat(lt[0]+''+lt[1]);
			tripDuration = gdir.getDuration().html;
			document.getElementById("tdane").innerHTML = 'Długość: <span class="blacktxt">' + tripLength + ' km</span><br/>' + 'Czas jazdy: <span class="blacktxt">' + tripDuration + '</span> <span style="font-size:12px;padding:2px;color:#8888FF;" onmousemove="HINTmousemove(event,\'Czas jazdy jest jedynie informacją szacunkową i może się zmienić w zależności od warunków na drodze\',300,this)" onmouseout="HINTmouseout()">(?)</span>';
			document.getElementById("tdanebox").style.display = "";
			if(!wasInfoShown){
			  setTimeout("showInformation2()",500);
				wasInfoShown = true;
			}
		}
	}
	
  function onGDirectionsError(){
	  /*if (gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
	    alert("Nie znaleziono któregoś z podanych adresów");
	  else if (gdir.getStatus().code == G_GEO_SERVER_ERROR) 
	    alert("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + gdir.getStatus().code);
	  else if (gdir.getStatus().code == G_GEO_MISSING_QUERY) 
      alert("The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: " + gdir.getStatus().code);
//    else if (gdir.getStatus().code == G_UNAVAILABLE_ADDRESS)  <--- Doc bug... this is either not defined, or Doc is wrong
//      alert("The geocode for the given address or the route for the given directions query cannot be returned due to legal or contractual reasons.\n Error code: " + gdir.getStatus().code);
   else if (gdir.getStatus().code == G_GEO_BAD_KEY) 
     alert("The given key is either invalid or does not match the domain for which it was given. \n Error code: " + gdir.getStatus().code);
   else if (gdir.getStatus().code == G_GEO_BAD_REQUEST) 
     alert("A directions request could not be successfully parsed.\n Error code: " + gdir.getStatus().code);
   else alert("Wystąpił nieznany błąd.");*/
	}	
	
	function onPolylineMouseMove(){
	  isOnPolyline = true;
		if(!isDotDrageed && !isOnStepsPoint){
		  if(!isDotOnMap){
				map.addOverlay(dot);
				isDotOnMap = true;
			}
			dot.show();
		}
	}

	function onPolylineMouseOut(){
	  isOnPolyline = false;
		if(!isDotDrageed || isOnStepsPoint){ 
		  if(isDotOnMap){
			  //map.removeOverlay(dot);
				dot.hide();
				//isDotOnMap = false;
			}
		}
	}
	
// -------- GDirections ----------------------------------------------	
	
	
	
	
	
	
	
	
// -------- GMap -----------------------------------------------------

  function onGMapMouseMove(point){
	  if(isOnPolyline && !isDotDrageed && !isOnStepsPoint && !isStepPointDraged){
			dot.setLatLng(point);
			dot.show();
		}
		if(!isOnPolyline && !isDotDrageed){
		  dot.hide();
		}
/*		echo3.innerHTML  = 'isOnPolyline: '+isOnPolyline;
		echo3.innerHTML += '<br/>isDotDrageed: '+isDotDrageed;
		echo3.innerHTML += '<br/>isOnStepsPoint: '+isOnStepsPoint;
		echo3.innerHTML += '<br/>isStepPointDraged: '+isStepPointDraged;
		echo3.innerHTML += '<br/>isDotOnMap: '+isDotOnMap;*/
	}
	
	function onGMapMouseOut(){
	  hideMenuDiv();
	}

  function onGMapClick(obj, point, objpoint){
	  hideMenuDiv();
	  if(isStepPointClicked){
		  isStepPointClicked = false;
		}
		map.closeInfoWindow();
	}

	function onDotDragEnd(point){
		isDotDrageed = false;
		changeZoomLvl = false;
		
		var tab = new Array(4);		
		tab[0] = point;
		tab[2] = false;
		tab[3] = tripStepDecodeTxt;
		tab[1] = new GMarker(point,{draggable: true, icon:myIcon1, title:'Punkt pośredni'});
		GEvent.addListener(tab[1], 'mouseover', onStepsPointMouseOver);
		GEvent.addListener(tab[1], 'mouseout', onStepsPointMouseOut);
		GEvent.addListener(tab[1], 'dragstart', onStepsPointDragStart);
		GEvent.addListener(tab[1], 'drag', onStepsPointDrag);
		GEvent.addListener(tab[1], 'dragend', onStepsPointDragEnd);
		GEvent.addListener(tab[1], 'click', onStepsPointClick);
		map.addOverlay(tab[1]);
		  	
		if(tripPrevPointNr > -10){
		  if(tripPrevPointNr+1 == tripStepsCount) { tripSteps[tripStepsCount] = tab; tripStepDecode = tripStepsCount; } else
			if(tripPrevPointNr+1 < tripStepsCount){
			  for(var i=tripStepsCount; i>tripPrevPointNr+1; i--) tripSteps[i] = tripSteps[i-1];
				tripSteps[tripPrevPointNr+1] = tab;
				tripStepDecode = tripPrevPointNr+1;
			}
		}
		//tripStepDecode = tripStepsCount;
		reversegeocoder.reverseGeocode(point);
		
		changePoint = tripPrevPointNr+1;	// ustawiam aby direction loader poprawil koordynaty tego punktu
		tripPrevPointNr = -10;
		tripStepsCount++;
		map.removeOverlay(polyline);
		map.removeOverlay(tripBegin[4]);
		map.removeOverlay(tripEnd[4]);		
		var tripPoints = makeTripPoints();
		setDirections(tripPoints, 2);
		dot.setLatLng(new GLatLng(1,1));
		//map.removeOverlay(dot);
		dot.hide();
		tripStepDecodeTxt = '';
		writeSteps();
	}
	
  function onDotDragBegin(point){
	  isDotDrageed = true;
		var cpt = findClosestPoint(polyline, point);
		var cnr = getVertaxNr(polyline, cpt);
		if(cnr == -1) return;
		tripPrevPointNr = -1;
		for(var i=0; i<tripStepsCount; i++){
		  pt = getVertaxNr(polyline, tripSteps[i][0]);
			if(pt <= cnr) tripPrevPointNr = i;
			else break;
		}
	}
	
	function onStepsPointMouseOver(point){
	  if(!isDotDrageed){
		  if(isDotOnMap){
				//map.removeOverlay(dot);
				//isDotOnMap = false;
				dot.hide();
			}
	    isOnStepsPoint = true;
		}
	}

	function onStepsPointMouseOut(){
	  isOnStepsPoint = false;
		if(isOnPolyline){
		  //map.addOverlay(dot);
			dot.show();
		}
	}
	
	function onStepsPointDragStart(point){
	  isStepPointDraged = true;
		for(var i=0; i<tripStepsCount; i++){
		  if(point.equals(tripSteps[i][0])){
			  tripSteps[i][2] = true;
				break;
			}
		}
	}
	
	function onStepsPointDragEnd(point){
	  isStepPointDraged = false;
		changeZoomLvl = false;
		isOnStepsPoint = false;
		for(var i=0; i<tripStepsCount; i++){
		  if(tripSteps[i][2] == true){
			  tripSteps[i][2] = false;
			  tripSteps[i][0] = point;
				changePoint = i;
				var pts = makeTripPoints();
				map.removeOverlay(polyline);
				map.removeOverlay(tripBegin[4]);
				map.removeOverlay(tripEnd[4]);		
				setDirections(pts, 2);
				break;
			}
		}
	}
	
	function onStepsPointDrag(point){
	  //echo2.innerHTML = tripSteps[0][1].getLatLng().lat();
	}

	function onStepsPointClick(point){
//	  isStepPointClicked = true;
			var pkt = getPointNr(point);
			if(pkt > -1){
				text = 'Chcesz usunąć ten punkt?<br/><a href="" onclick="removePoint('+pkt+');return false;" class="underline">usuń punkt</a>';
				tripSteps[pkt][1].openInfoWindowHtml(text);
			} else alert("jest zle");
		
	}
	
	function onBeginMarkerDragEnd(point){
		tripBegin[3] = 1;
		dropPoint = point;
		reversegeocoder.reverseGeocode(point);	
	  tripBegin[1] = point;
		changeZoomLvl = false;
		if(tripEnd[4]){
			var pts = makeTripPoints();
			if(polyline) map.removeOverlay(polyline);
			if(tripBegin[4]) map.removeOverlay(tripBegin[4]);
			if(tripEnd[4]) map.removeOverlay(tripEnd[4]);		
			setDirections(pts, 2);
		}
	}
	
	function onEndMarkerDragEnd(point){
		tripEnd[3] = 1;
		dropPoint = point;
		reversegeocoder.reverseGeocode(point);	
	  tripEnd[1] = point;
		changeZoomLvl = false;
		if(tripBegin[4]){
			var pts = makeTripPoints();
			if(polyline) map.removeOverlay(polyline);
			if(tripBegin[4]) map.removeOverlay(tripBegin[4]);
			if(tripEnd[4]) map.removeOverlay(tripEnd[4]);		
			setDirections(pts, 2);
		}
	}
	
	
	
	
	
	
// -------- GMap -----------------------------------------------------








	
// -------- Inne funkcje ---------------------------------------------

// Funkcja wczytuje trase na podstawie otrzymanych danych. Zwracany wynik jest w języku polskim
// @params
// * type - gdy type=1 wtedy zmienna data ma postac ciagu znakow
//          gdy type=2 wtedy data ma postac tablicy punktow LatLng
// * data - dane potrzebne do wczytania
	function setDirections(data, type) {
		if(type == 1){
			gdir.load(data,{ locale: "PL", getPolyline: true, getSteps: true  });
		}
		if(type == 2){
			gdir.loadFromWaypoints(data, {locale:"PL", getPolyline: true, getSteps: true });
		}
	}
	
// Funkcja tworzy tablice punktów LatLng na podstawie wprowadzonej trasy	
	function makeTripPoints(){
		var tripPoints = new Array(tripStepsCount+2);
		tripPoints[0] = tripBegin[1];
		for(i=0; i<tripStepsCount; i++){
		  tripPoints[i+1] = tripSteps[i][0];
		}
		tripPoints[tripStepsCount+1] = tripEnd[1];
		return tripPoints;
	}

// Funkcja zwraca najblizszy punk na linii
// @params
// * poly - polyline na którym wyszukujemy punktu
// * pt - punkt co do którego mamy znaleźć najbliższy punkt
  function findClosestPoint(poly, pt){
	  var ret = poly.getVertex(0);
		var c_distance = Math.sqrt( sqr(pt.lat() - ret.lat()) + sqr(pt.lng() - ret.lng()) );
		for(var i=1;i<poly.getVertexCount();i++){
		  tmpv = poly.getVertex(i);
			tmpd = Math.sqrt( sqr(pt.lat() - tmpv.lat()) + sqr(pt.lng() - tmpv.lng()) );
			if(tmpd < c_distance){
			  ret = tmpv;
				c_distance = tmpd;
			}
		}
	  return ret;
	}
	
	
	function getVertaxNr(_poly, _pt){
	  var nr = -1;
		for(var i=0;i<_poly.getVertexCount();i++){
			if(_pt.equals(_poly.getVertex(i))){
			  nr = i;
				break;
			}
		}
		return nr;
	}

// Funkcja wyszukująca punkt posredni na podstawie zadanych koordynatow LatLng;
// @params
// * _point - punkt LatLng
	function getPointNr(_point){
		for(var i=0; i<tripStepsCount; i++){
		  if(_point.equals(tripSteps[i][0])) return i;
		}
		return -1;
	}

	
	function writeSteps(){
	  var sbox = document.getElementById("daneinfosteps");
	  if(tripStepsCount == 0){
			sbox.style.display = 'none';
		  return 0;
		}
		sbox.style.display = '';
		sbox.innerHTML = '<span class="bold">Przez:</span><br/>';
		for(var i=0; i<tripStepsCount; i++){
		  sbox.innerHTML += '<div style="margin-top:5px"><a href="javascript:removePoint('+i+');"><img src="/gfx/x_minus2.gif" alt="" class="fright" style="position:relative;top:4px"/></a>'
		  sbox.innerHTML += tripSteps[i][3]+'<br/><span class="col_gray">@['+tripSteps[i][0].lat().toFixed(8)+',&nbsp;'+tripSteps[i][0].lng().toFixed(8)+']</span></div>';
		}
	}
	
	
	function removePoint(nr){
	  if(nr > -1){
		  tripSteps[nr][1].closeInfoWindow();
			map.removeOverlay(tripSteps[nr][1]);
			for(var i=nr; i<tripStepsCount-1; i++) tripSteps[i] = tripSteps[i+1];
			tripStepsCount--;		  
			var pts = makeTripPoints();
			map.removeOverlay(polyline);
			map.removeOverlay(tripBegin[4]);
			map.removeOverlay(tripEnd[4]);		
			setDirections(pts, 2);
			writeSteps();
		}
	}
	

// Funkcja podająca kwadrat liczby
// @params
// * val - liczba która ma być podniesiona do kwadratu
	function sqr(val){ return val * val; } 
	
// -------- Inne funkcje ---------------------------------------------
	
	
// -------- Funkcje: SG Po drodze ---------------------------------------------
	
	function showInformation1(){
	  map.openInfoWindowHtml(map.getCenter(),'Aby wyznaczyć trasę skorzystaj albo z wyszukiwarki po lewej, albo kliknij prawym przyciskiem myszy na mapie i określ miejsca w których ma się zaczynać i kończyć trasa.<br/><br/><a href="" class="underline" onclick="map.closeInfoWindow();return false;">zamknij to okno</a>',{maxWidth:400});
	}
	
	function showInformation2(){
	  map.openInfoWindowHtml(map.getCenter(),'Możesz zmieniać przebieg trasy poprzez chwycenie i przeciągnięcie czerwonej kropki, która pojawi się gdy najedziesz myszką na linię trasy.<br/><br/>Możesz także dodać punkt pośredni klikając prawym przyciskiem myszy w tym miejscu.<br/><br/>Punkt pośredni możesz chwycić i przesunąć.<br/><br/><a href="" class="underline" onclick="map.closeInfoWindow();return false;">zamknij to okno</a>',{maxWidth:400});
	}
	
	
	
	
	
	
// -------- Funkcje: SG Po drodze ---------------------------------------------
	
	
	
	
	
	
	
	
	
