// Init Variables section
// Init Variables section

var homeURL = '';

var centerLatitude  = 54.546579538405034;
var centerLongitude = -4.26806640625;
var startZoom = 6;
var map;

// redraw route while dragging?
var drawWhileDrag = true;
var hideDragMarker = false;
var maxInfoHTMLength = 1024;
var enableShowAllMarkers = false;

//var MARKER_DIRECTORY='../images/icons/';
//Current Icon  of GIcon type.
var selectedIcon=null;
var watchRouteModifications = false;
var loadSearchPoints = false;
var userPostCode = '';
var contextIsOverMarker = -1;
var contextOpenedOverMarker = -1;
var removeRouteMarker = false;
var errorWhileDrag = false;

var drawMarkerOverRoute = false;
var side_bar_html = "";
var showToolBar = false;
var gmarkers = [];
var gmarkersPropertiesArray = new Array();
var clickedMarkerNo = 0;
var disableRouteDraw = false;
var routeReadOnly = false;
var routeNeedsSaving = false;
var routeIdentifier = 0;
var map_set_center_lat = 0;
var map_set_center_lng = 0;
var currentScreen = '';
var SubTabMenuOn = false;
var i = 0;
var mapClickListener;
var mapZoomListener;
var gdir; //GDirections object
var gpoly;
var IE = document.all ? true : false;
var polyline;
var pLine;
var startMarker;
var endMarker;
var dragMarker = false;
var pLinePoints = Array();
var markerDragging = false;
var mouseLatLng;
var f_CreateHighWay;
var f_insertStaticMarker;
var f_addMapClickListener;
var f_addMapZoomListener;
var f_log;
var content=''; // log var
var dragStartPoint;
var dragStartPointLatLng;
var points_arr = new Array();
var VMarkerIndex = 0;
var vMarkerInArrayIndex = -1;


var now = new Date();
var lastDrawAt = now.getTime() // last refreshed at
var dragRefreshPeriod = 1000; // refresh each miliseconds

