// HTML baloons and GMarker arrays
var arrayInfos = new Array();
var arrayMarkers = new Array();
var map;
var num = 0;
var mapPrint = false;
var measuring = false;
var mapDirections = false;
var meaMarkers = new Array();
var meaLine;
var meaDistance = 0;

function loadmap(small) 
{
	// check client browser compatibility
	if (!GBrowserIsCompatible())
		return;

    map = new GMap2(GId("mapin"));  

	// create direction object and bind events
	mapDirections = (GId("mapdir") != null);
   	if( mapDirections ) loadDirections();

    // add controls
    if(small)
	{
		// print page; none controls
		if( !mapPrint )
			map.addControl(new GSmallMapControl());
	}
    else
    {
        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());   
        map.addControl(new GOverviewMapControl());  

        // add our custom controls
        // print button; add a click event handler for print button
        map.addControl(new HtmlControl('<div id="btnPrint" title="Vytisknout mapu" style="background-color:white; color:black; font: smaller Arial; margin-bottom:3px;text-align:center; cursor:pointer; border:black 1px solid; padding:2px; width:62px;"><img src="images/printer.png" style="position:relative; top:1px"> Tisk</div>',"Vytisknout mapu",false,true),
                        new GControlPosition(G_ANCHOR_TOP_RIGHT,new GSize(7,60))); 
		GEvent.addDomListener(GId('btnPrint'), 'click', function() { 
			// navigate to print page
			window.open('print.html?' + GetUrl(null));
		} );

		// measure distance button; add a click event handler for distance button
		map.addControl(new HtmlControl('<div id="btnMeasure" title="Změřit vzdálenost" style="background-color:white; color:black; font: smaller Arial; margin-bottom:3px;text-align:center; cursor:pointer; border:black 1px solid; padding:2px; width:62px;"><img src="images/chart_line.png" style="position:relative; top:1px"> Měření</div>',"Změřit vzdálenost",false,true),
					new GControlPosition(G_ANCHOR_TOP_RIGHT,new GSize(7,90))); 
		GEvent.addDomListener(GId('btnMeasure'),'click', function() {
			spn = GId('spnDistance');
			measuring =!measuring;
			if(measuring)
			{
				if( mapDirections ) clearDirections();

				// start to measure
				GId("dsttext").innerHTML="Kliknutím změříte vzdálenost";
				spn.style.width="190px";
				meaDistance = 0;
				// make the measuring visible...
				GId('spnDistance').style.visibility='visible';
			}
			else
			{
				// clean up, remove measuring markers
				CleanMeasuring();
			}
		} );
		
		// GPS coordinates info box; coordinates updater...
		map.addControl(new HtmlControl('<div id="spnGPS" title="GPS souřadnice"><img src="images/cursor.png"> <span id="gpstext">GPS Souřadnice</span></div>','GPS Souřadnice',false,true), new GControlPosition(G_ANCHOR_BOTTOM_LEFT,new GSize(70,7)));
		GEvent.addListener(map, "mousemove", function(pnt){
			GId("gpstext").innerHTML = formatGPS(pnt.y, pnt.x);
		} );

        // distance results info box
		map.addControl(new HtmlControl('<div id="spnDistance" title="Aktuální vzdálenost"><img src="images/chart_line.png"> <span id="dsttext">Kliknutím změříte vzdálenost</span></div>','Aktuální vzdálenost',false,false), new GControlPosition(G_ANCHOR_BOTTOM_LEFT,new GSize(275,7)));
		 
		// GPS coordinates updater
        GEvent.addListener(map, "click", function(overlay, pnt) {
			if(measuring&&pnt)
			{
				// set the panel smaller...
				GId("spnDistance").style.width="90px";
				// create new marker
				var mkr = createMeasureMarker(pnt);
				map.addOverlay(mkr);
				// add the handler for new marker
				GEvent.addListener(mkr,'drag',function() { RedrawLine() } );
				// store it to the array
				meaMarkers.push(mkr);
				// redraw
				RedrawLine();
			}
		} );
	}
    
    // set the preferences
    map.enableDoubleClickZoom();
    map.enableContinuousZoom();
    // center and zoom to Czech republic
    map.setCenter(new GLatLng(50.05,15.4), 7);
    // use keys for map move
    new GKeyboardHandler(map);

	// choose IE or FF solution
	if( !window.event )
	{
		// the DOM way; access event.shiftKey in FireFox; show stored point from Google API click event
		var mypoint;
		map.getContainer().addEventListener('click', function(e) {
			if( e.shiftKey )
				alert("Coordinate in degrees (latitude,longitude):\r\n" + mypoint + ".");
		}, false); 

		// store point from Google API click for future show
		GEvent.addListener(map, "click", function( marker, point) {
			mypoint = point;
		}); 
	}
	else
	{
		// IE, direct clean solution
		GEvent.addListener(map, "click", function( marker, point) {
			if( event.shiftKey )
				alert("Coordinate in degrees (latitude,longitude):\r\n" + point + ".");
		});
	}
	
	// add mediatel icons
	AddMediatelMarkers();

    // get point data from URL
    var urlLat = GetUrl("la");
    var urlLng = GetUrl("ln");
    var urlName = GetUrl("n");
    var urlAddress = GetUrl("a");
    var urlCity = GetUrl("c");
    var urlPhone = GetUrl("p");
    var urlLink = GetUrl("l");
    var urlEmail = GetUrl("e");
    var urlLogo = GetUrl("lg");
    // check data and create point
    if( urlLat != "" && urlLng != "" )
    {
		var point = new GLatLng(urlLat, urlLng);
		var icon = createIcon();
		map.addOverlay(createMarker(point, icon, urlName, urlAddress, urlCity, urlPhone, urlLink, urlEmail,urlLogo));
        map.setCenter(point,15);

		// print page; none controls
		var t;
		if( mapPrint )
			t = setTimeout("printMap()", 2000);
    }
    else
    {
		// read XMl data file name from URL; when empty use default
		var xmlFile = GetUrl("xml");
		var icon = createIcon();
		var usePan = true;
		if( xmlFile != "" )
	    {
//	        xmlFile = "markers.xml";
//	        // default files, use the mediatel Icons...
//	        icon = createMediatelIcon();
//	        // when mediatel; when do not use panTo function
//	        usePan = false;
            AddXMLMarkers(xmlFile,null,true,true,true);
	    }
	}
}

