/*
 * Point, Polyline and Polygon drawing tool using Google Maps
 * antoniom@tessera.gr
 */

// prepeare the map configuration object
var MapDataSet = new Object();
MapDataSet.points = null;
MapDataSet.routes = null;

var MapConfig = new Object();
MapConfig.MODE_POINT = 1;
MapConfig.MODE_POLYLINE = 2;
MapConfig.MODE_POLYGON = 3;
MapConfig.MODE_MULTIPOINT = 4;

MapConfig.lineColor = "#0000af";
MapConfig.fillColor = "#335599";
MapConfig.lineWeight = 3;
MapConfig.lineOpacity = .8;
MapConfig.fillOpacity = .2;

MapConfig.canvasId	= "map_canvas";

MapConfig.defaultLat = 37.05150;
MapConfig.defaultLng = 22.00811;
MapConfig.defaultZoom = 14;
MapConfig.defaultDrawMode = MapConfig.MODE_MULTIPOINT;
MapConfig.defaultSnap = true;

MapConfig.mapWidth = 635;
MapConfig.mapHeight = 400;
MapConfig.openWindowMaxWidth = 200;

MapConfig.initPoint = {lat:MapConfig.defaultLat,lng:MapConfig.defaultLng,zoom:MapConfig.defaultZoom};

//global variables

