var apiKey = 'ABQIAAAATl1qlNh1LwB9RqZqpT699xQBIh6mG96lAQDDdhSQlhn85gDlmBQ5TFPit82DegGbminRgbb8CBzhHQ';
var apiKey_skm = 'ABQIAAAATl1qlNh1LwB9RqZqpT699xQBIh6mG96lAQDDdhSQlhn85gDlmBQ5TFPit82DegGbminRgbb8CBzhHQ';
var map = false;
var tory = r_tory = false;
var spd = 0.5;
var ovlMarker = false;
var encLine = false;
var area = false;
var areaOdDo = false;
var stopTime = 40; //blink time
var currPoc = false;
var domain = 'http://www.skm.pkp.pl/';
var GProj = false;
var odDef = false;
var doDef = false;

function print_r(theObj){
  if(theObj.constructor == Array ||
     theObj.constructor == Object){
    document.write("<ul>")
    for(var p in theObj){
      if(theObj[p].constructor == Array||
         theObj[p].constructor == Object){
		document.write("<li>["+p+"] => "+typeof(theObj)+"</li>");
        document.write("<ul>")
        print_r(theObj[p]);
        document.write("</ul>")
      } else {
		document.write("<li>["+p+"] => "+theObj[p]+"</li>");
      }
    }
    document.write("</ul>")
  }
}


function initMapSmall()
{
	if (!map)
	{
		var script = document.createElement("script");
		script.type = "text/javascript";
		script.src = "http://maps.google.com/maps?file=api&v=2.x&key="+apiKey+"&async=2&callback=_initMapSmall";
		document.body.appendChild(script);
	}
}

function initMap()
{
	if (!map)
	{
		var script = document.createElement("script");
		script.type = "text/javascript";
		script.src = "http://maps.google.com/maps?file=api&v=2.x&key="+apiKey+"&async=2&callback=_initMap";
		document.body.appendChild(script);
	}
}

function _initMapSmall()
{
	map_id = 'map_canvas_small';
	if (GBrowserIsCompatible())
    {
        map = new GMap2(document.getElementById(map_id));
        if (!map)
        {
            alert('Nie udało się połaczyć z maps.google.com');
            return false;
        }
   		map.addControl(new GSmallZoomControl3D());
 		area = new GLatLngBounds();
		areaOdDo = new GLatLngBounds();
		map.addControl(new GMenuMapTypeControl());
		map.enableScrollWheelZoom();
		map.setMapType(G_NORMAL_MAP);
		pokazTrase();
		encLine = decodeLine(document.getElementById('polylineC').value);
		rysujPolilinie(encLine);
		rzucStacje();
		if (odDef && doDef)
			zoomToViewMyWay();
		else
			zoomToViewAllMarkers();
		return true;
    }
    else
    {
        alert("Twoja przegladarka nie jest kompatybilna z Google Maps API");
        return false;
    }
}

function _initMap()
{
	map_id = 'map_canvas';
    if (GBrowserIsCompatible())
    {
        map = new GMap2(document.getElementById(map_id));
        if (!map)
        {
            alert('Nie udało się połaczyć z maps.google.com');
            return false;
        }
   		map.addControl(new GSmallZoomControl3D());
 		area = new GLatLngBounds();
		
		map.addControl(new GMenuMapTypeControl());
		map.enableScrollWheelZoom();
		map.setMapType(G_NORMAL_MAP);//G_NORMAL_MAP
		//GProj = map.getProjection();
		pokazTrase();
		area = new GLatLngBounds();
		encLine = decodeLine(document.getElementById('polylineC').value);
		rysujPolilinie(encLine);
		rzucStacje();
		addGMarkers();
		zoomToViewAllMarkers();
		setInterval(runSkm, Math.ceil(1000/spd));		
		return true;
    }
    else
    {
        alert("Twoja przegladarka nie jest kompatybilna z Google Maps API");
        return false;
    }
}

function pokazTrase()
{
    if (!map) return;
    var point = new GLatLng(54.366158, 17.795105);
    map.setCenter(point, 9);
	return false;
}

function rysujPolilinie(coordsArr, f)
{
    if (!map) return;
	var points = new Array();
	for (var i = 0; i < coordsArr.length; ++i)
		points[i] = new GLatLng(coordsArr[i][0],coordsArr[i][1]);
	op = f ? f : 0.9;
 	tory = new GPolyline(points, '#0000ff', 4, op, '#ff0000', 0.05);
	var r_points = new Array();
	var n=0;
	for (var i = coordsArr.length-1; i>=0 ; --i,++n)
		r_points[n] = new GLatLng(coordsArr[i][0],coordsArr[i][1]);
 	r_tory = new GPolyline(r_points, '#0000ff', 4, op, '#ff0000', 0.05);
	map.addOverlay(tory);
}