function init() {
    if (GBrowserIsCompatible()) {

    // create the map
		map = new GMap2(document.getElementById("map"));  //,{draggableCursor:"crosshair"}
		map.addControl(new GLargeMapControl()); //polzunok
		map.addControl(new GMapTypeControl());  //sputnik / plan /
		map.addMapType(G_PHYSICAL_MAP); // Terrian Map
		map.addControl(new GOverviewMapControl()); // preview window
		map.enableScrollWheelZoom();

		// right hand menu call
		contextMenu = new ContextMenu(map);

		G_PAUSE_ICON.image  = "";
		G_PAUSE_ICON.shadow = "";

		if(userPostCode.length > 2){
			postCodeCenter(userPostCode);
    	}
    	else{
			if(map_set_center_lng != 0){
	    		map.setCenter(new GLatLng(map_set_center_lat, map_set_center_lng), startZoom);
	    		if(loadSearchPoints == true){
	    			loadSearchPointsFunc(startZoom);
	    		}
	    	}
	    	else{
				getLatLngByIP();
	    	}

			if(routeIdentifier > 0){
				retrieveMarkers(routeIdentifier);
	    	}
    	}

		// MOUSE MOVE EVENT HANDLING
		var rcnt = 0;


	function mouseMove(mousePt) {
		mouseLatLng = mousePt;
		getNearestVertex(mouseLatLng);


		if(markerDragging){
			now = new Date();
			if((now.getTime()-lastDrawAt) > dragRefreshPeriod){
				rcnt++;
				lastDrawAt = now.getTime();

				// add virtualMarker & redraw the map
				insertVirtualMarker(mousePt);
			}
		}
	} // End of mouseMove

//*************************************************************************************
// Virtual -> refresh Route While Dragging


	function insertVirtualMarker(point) {

		if(!markerDragging) {
			return;
		}

		var now1 = new Date();
		var startAt = now1.getTime() // last refreshed at

		var marker = new GMarker(point,{draggable:false,bouncy:false}); // default Icon

		// keeps drag start position for Virtual markers.
		//marker.hide()
		map.addOverlay(marker);

		// Update markers array !!! put marker onto necessary position if this ROUTE has been dragged.
		var gmarkers_tmp = Array();
		//correctMarkerCoords();
		var indx = 0;

		//Rearrange array of markers (insert newly created into necessary position)
		if(vMarkerInArrayIndex == -1){

			var bounds = map.getBounds();
			var SW = bounds.getSouthWest();
			var NE = bounds.getNorthEast();
			var diag = SW.distanceFrom(NE);
			threshold = diag / 150;

			var intermediateIndex = Math.round(pLinePoints.length / 100);
			var vMarkerInserted = false;

			for ( var v = 0 ; v < pLinePoints.length - intermediateIndex; v += intermediateIndex ) {
				if( dragStartPointLatLng.distanceFrom(pLinePoints[v]) < threshold && !vMarkerInserted) {

					VMarkerIndex = gmarkers_tmp.length;
					gmarkers_tmp[VMarkerIndex] = marker;

					//Remember Marker index
					vMarkerInArrayIndex = VMarkerIndex;
					vMarkerInserted = true;

					//Marker properties array
					var prop_len = gmarkersPropertiesArray.length - 1;

					for(i = prop_len; i >= vMarkerInArrayIndex; i--){
						gmarkersPropertiesArray[i+1] = gmarkersPropertiesArray[i];
					}
					gmarkersPropertiesArray[vMarkerInArrayIndex] = new gmarkersProperties('virtual', '', '', '');

					continue;
				}

				// if Virtual marker already inserted - just add the rest of markers - to optimize speed.
				if(vMarkerInserted) {
					for ( cnt=indx; cnt < gmarkers.length; cnt++ ) {
						gmarkers_tmp[gmarkers_tmp.length] = gmarkers[cnt];
					}
					break;
				}


				if(gmarkers.length > indx){
					var reorderedMarkerLatLng = gmarkers[indx].getLatLng(); //tmp object to check the next condition
					if ( reorderedMarkerLatLng.distanceFrom(pLinePoints[v]) < threshold ) {
						gmarkers_tmp[gmarkers_tmp.length] = gmarkers[indx];
						indx ++;
					}
				}
			}

			//Check for last marker insertion.
			if(gmarkers.length == gmarkers_tmp.length){
				gmarkers_tmp[gmarkers_tmp.length] = gmarkers[gmarkers.length-1];
			}
		}
		else{ // if we still dragging the same point - we already know it's index in array.
			var gmIndx = 0;
			for ( cnt=0; cnt<=gmarkers.length; cnt++ ){
				if(cnt == vMarkerInArrayIndex ) {
					gmarkers_tmp[cnt] = marker;
				}
				else {
					gmarkers_tmp[cnt] = gmarkers[gmIndx];
					gmIndx++;
				}
			}
			//Marker properties array
			var prop_len = gmarkersPropertiesArray.length - 1;

			for(i = prop_len; i >= vMarkerInArrayIndex; i--){
				gmarkersPropertiesArray[i+1] = gmarkersPropertiesArray[i];
			}
			gmarkersPropertiesArray[vMarkerInArrayIndex] = new gmarkersProperties('virtual', '', '', '');

		}


		if(gmarkers_tmp.length > 1){
			gmarkers = gmarkers_tmp;
		}

		//Recreate Route due to a new marker added.

		if(drawWhileDrag) {
			if(!errorWhileDrag){
				f_CreateHighWay();
			}
		}


		//remove VirtualMarker.
		try {map.removeOverlay(marker)}
	    catch(e) {}

		// Remove it from gmarkers array
		gmarkers.splice(VMarkerIndex, 1);
		gmarkersPropertiesArray.splice(VMarkerIndex, 1);

		if(drawWhileDrag) {
			if(errorWhileDrag){
				f_CreateHighWay();
				errorWhileDrag = false;
			}
		}


	} // End of insertVirtualMarker

//*************************************************************************************



	//Correct Markers coordinates to match Polyline
	function correctMarkerCoords() {
		for (m=0; m<gmarkers.length; m++){

			markerLatLng = gmarkers[m].getLatLng();

			if (pLinePoints.length > 1){
				var bounds = map.getBounds();
				var SW = bounds.getSouthWest();
				var NE = bounds.getNorthEast();
				var diag = SW.distanceFrom(NE);
				//threshold = diag / 100;
				threshold = diag / 25;

				var minDist = 9999999999;
				var intermediateIndex = Math.round(pLinePoints.length / 100);

				for (var n = 0; n < pLinePoints.length-intermediateIndex; n+= intermediateIndex ) {
					if (markerLatLng.distanceFrom(pLinePoints[n]) < minDist && dragMarker) {
						minDist = markerLatLng.distanceFrom(pLinePoints[n]);
						if (minDist < threshold) {
							gmarkers[m].setLatLng(pLinePoints[n]);
						}
					}
				}
			}
		}
	}  // End of correctMarkerCoords()


	// Watch where mouse pointer is and move marker to the nearest coordinates on the route.
	function getNearestVertex(mouseLatLng) {
		if (markerDragging || hideDragMarker) {
			return;
		}

		if (pLinePoints.length > 1){
			var bounds = map.getBounds();
			var SW = bounds.getSouthWest();
			var NE = bounds.getNorthEast();
			var diag = SW.distanceFrom(NE);
			threshold = diag / 100;
			var minDist = 9999999999;
			var intermediateIndex = Math.round(pLinePoints.length / 100);

			for (var n = 0 ; n < pLinePoints.length-intermediateIndex ; n+= intermediateIndex ) {
				if (mouseLatLng.distanceFrom(pLinePoints[n]) < minDist && dragMarker) {
					minDist = mouseLatLng.distanceFrom(pLinePoints[n]);
					if (minDist < threshold) {
						dragMarker.show();
						dragMarker.setLatLng(pLinePoints[n]);
						dragStartPoint = pLinePoints[n];
						dragStartPointLatLng = dragMarker.getLatLng(pLinePoints[n]);
					}
					else {
						dragMarker.hide();
					}
				}
			}
		}
	}  // End of getNearestVertex


	// Gets array of pints - route line consists
	function copyPolyline(p) {
		pLinePoints = Array();
		for (var n = 0 ; n < p.getVertexCount() ; n++ ) {
			pLinePoints.push(p.getVertex(n));
		}
		var pLine = new GPolyline(pLinePoints,'#FF0000'); //#F7098A
		return pLine;
	}

	GEvent.addListener(map, 'mousemove', mouseMove);




	// END OF Mouse Move event



// **** ADD Zoom change event listener to MAP ********** //
f_addMapZoomListener = function addMapZoomListener(){
		mapZoomListener = GEvent.addListener(map, "zoomend", function(zoomOld, zoomNew) {
			loadSearchPointsFunc(zoomNew);
		}
	);
}

//	init zoom listener
if(map_set_center_lng != 0 && loadSearchPoints == true){
	f_addMapZoomListener();
}


// **** ADD Zoom change event listener to MAP ********** //








//*****************************************************************************
// MARKERS Section
	//allow the user to click the map to create a marker
	f_addMapClickListener = function addMapClickListener(){

		mapClickListener = GEvent.addListener(map, "click", function(overlay, latlng) {
			if(!latlng) return; // if click was made not on the map - we do not have lat & lng

			if(routeReadOnly) return;

			if(selectedIcon)
				var marker = new GMarker(latlng,{draggable:true,bouncy:true,icon:selectedIcon}); // changed icon
			else
				var marker = new GMarker(latlng,{draggable:true,bouncy:true}); // default Icon
			marker.enableDragging(true);

			GEvent.addListener(marker,'dragend',f_CreateHighWay);

			GEvent.addListener(marker,'mouseover', function(){
				contextIsOverMarker = getMarkerNoByLatLng(marker.getLatLng());
			});

			GEvent.addListener(marker,'mouseout', function(){
				contextIsOverMarker = -1;
			});

			GEvent.addListener(marker, 'click',
				function() {
					getMarkerNoByLatLng(marker.getLatLng());
					if(gmarkersPropertiesArray[clickedMarkerNo].mtype == 'dragNode') return; // do not show info Window if this is just a drag node.
					marker.openInfoWindowHtml(infoWinHtml);
					loadMarkerInfoWindowData();
				}
			);

			map.addOverlay(marker);
			gmarkers[gmarkers.length] = marker;
			clickedMarkerNo = gmarkers.length-1;
			var markerType  = selectableIcons[0].mType;
			var markerImage = selectableIcons[0].image;
			if(selectedIcon){
				var markerType = selectedIcon.mType;
				var markerImage = selectedIcon.image;
			}
			gmarkersPropertiesArray[gmarkers.length-1] = new gmarkersProperties(markerType, '', '', markerImage);
			markerDragging = false;

			routeChanged();

			//Recreate Route due to a new marker added - if it is Route Marker
			if(markerType == 'route'){
				f_CreateHighWay();
			}
		});
    }

    // call function to add map click listener
	f_addMapClickListener();



/*************
	FUNCTION
*****************/

//Create marker when route dragging finished
f_insertStaticMarker = function insertStaticMarker(point) {

	var is_draggable = true;
	if(routeReadOnly){
		is_draggable = false;
	}

	if(selectedIcon){
		if(markerDragging){
			var marker = new GMarker(point,{draggable:is_draggable,bouncy:true,icon:iconAfterDragNode}); // changed icon //,{draggable:true,bouncy:true,icon:selectedIcon}
		}
		else{
			var marker = new GMarker(point,{draggable:is_draggable,bouncy:true,icon:selectedIcon}); // changed icon //,{draggable:true,bouncy:true,icon:selectedIcon}
		}
	}
	else
		var marker = new GMarker(point,{draggable:is_draggable,bouncy:true,icon:iconAfterDragNode}); // default Icon /////

	GEvent.addListener(marker,'dragend',f_CreateHighWay);

	GEvent.addListener(marker, 'click',
			function() {
					getMarkerNoByLatLng(marker.getLatLng());
					if(gmarkersPropertiesArray[clickedMarkerNo].mtype == 'dragNode') return; // do not show info Window if this is just a drag node.
					marker.openInfoWindowHtml(infoWinHtml);
					loadMarkerInfoWindowData();
				}
			);


	GEvent.addListener(marker,'mouseover', function(){
		contextIsOverMarker = getMarkerNoByLatLng(marker.getLatLng());
	});

	GEvent.addListener(marker,'mouseout', function(){
		contextIsOverMarker = -1;
	});


	map.addOverlay(marker);


	// Update markers array !!! put marker onto necessary position if this ROUTE has been dragged.
	if(markerDragging){ // && dragStartPoint.length
		var gmarkers_tmp = Array();
		var gmarkersPropertiesArray_tmp = Array();
//			correctMarkerCoords();

		var gmIndx = 0;
		for ( cnt=0; cnt<=gmarkers.length; cnt++ ){
			if(cnt == vMarkerInArrayIndex ) {
				gmarkers_tmp[cnt] = marker;
				gmarkersPropertiesArray_tmp[cnt] = new gmarkersProperties('dragNode', '','',iconAfterDragNode.image);
				clickedMarkerNo = cnt;
			}
			else {
				gmarkers_tmp[cnt] = gmarkers[gmIndx];
				gmarkersPropertiesArray_tmp[cnt] = gmarkersPropertiesArray[gmIndx];
				gmIndx++;
			}
		}
		gmarkers = gmarkers_tmp;
		gmarkersPropertiesArray = gmarkersPropertiesArray_tmp;
		dragStartPoint = '';
		markerDragging = false;
	}
	return marker;

} // End of insertStaticMarker() function





// Add marker to run over the route polyline
function addDragMarker(point) {

	if(routeReadOnly) return;

	if(!dragMarker){
		dragMarker = new GMarker(point, {icon:iconDragNode,draggable:true,bouncy:false}); //


		GEvent.addListener(dragMarker, 'dragend', function(){

			// create normal marker after route has been dragged to necessary place.
			f_insertStaticMarker(mouseLatLng); //dragMarker.getLatLng()

			clickedMarkerNo = vMarkerInArrayIndex;

			vMarkerInArrayIndex = -1;

			if (dragMarker) {
				try {map.removeOverlay(dragMarker);}
				catch(e) {}
				dragMarker = null;
			}

			f_CreateHighWay();
		});

		GEvent.addListener(dragMarker, 'dragstart', function(){
			markerDragging = true;
		});

		map.addOverlay(dragMarker);
	}
	else{
		dragMarker.setLatLng(point);
	}

} // End of addDragMarker() function

//End of Markers Section

// DIRECTIONS Section

// temporary func to output debug info
f_log = function log(str){
	document.getElementById('log').innerHTML += str;
} //end of //f_log function



// Function that draws route between Markers present on the map.
f_CreateHighWay = function CreateHighWay() {

	// do not draw route
	if(disableRouteDraw){
		return;
	}

	if(gmarkers.length < 2){
		gdir.clear();
		if(dragMarker){
			dragMarker.hide();
			pLinePoints = Array();
		}
		return;
	}

	points_arr = new Array();

	//var gmp_shift = 0;
	var points_i = 0;

	//print_r(gmarkersPropertiesArray);

	//Prepare array of points(LatLng-s) for loadFromWaypoints function
	for (var i = 0; i < gmarkers.length; i++) {
		// obtain the attribues of each marker and make array

		//Work with GmarkerProperties array.
		if(gmarkersPropertiesArray[i].mtype == 'route' || gmarkersPropertiesArray[i].mtype == 'dragNode' || gmarkersPropertiesArray[i].mtype == 'virtual' ) {
			var str = gmarkers[i].getLatLng();
			str = str.toString();
			str = str.replace(/[\(\)]/gi, "");
			points_arr[points_i] = str;
			points_i++;
		}
	 }

	routeChanged();

	// if removed route marker and left less then < routew markers on the map - need to clear route from the map.
	if(points_i < 2){
		if(removeRouteMarker){
			gdir.clear();
			removeRouteMarker = false;
		}
		return;
	}

	if(markerDragging){
		// To Disable Redrawing route while dragging - comment the Next line!!!!!!!!!!!
		gdir.loadFromWaypoints(points_arr,{preserveViewport: true});
	}
	else{
		gdir.loadFromWaypoints(points_arr, {preserveViewport: true});
	}



  } // END of CreateHighWay()



// END OF Directions Section

    // === create a GDirections Object ===
    gdir=new GDirections(map, document.getElementById("directions")); // fills in side Panel



    // HIDE  G R E E N MARKERS.
	// Not using the directions markers so hide them.
    function hideDirMarkers(){

		//if we have a route on the map. Add drag marker to it.
    	var startLatLng = gdir.getRoute(0).getStep(0).getLatLng();
		addDragMarker(startLatLng);

		var numMarkers = gdir.getNumGeocodes();
        for (var i = 0; i < numMarkers; i++) {
                var marker = gdir.getMarker(i);
                if (marker != null)
                    marker.hide();
                else
                    alert("Marker is null");
        }
    }

	GEvent.addListener(gdir, "addoverlay", hideDirMarkers);


	//watch directions LOAD event
	GEvent.addListener(gdir, "load", function() {
		gpoly = gdir.getPolyline();
		pLine = copyPolyline(gpoly);


		//watch directions LOAD event
		GEvent.addListener(gpoly, "click", function(latlng) {
			if(drawMarkerOverRoute){
				var tmp_marker = f_insertStaticMarker(mouseLatLng);
				gmarkers[gmarkers.length] = tmp_marker;
				gmarkersPropertiesArray[gmarkers.length-1] = new gmarkersProperties(selectedIcon.mType,'','', selectedIcon.image);
			}

		});
	});


      // === Array for decoding the failure codes ===
      var reasons=[];
      reasons[G_GEO_SUCCESS]            = "Success";
      reasons[G_GEO_MISSING_ADDRESS]    = "Missing Address: The address was either missing or had no value.";
      reasons[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address:  No corresponding geographic location could be found for the specified address.";
      reasons[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address:  The geocode for the given address cannot be returned due to legal or contractual reasons.";
      reasons[G_GEO_BAD_KEY]            = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
      reasons[G_GEO_TOO_MANY_QUERIES]   = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
      reasons[G_GEO_SERVER_ERROR]       = "Server error: The geocoding request could not be successfully processed.";
      reasons[G_GEO_BAD_REQUEST]        = "A directions request could not be successfully parsed.";
      reasons[G_GEO_MISSING_QUERY]      = "No query was specified in the input.";
      reasons[G_GEO_UNKNOWN_DIRECTIONS] = "The GDirections object could not compute directions between the points.";


// === catch Directions errors ===
GEvent.addListener(gdir, "error", function() {
	var code = gdir.getStatus().code;
	var reason="Code "+code;
	if (reasons[code]) {
	  reason = reasons[code]
	}


	if(markerDragging){
		errorWhileDrag = true;
		return;
	}
	else{
		alert("Failed to obtain directions, "+reason);
	}

	// Remove it from gmarkers array
	gmarkers[clickedMarkerNo].hide();
	//gmarkers.splice(gmarkers.length-1, 1);
	deleteCurrentMarker();

	f_CreateHighWay();
	});

	// Populate side bar with desired html
	//document.getElementById("side_bar").innerHTML = side_bar_html;
}

    else {
      alert("Sorry, the Google Maps API is not compatible with this browser");
    }

    //]]>

	// Show floating panels with additional info

// Tool bars to show / hide - uncomment these.
	if(showToolBar){
		toolswin=dhtmlwindow.open('divbox', 'div', 'toolsdiv', '', 'width=190px,height=20px,left=170px,top=420px,resize=0,scrolling=0,closeBtn=0,minimizeBtn=0');
		// select  hand tool by default
		setNextIcon('toolsHand');
	}
//	startTipwin=dhtmlwindow.open('divbox2', 'div', 'startTipdiv', 'Tip', 'width=320px,height=300px,left=350px,top=100px,resize=0,scrolling=1,closeBtn=1,minimizeBtn=1');


} // END OF INIT


// CLEAN map
function cleanMap(){
	map.clearOverlays();
	gmarkers = new Array();
	pLinePoints = Array();
}

// Remove overlay
function cleanLastOverlay(overlay){
	map.removeOverlay(overlay);
}

// Remove Markers in reverse order one by one
function removeLastMarker(){
	if(gmarkers.length){
		cleanLastOverlay(gmarkers[gmarkers.length-1]);
		gmarkers.splice((gmarkers.length-1),1);
	}
}

// Remove Marker No
function removeMarker(markerNo){
	if(gmarkers.length){
		// get Marker Type (do we need to redraw route?)
		var markerType = gmarkersPropertiesArray[markerNo].mtype;

		map.removeOverlay(gmarkers[markerNo]);
		gmarkers.splice(markerNo, 1);
		gmarkersPropertiesArray.splice(markerNo, 1);

		// if deleted marker was route marker - need to refresh route.
		if((markerType == 'route' || markerType == 'dragNode') && !routeReadOnly) {
			removeRouteMarker = true;
			f_CreateHighWay();
		}
	}
}


// RESERVED
function toggleToolbarIcon(pointer, status){
	if(status == 'on'){
//		pointer.style.border='solid 1px #ff0000';
	}
	else{
//		pointer.style.border='dotted 1px #ff0000';
	}
	return;
}


// change icon image
function setNextIcon(name){
	for(var i=0;i<selectableIcons.length;i++){
		var icon=selectableIcons[i];
		if(icon.displayName==name || icon.mType==name) {
			selectedIcon=icon;
			//apply icon to cursor
			changePointerBehaviour(icon.mType);
			map.getDragObject().setDraggableCursor('url('+MARKER_DIRECTORY+name+'.cur),default');

			return;
		}
	}
}

rClickMenuPoints = new Array();

function resetContextMenu(){
	rClickMenuPoints['deleteMarker'] 	= 0;
	rClickMenuPoints['addMarker_alert'] = 0;
	rClickMenuPoints['addMarker_route'] = 0;
	rClickMenuPoints['addMarker_cam'] 	= 0;
	rClickMenuPoints['addMarker_movie'] = 0;
	rClickMenuPoints['addMarker_info'] 	= 0;
}



// actions list for each marker type.
function changePointerBehaviour(pType) {

	resetContextMenu();

	if(pType == 'hand'){
		if(mapClickListener){
			GEvent.removeListener(mapClickListener);
		}
		mapClickListener = GEvent.addListener(map, "click", function(overlay, latlng) {
		});
	}
	else{
		if(mapClickListener){
			GEvent.removeListener(mapClickListener);
		}
		f_addMapClickListener();
	}

	//Check route dragging
	if(dragMarker){
		if(pType == 'route') {
			hideDragMarker = false;
			dragMarker.show();
		}
		else{
			hideDragMarker = true;
			dragMarker.hide();
		}
	}

	//Creating Markers when click on route line.
	 if(pType == 'route' || pType == 'hand') {
		drawMarkerOverRoute = false;
	 }else{
	 	drawMarkerOverRoute = true;
	 }

}





var iconDragNode = new GIcon(); iconDragNode.image=MARKER_DIRECTORY+"dragNode.png"; iconDragNode.toolbarImage=MARKER_DIRECTORY+"dragNode.png"; iconDragNode.iconSize=new GSize(8,8); iconDragNode.iconAnchor=new GPoint(4,4); iconDragNode.infoWindowAnchor=new GPoint(8,8); iconDragNode.displayName="iconDragNode"; //iconDragNode.shadow=MARKER_DIRECTORY+"s.png"; iconDragNode.shadowSize=new GSize(49.0, 32.0); iconDragNode.infoShadowAnchor=new GPoint(8,8);
var iconAfterDragNode = new GIcon(); iconAfterDragNode.image=MARKER_DIRECTORY+"afterDragNode.png"; iconAfterDragNode.toolbarImage=MARKER_DIRECTORY+"afterDragNode.png"; iconAfterDragNode.iconSize=new GSize(8,8); iconAfterDragNode.iconAnchor=new GPoint(4,4); iconAfterDragNode.infoWindowAnchor=new GPoint(8,8); iconAfterDragNode.displayName="dragNode";  iconAfterDragNode.displayName="dragNode"; //iconAfterDragNode.shadow=MARKER_DIRECTORY+"s.png"; iconAfterDragNode.shadowSize=new GSize(49.0, 32.0); iconAfterDragNode.infoShadowAnchor=new GPoint(8,8);

// STATIC DATA about markers images
var def=new GIcon();  def.image=MARKER_DIRECTORY+"googleMarker_s.gif"; def.toolbarImage=MARKER_DIRECTORY+"googleMarker_s.gif"; def.shadow=MARKER_DIRECTORY+"s.png"; def.iconSize=new GSize(20,34); def.shadowSize=new GSize(49.0, 32.0); def.iconAnchor=new GPoint(20,17); def.infoWindowAnchor=new GPoint(0,17); def.infoShadowAnchor=new GPoint(20,34); def.displayName="googleBaloon"; def.mType="baloon";
var marker1=new GIcon(); marker1.image=MARKER_DIRECTORY+"toolsHand.gif"; 	marker1.toolbarImage=MARKER_DIRECTORY+"toolsHand.gif"; 		marker1.shadow=MARKER_DIRECTORY+"s.png"; marker1.iconSize=new GSize(16,17); marker1.shadowSize=new GSize(24.0, 17.0); marker1.iconAnchor=new GPoint(8,17); marker1.infoWindowAnchor=new GPoint(8,0);  marker1.infoShadowAnchor=new GPoint(8,17);  marker1.displayName="toolsHand"; 		marker1.mType="hand";
var marker2=new GIcon(); marker2.image=MARKER_DIRECTORY+"toolsRoutes.gif"; 	marker2.toolbarImage=MARKER_DIRECTORY+"toolsRoutes.gif"; 	marker2.shadow=MARKER_DIRECTORY+"s.png"; marker2.iconSize=new GSize(17,18); marker2.shadowSize=new GSize(17.0, 18.0); marker2.iconAnchor=new GPoint(8,13); marker2.infoWindowAnchor=new GPoint(8,0);  marker2.infoShadowAnchor=new GPoint(8,18);  marker2.displayName="toolsRoutes"; 	marker2.mType="route";
var marker3=new GIcon(); marker3.image=MARKER_DIRECTORY+"toolsCam.gif"; 	marker3.toolbarImage=MARKER_DIRECTORY+"toolsCam.gif"; 		marker3.shadow=MARKER_DIRECTORY+"s.png"; marker3.iconSize=new GSize(16,12); marker3.shadowSize=new GSize(24.0, 12.0); marker3.iconAnchor=new GPoint(8,12); marker3.infoWindowAnchor=new GPoint(16,0); marker3.infoShadowAnchor=new GPoint(16,12); marker3.displayName="toolsCam"; 		marker3.mType="cam";
var marker4=new GIcon(); marker4.image=MARKER_DIRECTORY+"toolsMovie.gif"; 	marker4.toolbarImage=MARKER_DIRECTORY+"toolsMovie.gif"; 	marker4.shadow=MARKER_DIRECTORY+"s.png"; marker4.iconSize=new GSize(12,15); marker4.shadowSize=new GSize(24.0, 15.0); marker4.iconAnchor=new GPoint(6,15); marker4.infoWindowAnchor=new GPoint(16,0); marker4.infoShadowAnchor=new GPoint(16,15); marker4.displayName="toolsMovie"; 	marker4.mType="movie";
var marker5=new GIcon(); marker5.image=MARKER_DIRECTORY+"toolsInfo.gif"; 	marker5.toolbarImage=MARKER_DIRECTORY+"toolsInfo.gif"; 		marker5.shadow=MARKER_DIRECTORY+"s.png"; marker5.iconSize=new GSize(17,17); marker5.shadowSize=new GSize(24.0, 17.0); marker5.iconAnchor=new GPoint(8,17); marker5.infoWindowAnchor=new GPoint(16,0); marker5.infoShadowAnchor=new GPoint(16,17); marker5.displayName="toolsInfo"; 		marker5.mType="info";
var marker6=new GIcon(); marker6.image=MARKER_DIRECTORY+"toolsAlert.gif"; 	marker6.toolbarImage=MARKER_DIRECTORY+"toolsAlert.gif"; 	marker6.shadow=MARKER_DIRECTORY+"s.png"; marker6.iconSize=new GSize(14,14); marker6.shadowSize=new GSize(24.0, 17.0); marker6.iconAnchor=new GPoint(7,14); marker6.infoWindowAnchor=new GPoint(16,0); marker6.infoShadowAnchor=new GPoint(16,17); marker6.displayName="toolsAlert"; 	marker6.mType="alert";

var selectableIcons=[def, marker1, marker2, marker3, marker4, marker5, marker6, iconAfterDragNode];






/**
 * @param strChk      String to be cleaned
 * @param strFind     String to replace
 * @param strReplace  String to insert
 * @return            String without unwanted characters/strings
 */
function replaceAll(strChk, strFind, strReplace) {
  var strOut = strChk;
  var strFindTmp = '|__|';

  while (strOut.indexOf(strFind) > -1) {
    strOut = strOut.replace(strFind, strFindTmp);
  }

  while (strOut.indexOf(strFindTmp) > -1) {
    strOut = strOut.replace(strFindTmp, strReplace);
  }
  return strOut;
}



// Go through Markers Array and save each marker on the server.
function storeAllGMarkers() {

	if(!routeNeedsSaving){
		alert('Route is unchanged.');
	}

	if(gmarkers.length < 1){
		alert('Please specify points to the map.');
		return;
	}

	document.getElementById('saveStatus').innerHTML='Saving . . .';

	for(i=0; i<gmarkers.length; i++){
		storeGMarker(gmarkers[i], i);
	}
}

var savedPointsNo=0;

// Save marker on form submit
function storeGMarker(marker, storingNumber) {


	var lng = marker.getLatLng().lng();
	var lat = marker.getLatLng().lat();
	var lngRad = marker.getLatLng().lngRadians();
	var latRad = marker.getLatLng().latRadians();

	var request = GXmlHttp.create();

	getVars='lat='+lat+'&lng='+lng;
	getVars += '&latRad='+latRad+'&lngRad='+lngRad;

	getVars += '&mhtml='  + replaceAll(gmarkersPropertiesArray[storingNumber].html,  '&', 'amp;');
	getVars += '&mtitle=' + replaceAll(gmarkersPropertiesArray[storingNumber].title, '&', 'amp;');
	getVars += '&mtype='  + gmarkersPropertiesArray[storingNumber].mtype;

	if(!storingNumber){
		savedPointsNo = 0;
		getVars += '&cleanRoute=1';
		if(gmarkers.length > 1 && gdir && gdir.getNumRoutes()){
			getVars += '&distance='+new String(gdir.getDistance().meters);
		}
		else getVars += '&distance=0';

		getVars += '&routeId='+routeId;
		// pass Edit Route Details.
		getVars += '&routeTitle=' + replaceAll(document.getElementById('routeTitle').value, '&', 'amp;');
		getVars += '&routeDescr=' + replaceAll(document.getElementById('routeDescr').value, '&', 'amp;');
		//getVars += '&routeGroupId='+document.getElementById('routeGroupId').value;
	}

	//return;

	//open the request to storeMarker on server
	request.open('GET', homeURL+'/route/savepoint?' + getVars, false);

	savedPointsNo++;

	if(savedPointsNo == gmarkers.length){
		document.getElementById('saveStatus').innerHTML='The route has been saved.';
		routeNeedsSaving = false;
	}

	request.onreadystatechange = function() {

		if (request.readyState == 4) {

			var xmlDoc = request.responseXML;
			//retrieve the root document element (response)
/*
			savedPointsNo++;

			if(savedPointsNo == gmarkers.length){
				document.getElementById('saveStatus').innerHTML='The route has been saved.';
				routeNeedsSaving = false;
			}
*/
//		alert(savedPointsNo +' must be '+ gmarkers.length);
			var responseNode = xmlDoc.documentElement;
			//retrieve the type attribute of the node
			//var type = responseNode.getAttribute("type");

			//retrieve the content of the responseNode
			var content = responseNode.firstChild.nodeValue;
			//check to see if it was an error or success
			//var resp = xmlDoc.documentElement.getElementsByTagName("response");
			var resp = responseNode.getElementsByTagName("response");
			var type = resp[0].getAttribute("type");

			if(type != 'success') {
				alert('Failed to save Marker.');
			} else {

				/*
				//create a new marker and add its info window
				var latlng = new GLatLng(parseFloat(lat),parseFloat(lng));
				var marker = createMarker(latlng, content);
				map.addOverlay(marker);
				map.closeInfoWindow();
				*/
			}
		}
	}

	request.send(null);
	return false;
} // End of storeGMarker()


//Load and show all stored on server side markers.
function retrieveMarkers(route_id) {

	//Clean current route from the map.
	gmarkers = [];
	gmarkersPropertiesArray = [];
	var request = GXmlHttp.create();
	//tell the request where to retrieve data from.
	request.open('GET', homeURL+'/route/loadroute?rid='+route_id, true);

	//tell the request what to do when the state changes.
	request.onreadystatechange = function() {
		if (request.readyState == 4) {
			// clean map before draw anything on.
 			cleanMap();


			var xmlDoc = request.responseXML;
			var markers = xmlDoc.documentElement.getElementsByTagName("marker");

				for (var i = 0; i < markers.length; i++) {

					var lng   = markers[i].getAttribute("lng");
					var lat   = markers[i].getAttribute("lat");
					var mtype = markers[i].getAttribute("mtype");
					var mhtml = markers[i].getAttribute("mhtml");
					var mtitle= markers[i].getAttribute("mtitle");

					/*
					var mhtml = replaceAll(markers[i].getAttribute("mhtml"), 'amp;', '&');
					var mtitle= replaceAll(markers[i].getAttribute("mtitle"), 'amp;', '&');
					*/
					//check for lng and lat so MSIE does not error
					//on parseFloat of a null value

					if(lng && lat) {
						var latlng = new GLatLng(parseFloat(lat),parseFloat(lng));
						setNextIcon(mtype);
						marker = f_insertStaticMarker(latlng);
						gmarkers[gmarkers.length] = marker; // 'marker' var is in global scope
						gmarkersPropertiesArray[gmarkers.length-1] = new gmarkersProperties(mtype, mhtml, mtitle, selectedIcon.image);
					}

				} //for

				f_CreateHighWay();
				//center Map to route start.
				//var centerPoint=new GLatLng(markers[0].getAttribute("lat"), markers[0].getAttribute("lng"));
				//map.setCenter(centerPoint, startZoom); //set map center
				routeNeedsSaving = false;
				setNextIcon('toolsHand');
				document.getElementById('saveStatus').innerHTML='';

			} //if
		} //function
	request.send(null);
} // end of retrieveMarkers()



//Load and show all stored on server side markers.
function loadSearchPointsFunc(newZoom) {

	//Clean current route from the map.
	gmarkers = [];
	gmarkersPropertiesArray = [];
	var request = GXmlHttp.create();
	//tell the request where to retrieve data from.
	request.open('GET', homeURL+'/route/loadsearchpoints?search_lng='+map_set_center_lng+'&search_lat='+map_set_center_lat+'&zoom='+newZoom, true);

	//tell the request what to do when the state changes.
	request.onreadystatechange = function() {
		if (request.readyState == 4) {
			// clean map before draw anything on.
 			cleanMap();

 			var xmlDoc = request.responseXML;
			var markers = xmlDoc.documentElement.getElementsByTagName("marker");

				for (var i = 0; i < markers.length; i++) {


					var lng   = markers[i].getAttribute("lng");
					var lat   = markers[i].getAttribute("lat");
					var mtype = markers[i].getAttribute("mtype");
					var mhtml = markers[i].getAttribute("mhtml");
					var mtitle= markers[i].getAttribute("mtitle");

					//check for lng and lat so MSIE does not error
					//on parseFloat of a null value

					if(lng && lat) {
						var latlng = new GLatLng(parseFloat(lat),parseFloat(lng));
						setNextIcon(mtype);
						marker = f_insertStaticMarker(latlng);
						gmarkers[gmarkers.length] = marker; // 'marker' var is in global scope
						gmarkersPropertiesArray[gmarkers.length-1] = new gmarkersProperties(mtype, mhtml, mtitle, selectedIcon.image);
					}
				} //for
				routeNeedsSaving = false;
				setNextIcon('toolsHand');

			} //if
		} //function
	request.send(null);

} // End of loadSearchPointsFunc();


function getLatLngByIP() {

	var request = GXmlHttp.create();

	//tell the request where to retrieve data from.
	request.open('GET', homeURL+'/ajax/index', true);

	//tell the request what to do when the state changes.
	request.onreadystatechange = function() {
		if (request.readyState == 4) {
			var xmlDoc = request.responseXML;
			var point = xmlDoc.documentElement.getElementsByTagName("iptolatlng");

			var lng = parseFloat(point[0].getAttribute("lng"));
			var lat = parseFloat(point[0].getAttribute("lat"));

			if(lng && lat) {
				map.setCenter(new GLatLng(lat,lng), startZoom);
			}
			else{
				map.setCenter(new GLatLng(centerLatitude,centerLongitude), startZoom); //set map center
			}
		} //if
		else{
			map.setCenter(new GLatLng(centerLatitude,centerLongitude), startZoom); //set map center
		}
	} //function
	request.send(null);

	showAllMarkers();
}




// ************ Info Window section ******************************


 function gmarkersProperties(mType, infoWinHtml, infoWinTitle, image) {
   this.mtype = mType;
   this.html  = infoWinHtml;
   this.title = infoWinTitle;
   this.img   = image;
}


var infoWinHtml = '<div class="infoWindowContainer"><form name="markerForm">'+
	'Title: <input onkeyup="saveInfoWinTitle(this)" class="infoWindowTitleInput" name="infoWindowTitle" id="infoWindowTitle" value="" maxlength="50">'+
	'<div CLASS="infoWindowImageContainer"><IMG id="infoWindowMarkerImg" SRC="'+MARKER_DIRECTORY+'/toolsHand.gif"></div>'+
	'<br>Description:<br>'+
	'<textarea class="infoWindowTextArea" name="infoWindowHtml" id="infoWindowHtml" onchange="saveInfoWin(this)" cols="80" rows="4"></textarea>'+
	'<input type="Hidden" value="MarkerNo">'+
	'<br><table border="0"><tr><td id="infoWindowDelete"><a href="javascript:deleteCurrentMarker();" title="Delete this marker">Delete</a></td>'+
	'<td style="width:98px;text-align:right;"><input type="button" class="infoWinButton" onclick="okInfoWin(); gmarkers[clickedMarkerNo].closeInfoWindow()" value="OK"></td>'+
	'<td style="padding-left:10px;"><input type="button" class="infoWinButton" onclick="resetInfoWin(); gmarkers[clickedMarkerNo].closeInfoWindow()" value="Cancel"></td></tr></table>'+
	'</form></div>';


var  initialTitle = '';
var  initialHtml  = '';
function resetInfoWin(){
	gmarkersPropertiesArray[clickedMarkerNo].html  = initialHtml;
	gmarkersPropertiesArray[clickedMarkerNo].title = initialTitle;
}

function saveInfoWin(pointer){
	if(pointer.value.length > maxInfoHTMLength){
		alert("Description is too big. It can't be longer then "+maxInfoHTMLength+" characters.");
		pointer.focus();
		return false;
	}
	gmarkersPropertiesArray[clickedMarkerNo].html = pointer.value;
}

function okInfoWin(){
	if(gmarkersPropertiesArray[clickedMarkerNo].html  != initialHtml || gmarkersPropertiesArray[clickedMarkerNo].title != initialTitle){
		routeChanged();
	}
}

function saveInfoWinTitle(pointer){
	gmarkersPropertiesArray[clickedMarkerNo].title = pointer.value;
}

function loadMarkerInfoWindowData(){
	document.getElementById('infoWindowHtml').value=gmarkersPropertiesArray[clickedMarkerNo].html;
	 initialHtml = gmarkersPropertiesArray[clickedMarkerNo].html;
	document.getElementById('infoWindowTitle').value=gmarkersPropertiesArray[clickedMarkerNo].title;
	 initialTitle = gmarkersPropertiesArray[clickedMarkerNo].title
	document.getElementById('infoWindowMarkerImg').src=gmarkersPropertiesArray[clickedMarkerNo].img;
}


function deleteCurrentMarker() {
		//remove Marker from the map.
		cleanLastOverlay(gmarkers[clickedMarkerNo]);

		//move all marker left inside arrays;
		for(i=clickedMarkerNo; i<gmarkers.length-1; i++){
			gmarkers[i] = gmarkers[i+1];
			gmarkersPropertiesArray[i] = gmarkersPropertiesArray[i+1];
		}
		// strip last elements of arrays.
		gmarkers.splice((gmarkers.length-1),1);
		gmarkersPropertiesArray.splice((gmarkersPropertiesArray.length-1),1);

		//reload road.
		f_CreateHighWay();
}


// Get marker No in array by LatLng
function getMarkerNoByLatLng(mLatLng){
	for(var i=0; i<gmarkers.length; i++){
		if(gmarkers[i].getLatLng() == mLatLng){
			clickedMarkerNo=i;
			return i;
		}
	}
	clickedMarkerNo=-1;
	return -1;
}

// ************ End of Info Window section ***********************


window.onload = init;
window.onunload = GUnload;


// EOF
//********************************************************************************************
//********************************************************************************************
//********************************************************************************************
//********************************************************************************************


/*
	detect  LAT LNG using Location Name
	fill in necessary hidden fields before submit search form
*/

var cityLatLng = new Array();
var city = '';

var chkint;

function getGeoCode(formName) {
	city = document.forms[formName].searchRouteBy.value;
	if(city.length < 2){
		alert('Please enter search subject');
		document.getElementById('searchRouteBy').focus();
		return false;
	}

	getAddress(city);
	return;
}


var cityLat;
var cityLng;

	 function getAddress(search) {
 		var geo = new GClientGeocoder();
        geo.getLatLng(search, function (result){
			// If that was successful
			if(result){
				cityLat=result.latRadians();
				cityLng=result.lngRadians();
				document.location = homeURL+'/route/search?searchRouteBy='+city+'&search_lng='+cityLng+'&search_lat='+cityLat;
			}
			else{
              	alert('Failed to obtain Geo Coordinates of ['+city+'] location.');
              	return false;
            }
          }
        );
      }


	 function postCodeCenter(postCode) {
 		var geo = new GClientGeocoder();

        geo.getLatLng(postCode, function (result){
			// If that was successful
			if(result){
				placeLat=result.lat();
				placeLng=result.lng();
				map.setCenter(new GLatLng(placeLat, placeLng), startZoom);
				showAllMarkers();
			}
			else{
				getLatLngByIP();
            }
          }
        );
      }


    // Actions to be performed on route change event!
	function routeChanged(){
		if(!watchRouteModifications){
			return;
		}
		routeNeedsSaving = true;
		// show message
		document.getElementById('saveStatus').innerHTML='<span class="routeSaveAlert">The route has been modified.</span>';
	}

	function print_r(arr){
		var str = "array: \n";
		for(i=0; i<arr.length; i++){
			str += arr[i].mtype + "\n";
		}
		alert(str);
	}

	function showAllMarkers(){
		if(!enableShowAllMarkers) return false;
		loadSearchPointsFunc(startZoom);
	}