// create numbered icon...
function CreateNumberedIcon(number)
{
   	var icon = new GIcon();
    icon.image = "images/red_bubble_32_i.png";
    if(number>=1 && number<=20)
        icon.image = "images/red_bubble_32_"+number+".png";
	icon.shadow = "images/red_bubble_32_shadow.png";
	icon.iconSize = new GSize(32, 32);
	icon.shadowSize = new GSize(40, 32);
	icon.iconAnchor = new GPoint(10, 28);
	icon.infoWindowAnchor = new GPoint(14,10);
    return icon; 
}

// mediatel markers will be always visible
function AddMediatelMarkers()
{
    AddXMLMarkers("markers.xml",createMediatelIcon(),false, false,false,true);
}

// process the xml set and create the markers
function AddXMLMarkers(xmlurl, icon, numbered, addToResults, fitResults, mediatel)
{
	GDownloadUrl( xmlurl, function(data, responseCode) {
		var xml = GXml.parse(data);
		var markers = xml.documentElement.getElementsByTagName("marker");
		var point = null;
		var mbounds = new GLatLngBounds;
		var j;
		for (var i = 0; i < markers.length; i++) 
		{
			// get point data from XML record
			var xmlLat = parseFloat(markers[i].getAttribute("lat"));
			var xmlLng = parseFloat(markers[i].getAttribute("lng"));
			var xmlName = markers[i].getAttribute("name");
			var xmlAddress = markers[i].getAttribute("address");
			var xmlCity = markers[i].getAttribute("city");
			var xmlPhone= markers[i].getAttribute("phone");
			var xmlLink = markers[i].getAttribute("link");
			var xmlEmail = markers[i].getAttribute("email");
			var xmlLogo = markers[i].getAttribute("logo");

			// create point
			point = new GLatLng( xmlLat, xmlLng );
			
			// select the right icon
		    icn = (icon) ? icon : createIcon();
			if(numbered)
			    icn = CreateNumberedIcon(i+1);
			j=(numbered)?i+1:-1;
			map.addOverlay(createMarker(point, icn, xmlName, xmlAddress, xmlCity, xmlPhone, xmlLink, xmlEmail,xmlLogo,j, mediatel));
			mbounds.extend(point);
		}
		// zoom and center to the results
		if(fitResults)
            map.setCenter(mbounds.getCenter(),map.getBoundsZoomLevel(mbounds));
	});
}

// hide/show the html control
function switchVisible(control)
{
	control.isVisible = !control.isVisible;
	control.style.visibility = (control.isVisible) ? 'visible' : 'hidden';
}

// removes markers and hide controls for distance measuring
function CleanMeasuring()
{
    GId("spnDistance").style.visibility='hidden';  
    
    // clean up, remove measuring markers
	for (x=0; x<meaMarkers.length; x++) 
		map.removeOverlay(meaMarkers[x]);

	// clean array
	meaMarkers = new Array();
	meaDistance = 0;
	map.removeOverlay(meaLine);

	measuring=false;
}