function rzucStacje()
{
	var trasa = false;
	var vod=false, vdo=false;
	var points = new Array();
	var marker = false;
	var od_do = false;
	/*for (var i=0; i<stacje.length; ++i)
		if (stacje[i].sod) {
			trasa = true;
		}*/
		//print_r(stacje);
for (var i=0; i<stacje.length; ++i) {
		ll = tory.getVertex(stacje[i].v);
		if (stacje[i].sod) {
			vod = stacje[i].v;
			trasa = trasa ? false : true;
			area.extend(ll);
			if (areaOdDo)
			{
				areaOdDo.extend(ll);
				odDef = true;
			}
			marker = createMarker(ll, 'Stacja: <b>'+stacje[i].n+'</b><br/>' + stacje[i].kasy_str+'<br/>' +stacje[i].aut_str+'<br/>Stacja początkowa', domain+'fileadmin/templates/main/img/marker-station-start.png', null, 10, false);
		}
		else if (stacje[i].sdo) {
			vdo = stacje[i].v;
			trasa = trasa ? false : true;
			area.extend(ll);
			if (areaOdDo)
			{
				areaOdDo.extend(ll);
				doDef = true;
			}
			marker = createMarker(ll, 'Stacja: <b>'+stacje[i].n+'</b><br/>' + stacje[i].kasy_str+'<br/>' +stacje[i].aut_str+'<br/>Stacja końcowa', domain+'fileadmin/templates/main/img/marker-station-stop.png', null, 10, false);
		}
		else {
			icon = trasa ? domain+'fileadmin/templates/main/img/marker-station-trip.png' : domain+stacje[i].ic;
			marker = createMarker(ll, 'Stacja: <b>'+stacje[i].n + '</b><br/>' + stacje[i].kasy_str+'<br/>' +stacje[i].aut_str+'<br/>', icon, null, 10, false);
			area.extend(ll);
		}
		map.addOverlay(marker);
	}
	if (vod && vdo>vod) {
		for (var i = vod; i<=vdo; ++i)
			points[i] = new GLatLng(encLine[i][0],encLine[i][1]);
		map.addOverlay(new GPolyline(points, '#FF0000', 4, 0.8, '#ff0000', 0.05));
	}
}

function getProperVertex(v, p)
{
	return p ? v : tory.getVertexCount()-v-1;
}

function rzucPociag(poc_i, time)
{
	var s = poc[poc_i].s;
	var len = s.length;
	if (s[0].t>time || s[len-1].t<time)	{
		if (poc[poc_i].p) {
			map.removeOverlay(poc[poc_i].p);
			poc[poc_i].p = false;
		}
		return false;
	}
	p = (poc[poc_i].nr%2)==0;
	va = vb = aTime = dTime = -1;
	for (var i=0; i<len; ++i)
		if (s[i].t<time && s[i+1] && s[i+1].t>time) {
			va = getProperVertex(s[i].v, p);
			vb = getProperVertex(s[i+1].v, p);
			aTime = parseInt(s[i].t, 10);
			bTime = parseInt(s[i+1].t, 10);
			dTime = (bTime - aTime) - stopTime;
			break;
		}
	if (vb<0 || va<0 || dTime<1 || vb>300 || va>300)
		return false;
	pTory = p ? tory : r_tory;
	a = getDistanceToVertex(pTory, va);
	b = getDistanceToVertex(pTory, vb);
	if (b-a<1)
		return false;
	distance = a + (((time-aTime)*(b-a))/dTime);
	ll = getPointAtDistance(pTory, distance);
	//$('#output').html(poc[poc_i].nr+'(b-a:'+Math.round(b-a)+')# time: '+Math.round(time)+', dTime: '+dTime+', doj na b: '+Math.round(aTime+dTime)+' [z: '+va+' do: '+vb+'] meters(-): '+Math.round(b-distance)+', (+): '+Math.round(distance-a)+'<br/>');
	//$('#output').html('a:'+Math.round(a)+', b: '+Math.round(b)+', : '+dTime+', distance: '+Math.round(distance)+' [z: '+va+' do: '+vb+'] meters(-): '+Math.round(b-distance)+', (+): '+Math.round(distance-a)+'<br/>');
	if (poc[poc_i].p) {
		if (time<bTime && time>bTime-stopTime)
		{
			if (poc[poc_i].moving)
				poc[poc_i].p.setImage(domain+'fileadmin/templates/main/img/icon_postoj.gif');
			poc[poc_i].moving = false;
			return false;
		}
		else if (!poc[poc_i].moving)
			poc[poc_i].p.setImage(domain+'fileadmin/templates/main/img/marker-train.png');
		poc[poc_i].p.setLatLng(ll);
		poc[poc_i].p.redraw();
		poc[poc_i].moving = true;
	}
	else {
		poc[poc_i].p = createMarker(ll, 'Pociąg numer: <b>'+poc[poc_i].nr+'</b>', domain+'fileadmin/templates/main/img/marker-train.png', null, 99, true, poc[poc_i].nr);
		map.addOverlay(poc[poc_i].p);
		poc[poc_i].moving = true;
	}
	return true;
}

function runSkm()
{
	var n = 0;
	for (var i=0; i<poc.length; ++i)
		if (rzucPociag(i, t)) n++;
	if (ovlMarker)
	{
		iw = map.getInfoWindow();
		iw.reset(ovlMarker.getLatLng(), iw.getTabs(), new GSize(0,0), iw.getPixelOffset());
	}
	$('#info').html(n);
	t+=1/spd;
}