var Map = Class.create({

	// initializes the google map
	initialize: function( ) {
		// exit if browser is not compatible
		if (!GBrowserIsCompatible())
			return false;

		//property initialization
		this.gmap = null;
		this.zoom = null;
		this.snap = null;
		this.drawMode = MapConfig.MODE_MULTIPOINT;
		this.points = new Array();
		this.markers = new Array();
		this.messages = new Array();
		this.poly = null;
		this.tooltip = null;
		this.iwTitle = null;	//infoWindo Title
		this.iwText = null;	//infoWindo Text
		this.cursorPoint = null;

		// now initialize the map
		this.gmap = new GMap2(document.getElementById(MapConfig.canvasId), {size:(new GSize(MapConfig.mapWidth, MapConfig.mapHeight))});

		// Look n feel
		this.gmap.setUIToDefault();

		// no zoom on wheel move
		this.gmap.disableScrollWheelZoom();

		// prepare tooltip support
		tooltip = document.createElement("div");
		tooltip.className="tooltip";
		this.gmap.getPane(G_MAP_MARKER_PANE).appendChild(tooltip);

		//set default configuration
		this.configMap();

		this.gmap.setCenter(new GLatLng( MapConfig.defaultLat, MapConfig.defaultLng) , this.zoom);

		return true;
	},

	//shows maps ands adds one (or more) points and sets the default drawMode
	configMap: function(dm, z, s) {

		// set the draw mode tool
		this.drawMode = (dm == null) ? MapConfig.MODE_MULTIPOINT : dm;

		// set default zoom
		this.zoom = (dm == null) ? MapConfig.defaultZoom : z;

		// set default snap
		this.snap = (s == null) ? MapConfig.defaultSnap : s;

	},

	//shows maps ands adds one (or more) points and sets the default drawMode
	showMap: function(initPoints, dm, z, s, msgTitle, msgText) {

		// set init points
		initPoints = (initPoints == null) ? new Array() : initPoints;

		// set default texts
		iwTitle = (msgTitle == null) ? null : msgTitle;

		iwText = (msgText == null) ? null : msgText;

		//load init points
		if ( initPoints.length ) {
			loadPoints(initPoints);
		}

		//render the map
		drawOverlay();

		// set center and zoom according to draw mode
		if (drawMode == MapConfig.MODE_POINT) {
			var center = points[0];

			gmap.setCenter(center, z);
		} else {
			var tmpPolyline = new GPolyline(points) ;
			var center = tmpPolyline.getBounds().getCenter();

			zoomLvl = gmap.getCurrentMapType().getBoundsZoomLevel(tmpPolyline.getBounds(), gmap.getSize());

			gmap.setCenter(center, zoomLvl);
		}

		// Mouseout listener
		GEvent.addListener(gmap, "mousemove", function(point) {
			cursorPoint = point;
		});
	},

	//loads a point (in case of point mode), or a group of points (in case of polyline, or polygone mode)
	loadPoints: function(newItems, newTooltip, newIcon) {

		newTooltip = (newTooltip == null) ? null : newTooltip;
		newIcon = (newIcon == null) ? null : newIcon;

		newItems.each(function(item, index) {

			var point = new GLatLng( item.lat, item.lng );

			map.points.push(point);

			if (map.drawMode == MapConfig.MODE_POINT || map.drawMode == MapConfig.MODE_MULTIPOINT)
			{
				map.addMarker(point, newTooltip, newIcon);
			}
			else if (index == 0)
			{
				map.addMarker(point, newTooltip, 'start');
			}
			else if (index == (newItems.length - 1))
			{
				map.addMarker(point, newTooltip, 'finish');
			}

		});

	},

	// add a marker and optionally add a message as tooltip
	addMarker: function (point, tooltipMsg, icon) {

		if(!point) 
			return;
		
		if (icon)
		{
			var myIcon = new GIcon();
			myIcon.image = document.location.pnbaseURL + 'modules/Maps/pnimages/markers/'+icon+'.png';
			myIcon.shadow = document.location.pnbaseURL + 'modules/Maps/pnimages/markers/standard/shadow.png';
			myIcon.iconSize = new GSize(32,37);
			myIcon.transparent = document.location.pnbaseURL + 'modules/Maps/pnimages/markers/standard/transparent.png';
			myIcon.shadowSize = new GSize(51,37);
			myIcon.iconAnchor = new GPoint(16,37);
			myIcon.infoWindowAnchor = new GPoint(16,0);
			myIcon.imageMap = [29,0,30,1,31,2,31,3,31,4,31,5,31,6,31,7,31,8,31,9,31,10,31,11,31,12,31,13,31,14,31,15,31,16,31,17,31,18,31,19,31,20,31,21,31,22,31,23,31,24,31,25,31,26,31,27,31,28,31,29,30,30,29,31,23,32,22,33,21,34,20,35,19,36,12,36,11,35,10,34,9,33,8,32,2,31,1,30,0,29,0,28,0,27,0,26,0,25,0,24,0,23,0,22,0,21,0,20,0,19,0,18,0,17,0,16,0,15,0,14,0,13,0,12,0,11,0,10,0,9,0,8,0,7,0,6,0,5,0,4,0,3,0,2,1,1,2,0];
		}
		else {
			var myIcon = new GIcon(G_DEFAULT_ICON);
		}

		var marker = new GMarker(point, {icon: myIcon, draggable:false, bouncy:false, dragCrossMove:true});

		marker.tooltip = (tooltipMsg == null) ? null : tooltipMsg;

		// prepare the array
		this.markers.push(marker);

		// add the marker to the map
		this.gmap.addOverlay(marker);

		// mouseover listener
		GEvent.addListener(marker, "click", function() {

			if (map.drawMode == MapConfig.MODE_POINT || map.drawMode == MapConfig.MODE_MULTIPOINT) {
				var str = this.tooltip;

				if (str != null) {

					marker.openInfoWindow(str, {maxWidth: MapConfig.openWindowMaxWidth});
					map.gmap.setZoom( 17 );

				}
			}
		});

	},

	drawOverlay: function(){

		//if a polygin already exists, remove it, so as to add a new one
		if(this.poly) { 
			this.gmap.removeOverlay(this.poly); 
		}

		// Check radio button
		if (this.drawMode == MapConfig.MODE_POLYLINE || this.drawMode == MapConfig.MODE_POLYGON)
		{
			if(this.drawMode == MapConfig.MODE_POLYLINE) {
				if (this.snap) {

					var directions = new GDirections(null, document.getElementById('text'));
					directions.clear();

					// Add load listener
					GEvent.addListener(directions, "load", function() {

						if(map.poly) { 
							map.gmap.removeOverlay(map.poly); 
						}
						
						map.poly = directions.getPolyline();
						map.gmap.addOverlay(map.poly);
					});

					directions.loadFromWaypoints(this.points, {getPolyline:true,travelMode:G_TRAVEL_MODE_WALKING });
				} else {
					// Polyline mode
					this.poly = new GPolyline(this.points, MapConfig.lineColor, MapConfig.lineWeight, MapConfig.lineOpacity);
					this.gmap.addOverlay(this.poly);
				}
		
			}
			else if(this.drawMode == MapConfig.MODE_POLYGON) {

				// Polygon mode
				this.points.push(markers[0].getLatLng());
				this.poly = new GPolygon(points, MapConfig.lineColor, MapConfig.lineWeight, MapConfig.lineOpacity, MapConfig.fillColor, MapConfig.fillOpacity);
				this.gmap.addOverlay(poly);

			}

			// now center map to the poly
			var tmpPolyline = new GPolyline(this.points) ;
			var center = tmpPolyline.getBounds().getCenter();

			zoomLvl = this.gmap.getCurrentMapType().getBoundsZoomLevel(tmpPolyline.getBounds(), this.gmap.getSize());

			this.gmap.setCenter(center, zoomLvl);

		}
	},

	clearMap: function () {

		//zoom out
		this.gmap.setZoom( MapConfig.defaultZoom );

		// reconfigure the map
		this.configMap();

		// Clear current map and reset arrays
		this.gmap.clearOverlays();
		this.points.clear();
		this.markers.clear();
	},

	setCenter: function(mid) {

		MapDataSet.points.each(function (item, index) {
			
			if (item.mid == mid) {
				var lat = eval(item.geodata.points)[0].lat;
				var lng = eval(item.geodata.points)[0].lng;

				map.gmap.setCenter(new GLatLng(lat, lng), 17);

				if (map.drawMode == MapConfig.MODE_POINT || map.drawMode == MapConfig.MODE_MULTIPOINT) {

					if (map.markers[index].tooltip != null) {
						map.markers[index].openInfoWindow(map.markers[index].tooltip, {maxWidth: MapConfig.openWindowMaxWidth});
					}
				}

			}

		});
	},

	importPointsFromDataSet: function ( ) {

		this.clearMap();

		map.configMap();

		MapDataSet.points.each(function (item, index) {
			newpoints = eval(item.geodata.points);

			newTooltip = "";
		
			if (item.title[MapMessage.lang]) {
				newTooltip += '<div class="iwtitle">'+ item.title[MapMessage.lang] +'</div><br/>';
			}
			if (item.comments[MapMessage.lang]) {
				newTooltip += '<div class="iwtext">'+ item.comments[MapMessage.lang] +'</div>';
			}

			if (item.geodata.icon == null || item.geodata.icon == "default")
			{
				newIcon = item.icon;
			}
			else {
				newIcon = item.geodata.icon;
			}

			map.loadPoints( newpoints, newTooltip, newIcon );

		});
	},

	loadRoute: function ( mid ) {

		MapDataSet.routes.each(function (item, index) {
			
			if (item.mid == mid) {

				newpoints = eval(item.geodata.points);

				map.clearMap();

				map.configMap(item.geodata.drawmode, item.geodata.gzoom, item.geodata.snap)

				map.loadPoints( newpoints );

				map.drawOverlay();
			}

		});

	},

	showAddress: function(address) {

		geocoder = new GClientGeocoder();

		if (!geocoder) {
			alert(MapMessage.geocoderErrorText);
			return;
		}

		addressToSearch = address + " " + MapMessage.addressSearchSuffix;

		geocoder.getLatLng(addressToSearch, function(point) {

			if (!point) {
				alert(MapMessage.addressNotFoundText);
				return;
			} 

			//refine results
			distanceFromTownCenter = point.distanceFrom(new GLatLng(MapConfig.defaultLat, MapConfig.defaultLng));

			//do not results with distance greater than 20kn 
			if (distanceFromTownCenter > 20000)
			{
				alert(MapMessage.addressNotFoundText);
				return;
			}

			map.clearMap();

			map.gmap.setCenter(point, 17);

			newTooltip = '<div class="iwtitle">'+ MapMessage.addressFoundTitle +'</div><br/>';
			newTooltip += '<div class="iwtext">'+ MapMessage.addressFoundText + '<b>' + address +'</b></div>';

			map.addMarker(point, newTooltip, 'search');

		});

	}

});



// Ajax calls
function getPoints() {

	$('results').update(null);
	$("search_loader").setStyle({display: "block"});

	var catCollection = $('categories').getElementsByClassName('category');

	var checked = 0;

	for (var i = 0; i < catCollection.length ; i++)
	{
		if (catCollection[i].checked)
		{
			checked++;
		}
	}

	if (checked > 0) {
		pars = $('category_map_search').serialize();

		var myRequest = new Ajax.Request('ajax.php',
		{
			method:'get',
			parameters: pars,
			onComplete: getPointsResponse,
			onFailure: function(){ /*alert('Something went wrong...');*/ }
		});
	}
	else {
		//cancel search, no category selected
		$("search_loader").setStyle({display: "none"});

		//also clear map
		map.clearMap();
	}
}

function getPointsResponse(req)
{

	if (req.status != 200 ) 
	{
		pnshowajaxerror(req.responseText);

		return;
	}

	var json = pndejsonize(req.responseText);

	MapDataSet.points = json.mappoints;
	MapDataSet.routes = json.maproutes;

	$("search_loader").setStyle({display: "none"});
	$('results').update(json.output);

	map.importPointsFromDataSet();

}