// redraw the line...
function RedrawLine()
{
   // draw the line around and calculate
    if(meaLine)
        map.removeOverlay(meaLine);
        
    line = new Array();
    meaDistance = 0;
    last = meaMarkers[0].getPoint();
    for (x=0; x<meaMarkers.length; x++) 
	{
		pnt = meaMarkers[x].getPoint();
		line.push(pnt);
		meaDistance+=last.distanceFrom(pnt);
		last = pnt;
	}

    meaLine = new GPolyline(line, "#0000FF",5,0.5);
    map.addOverlay(meaLine);
    GId("dsttext").innerHTML=formatDistance(meaDistance);
}


// format degrees into x°xy'xy.zw"
function formatDegrees(x)
{
    var res = "";
    var absx=Math.abs(x);
    res += Math.floor(absx);
    res +="°";
    
    mn = (x-Math.floor(x))*(60/100)*100;
    res += Math.floor(mn);
    res +="'";
    
    sc = (mn - Math.floor(mn))*(60/100)*100;
    res +=sc.toFixed(2);
    res +='"';
    
    return res;
}

// format distance into meters and kilometers
function formatDistance(dist)
{
	var res="0 m";
	if(dist) res = (dist < 3000) ? (dist.toFixed(0) + " m") : ((dist/1000).toFixed(1) + " km");

	return res;
}

// format gps coordinates
function formatGPS(x,y)
{
    var gps = x.toFixed(5) +", "+y.toFixed(5);

    gps = (x<0) ? "S" : "N";
    gps += formatDegrees(x) + ", ";
   
	gps += (y<0) ? "W" : "E";
    gps += formatDegrees(y);
    
    return gps;
}


//function to create standard icon
function createIcon()
{
	var icon = new GIcon();
    icon.image = "images/red_bubble_32_i.png";
	icon.shadow = "images/red_bubble_32_shadow.png";
	icon.iconSize = new GSize(32, 32);
	icon.shadowSize = new GSize(40, 32);
	icon.iconAnchor = new GPoint(10, 28);
	icon.infoWindowAnchor = new GPoint(14,10);
    return icon;
}

//function to create standard icon
function createMediatelIcon()
{
	var icon = new GIcon();
    icon.image = "images/mediatel_zs.png";
	icon.shadow = "images/mediatel_stin.png";
	icon.iconSize = new GSize(32, 32);
	icon.shadowSize = new GSize(32, 32);
	icon.iconAnchor = new GPoint(16, 16);
	icon.infoWindowAnchor = new GPoint(16, 16);
    return icon;
}

// create marker with small blue icon
function createMeasureMarker(point)
{
    // small blue marker icon
    var icon = new GIcon();
    icon.image = "http://labs.google.com/ridefinder/images/mm_20_blue.png";
    icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
    icon.iconSize = new GSize(12, 20);
    icon.shadowSize = new GSize(22, 20);
    icon.iconAnchor = new GPoint(6, 20);

    var marker = new GMarker(point,{icon:icon, draggable: true});
    
    return marker;
}

// create start marker
function createStartMarker(point)
{
    // start green marker
    var icon = new GIcon(G_DEFAULT_ICON, "http://maps.google.com/mapfiles/dd-start.png");
    var marker = new GMarker(point,{icon:icon, draggable: true});
    
    return marker;
}

// create start marker
function createEndMarker(point)
{
    // end red marker
    var icon = new GIcon(G_DEFAULT_ICON, "http://maps.google.com/mapfiles/dd-end.png");
    var marker = new GMarker(point,{icon:icon, draggable: true});
        
    return marker;
}

// function to create marker with listener...            
function createMarker(point, icon, companyName, streetAdr, city, phoneNumber, url, email, logo, number, mediatel) 
{
	// tests
	//alert("Point: x: '" + point.x + "', y: '" + point.y + "'");
	//alert("Name: '" + companyName + "', address: '" + streetAdr + "', city: '" + city + "', phone: '" + phoneNumber + "', link: '" + url + "'");

	// prepare HTML info and GMarker object
    var marker = new GMarker(point, {icon:icon, title:companyName});
    var info = getCompanyInfo(companyName, streetAdr, city, phoneNumber, url, email, logo);
    var listact = "res" + (number-1);
    
    // store for future use
    if( number>=0 ) {
        arrayInfos[ arrayInfos.length ] = info;
        arrayMarkers[ arrayMarkers.length ] = marker;
    }

    GEvent.addListener(marker, "click", function() {
        marker.openInfoWindowHtml(info);
        // bug fix workaround...
        var spndist = GId("spnDistance");
            if(!measuring&&spndist)
                spndist.style.visibility="hidden";                            
    });
        
    if(number>=0) {
        GEvent.addListener(marker, "mouseover", function() {marker.setImage("images/blue_bubble_32_"+number+".png");});
        GEvent.addListener(marker, "mouseout", function() {marker.setImage("images/red_bubble_32_"+number+".png");});
    }
	else
    {
		if(mediatel) {
			// mediatel hover effect
			GEvent.addListener(marker, "mouseover", function() {marker.setImage("images/mediatel_zs_hover.png");});
			GEvent.addListener(marker, "mouseout", function() {marker.setImage("images/mediatel_zs.png");});       
		} else {
			// regular i-marker
			GEvent.addListener(marker, "mouseover", function() {marker.setImage("images/blue_bubble_32_i.png");});
			GEvent.addListener(marker, "mouseout", function() {marker.setImage("images/red_bubble_32_i.png");});       
		}
    }

	// check if result ID exist; when yes, add code for hover efect
    var listactli = GId( listact );
    if( listactli != null ) {
		GEvent.addListener(marker, "mouseover", function() {
			var listitem = GId( listact );
			listitem.className = "resact";
		} );
		GEvent.addListener(marker, "mouseout", function() {
			var listitem = GId( listact );
			listitem.className = "res";
		} );
	}
	
	// increment counter of items
    num++;
    return marker;
}