function createMarker(point, info, iconUrl, title, zIndex, shadow, crp)
{
	var icon = new GIcon(G_DEFAULT_ICON);
	icon.image = iconUrl;
	icon.iconSize = new GSize(27, 32);
	//if (shadow == true)
	//	icon.shadow = domain+'fileadmin/templates/main/img/marker-shadow.png';
	//else
		icon.shadow = '';
	var marker = new GMarker(point, {'icon': icon, 'title': title, 'zIndexProcess': setzIndex});
	marker.new_zIndex = zIndex;
	if (info)
	{
		GEvent.addListener(marker, "click", function(){
			marker.openInfoWindowHtml(info);
			ovlMarker = crp ? marker : false;
		});
		GEvent.addListener(marker, "infowindowclose", function(){
			ovlMarker = false;
		});
	}
	return marker;
}

function setzIndex(marker)
{
	return marker.new_zIndex;
}

function zoomToViewAllMarkers()
{
    if (!map) return;
	var zoom = map.getBoundsZoomLevel(area);
	var point = area.getCenter();
	map.setCenter(point, zoom>14 ? zoom-1 : zoom);
}

function zoomToViewMyWay()
{
    if (!map) return;
	var zoom = map.getBoundsZoomLevel(areaOdDo);
	var point = areaOdDo.getCenter();
	map.setCenter(point, zoom>14 ? zoom-1 : zoom);
}

function addGMarkers()
{
    if (!map) return;
    for (i in markers)
    {
        point = new GLatLng(markers[i].lat, markers[i].lng);
		marker = createMarker(point, '<div id="chmurka">'+markers[i].description+'</div>', markers[i].icon, markers[i].name, 2, false, markers[i].name);
        map.addOverlay(marker);
    }
}

function getDistanceToVertex(polyline, vertex, fromVertex, d0)
{
	if (vertex>0 && vertex < polyline.getVertexCount()) {
		var d = 0;
		var i = 1;
		if (fromVertex) {
			d = d0;
			i = fromVertex;
		}
		for (; i <= vertex; ++i)
			d += polyline.getVertex(i).distanceFrom(polyline.getVertex(i-1));
		return d;
	}
	return 0;
}

function getPointAtDistance(polyline, metres) {
  if (metres == 0) return polyline.getVertex(0);
  if (metres < 0) return null;
  var dist=0;
  var olddist=0;
  for (var i=1; (i < polyline.getVertexCount() && dist < metres); i++) {
    olddist = dist;
    dist += polyline.getVertex(i).distanceFrom(polyline.getVertex(i-1));
  }
  if (dist < metres) {return null;}
  var p1= polyline.getVertex(i-2);
  var p2= polyline.getVertex(i-1);
  var m = (metres-olddist)/(dist-olddist);
  return new GLatLng( p1.lat() + (p2.lat()-p1.lat())*m, p1.lng() + (p2.lng()-p1.lng())*m);
}


function decodeLine (encoded) {
  var len = encoded.length;
  var index = 0;
  var array = [];
  var lat = 0;
  var lng = 0;
  while (index < len) {
    var b;
    var shift = 0;
    var result = 0;
    do {
      b = encoded.charCodeAt(index++) - 63;
      result |= (b & 0x1f) << shift;
      shift += 5;
    } while (b >= 0x20);
    var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
    lat += dlat;
    shift = 0;
    result = 0;
    do {
      b = encoded.charCodeAt(index++) - 63;
      result |= (b & 0x1f) << shift;
      shift += 5;
    } while (b >= 0x20);
    var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
    lng += dlng;
    array.push([lat * 1e-5, lng * 1e-5]);
  }
  return array;
}

function createEncodings(moveMap) {
  var i = 0;
  var plat = 0;
  var plng = 0;
  var encoded_points = "";
  var encoded_levels = "";
  for(i = 0; i < points.length; ++i) {
    var point = points[i];
    var lat = point.Latitude;
    var lng = point.Longitude;
    var level = point.Level;
    var late5 = Math.floor(lat * 1e5);
    var lnge5 = Math.floor(lng * 1e5);
    dlat = late5 - plat;
    dlng = lnge5 - plng;
    plat = late5;
    plng = lnge5;
    encoded_points += encodeSignedNumber(dlat) + encodeSignedNumber(dlng);
    encoded_levels += encodeNumber(level);
  }
  // move if moveMap is true.
  if (moveMap) {
    document.map.setCenter(
        new GLatLng(points[0].Latitude, points[0].Longitude),
        document.map.getZoom());
  }
  document.getElementById('encodedLevels').value = encoded_levels;
  document.getElementById('encodedPolyline').value = encoded_points;
  if (document.overlay) {
    document.map.removeOverlay(document.overlay);
  }
  if (points.length > 1) {
    document.overlay = GPolyline.fromEncoded({color: "#0000FF",
                                              weight: 10,
                                              points: encoded_points,
                                              zoomFactor: 32,
                                              levels: encoded_levels,
                                              numLevels: 4
                                             });
    document.map.addOverlay(document.overlay);
  }
}