// will create the html representaion of the details
function getCompanyInfo(companyName, streetAdr, city, phoneNumber, url, email, logo)
{
	// add logo if specified... (and extend the infobox to 300px width
	var result = ( logo ) ? 
		"<div class='infotip fix320'><h3>" + companyName + "</h3>" :
		"<div class='infotip'><h3>" + companyName + "</h3>";

    // other company details       
    result+=
    "<div class='infoleft170'>" +
    "<div class='adr'>"+streetAdr+"<br/>"+city+"</div>"+
    "<div class='tel'>"+phoneNumber+"</div>" +
    "<div class='email'><a href='mailto:"+email+"' title='"+email+"'>"+email+"</a></div>" + 
    "<div class='url'><a href='http://"+url+"' title='"+companyName+"' target='_blank'>"+url+"</a></div></div>";
    if(logo)
		result +="<div class='company-logo'><img src='"+logo+"' alt='"+companyName+"'/></div>";                      

    result+="</div>";
    return result;
}

// print page
function Print()
{
    // get point data from URL
    var urlName = GetUrl("n");
    var urlAddress = GetUrl("a");
    var urlCity = GetUrl("c");
    var urlPhone = GetUrl("p");
    var urlLink = GetUrl("l");
    var urlEmail = GetUrl("e");
    var urlLogo = GetUrl("lg");

	// assign data to print page
	GId('cname').innerHTML = urlName;
	GId('caddress').innerHTML = urlAddress;
	GId('ccity').innerHTML = urlCity;
	GId('cphone').innerHTML = urlPhone;
	GId('cemail').innerHTML = urlEmail;
	GId('cemail').title = urlEmail;
	GId('cemail').href = 'mailto:' + urlEmail;
	GId('clink').innerHTML = urlLink;
	GId('clink').title = urlName;
	GId('clink').href = urlLink;

	if( urlLogo )
		GId('clogo').innerHTML = '<img src="' + urlLogo + '" alt="' + urlName + '" />';

	// enable print mode (hide all map controls)
	mapPrint = true;
	loadmap(true);
}

// will print the map page
function printMap()
{		
	try { 
	    window.print();
    }
    catch(e){
		GLog.write(e);
	}
}

// get url parameter         
function GetUrl( name )
{
	var regexexp = (name != null ) ? "[\\?&]"+name+"=([^&#]*)" : "\\?(.*)";
	var regex = new RegExp( regexexp );
	var tmpURL = window.location.href;
	var results = regex.exec( tmpURL );

	if( results == null ) return "";
	else
	{
		// first remove spaces and then decode from UTF8
		var result = results[1].replace(/\+/g, " ");
		try	{
			return decodeURIComponent(result);
		}
		catch(err) {
			return result;
		}
	}
}

// get element by ID
function GId( id )
{
	return document.getElementById(id);
}

// HtmlControl - used for custom buttons and infobox
// html - html inside hosting div 
// title - title for the div (will work as a tooltip)
// printable - true/false if it should be printable
function HtmlControl(html, title, printable, visible) 
{ 
    this.html = html;
    this.isPrintable = printable;
    this.Title = title;
    this.isVisible = visible;
 } 


HtmlControl.prototype = new GControl(); 
HtmlControl.prototype.initialize = function(map) { 
  var dive = document.createElement("div"); 
  dive.className = "htmlcontrol"; 
  dive.innerHTML = this.html; 
  dive.title = this.Title;
  if(this.isVisible)
    dive.style.visibility='visible';
  else
    dive.style.visibility='hidden';
  map.getContainer().appendChild(dive); 
  return dive; 
} 

HtmlControl.prototype.getDefaultPosition = function() { 
  return new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(7, 30)); 
}
