var startMarker;
var endMarker;
var directionsInfoDiv;
var dirObj;
var USstates = Array('Alabama','Alaska','Arizona','Arkansas','California','Colorado','Connecticut','Delaware','District of Columbia','Florida','Georgia','Hawaii','Idaho','Illinois','Indiana','Iowa','Kansas','Kentucky','Louisiana','Maine','Maryland','Massachusetts','Michigan','Minnesota','Mississippi','Missouri','Montana','Nebraska','Nevada','New Hampshire','New Jersey','New Mexico','New York','North Carolina','North Dakota','Ohio','Oklahoma','Oregon','Pennsylvania','Rhode Island','South Carolina','South Dakota','Tennessee','Texas','Utah','Vermont','Virginia','Washington','West Virginia','Wisconsin','Wyoming')
var pattern = '(' + USstates.join('|') + ')';

var IE = document.all ? true : false;
var detailmap;
var container;
var clckTimeOut = null;
var loading = false;
var countyLines = new Array();
var saveState = true;
var sliderMoving = false;
var customMapsInfo;
var iw;
var	mapMode;
var pLine;
var poiMarkers = new Array();
var pLinePoints;
var texasMask;
var searchAreaHighlight;
var normalProj = G_NORMAL_MAP.getProjection();	
var call =0;
function getDirections(mapDiv, oDriveFrom, oDriveTo, directionsInfoDiv, map) {
    //var map = map || '';//new GMap2(mapDiv);
    //var map = map || '';//new GMap2(mapDiv);
    if(!map)
        return false;
	dirObj = new GDirections(map);
	GEvent.addListener(dirObj, "load", onDirectionsLoad);
	GEvent.addListener(dirObj, "error", onDirectionsError);

	var oDriveVia = '';
	var oLocale = 'en_US';
	directionsInfoDiv.style.display = '';
//	resetSearchcontrols();
	var loadStr;
	if (oDriveFrom && oDriveTo) {
		loadStr = 'from:' + oDriveFrom;
		if (oDriveVia) {
			var viaSteps = oDriveVia.split(';');
			for (var n = 0 ; n < viaSteps.length ; n++ ) {
				loadStr += ' to: ' + viaSteps[n];
			}
		}
		loadStr += ' to: ' + oDriveTo;
	}
	if (loadStr) {
//		indicateLoading();
		dirObj.load(loadStr,{locale:oLocale,getPolyline:true,getSteps:true,preserveViewport:true});
//		updateLink();
		var geocoder = new GClientGeocoder();
		geocoder.getLatLng(oDriveFrom, function(point) {setZoom1(mapDiv, geocoder, point, oDriveTo);});
	}
}

function displayMapComplete(mapDivName, lat, lon, zoomLevel, func) {
  if (GBrowserIsCompatible()) {
//        alert(mapDivName.id +', '+ lat +', '+ lon +', '+ zoomLevel +', '+ func)
        map = new GMap2(mapDivName, { size: new GSize(952,500) } );
/*
From Google Documentation
The setCenter() method requires a GLatLng coordinate and a zoom level and this method must  be sent before any other operations are performed on the map, including setting any other attributes of the map itself. 
*/
		if (lat != "" && lon != "" && zoomLevel != ""){
            map.setCenter(new GLatLng(lat, lon), zoomLevel);
        }
		map.addControl(new GLargeMapControl());
		map.addControl(new GMapTypeControl());
		map.addControl(new GScaleControl()); 
        //map.setCenter(new GLatLng(lat, lon), zoomLevel);
       // alert(map.getZoom() +', '+map.getCenter())
		//map.addControl(new GOverviewMapControl());
        if(func == 'getRoute()'){
            getRoute(map);
            $(mapDivName).show();
        }else{
            eval(func);
        }
    return map;
  }
}


function setZoom1(mapDiv, geocoder, pointFrom, oDriveTo)
{
		geocoder.getLatLng(oDriveTo, function(point) {setZoom(mapDiv, pointFrom, point);});
}

function setZoom(mapDiv, pointFrom, pointTo)
{

		// Set Center based on all markers
    var centerLat = (pointFrom.y + pointTo.y) / 2;
  	var centerLon = (pointFrom.x + pointTo.x) / 2;
  	map.setCenter(new GLatLng(centerLat, centerLon), 13);

  	var neLat = pointTo.y;
  	var neLon = pointTo.x;
  	var swLat = pointFrom.y;
  	var swLon = pointFrom.x;
    if (pointTo.y < pointFrom.y) {
    	neLat = pointTo.y;
    	swLat = pointFrom.y;
		}
		else {
    	neLat = pointFrom.y;
    	swLat = pointTo.y;
		}
    if (pointTo.x > pointFrom.x) {
    	neLon = pointFrom.x;
    	swLon = pointTo.x;
		}
		else {
    	neLon = pointTo.x;
    	swLon = pointFrom.x;
		}

		// Set Zoom level so that all markers are visible
    var bds = new GLatLngBounds(new GLatLng(neLat, neLon), new GLatLng(swLat, swLon));
    map.setZoom(map.getBoundsZoomLevel(bds));
    
    mapDiv.style.visibility = "visible";
}
var callinggetPolylinePoints = 0;
function getPolylinePoints(p) {
    //alert('calling getPolylinePoints '+callinggetPolylinePoints+' p is '+p )
	var pLinePoints = Array();
	for (var n = 0 ; n < p.getVertexCount() ; n++ ) {
		pLinePoints.push(p.getVertex(n));
	}
	return pLinePoints;
}

function onDirectionsLoad() {

	var html = '';
	var status = dirObj.getStatus();
	var bounds = dirObj.getBounds();
	var copyrightHTML = dirObj.getCopyrightsHtml();
	var summaryHTML = dirObj.getSummaryHtml();
	var distance = dirObj.getDistance();
	var duration = dirObj.getDuration();
	var polyline = dirObj.getPolyline();
	pLinePoints = getPolylinePoints(polyline);
	pLine = new GPolyline(pLinePoints,'#F7098A');

	var numGeoCodes = dirObj.getNumGeocodes();
	var startPoint = dirObj.getGeocode(0);
	var endPoint = dirObj.getGeocode(numGeoCodes-1);
	if (startMarker) {
		var clickStartPoint = startMarker.getPoint();
		var resultStartLatLon = new GLatLng(startPoint.Point.coordinates[1],startPoint.Point.coordinates[0]);

//GLog.write(clickStartPoint.distanceFrom(resultStartLatLon))		
		
		if (clickStartPoint.distanceFrom(resultStartLatLon) > 0) {
			html += 'WARNING: The route starts some distance away from the point clicked.<br>';
		}
	}
	if (endMarker) {
		var clickEndPoint = endMarker.getPoint();
		var resultEndLatLon = new GLatLng(endPoint.Point.coordinates[1],endPoint.Point.coordinates[0]);
		if (clickEndPoint.distanceFrom(resultEndLatLon) > 0) {
			html += 'WARNING: The route ends some distance away from the point clicked.<br>';
		}
	}


	for (var n = 0 ; n < numGeoCodes ; n++ ) {
		var geoCode = dirObj.getGeocode(n);
		var marker = dirObj.getMarker(n);
	}

	/*
	html += '<div class="globalSummaryDiv">';
	html += '<table cellspacing="0" cellpadding="2" width="100%">';
	html += '<tr><td valign="top"> <b>' + startPoint.address + '</b> to <b>' + endPoint.address + '</b></td></tr>';
	html += '<tr><td valign="top"> '+summaryHTML+'</td></tr>';
	html += '</table></div>';
	*/

	var numRoutes = dirObj.getNumRoutes();
	for (var r = 0 ; r < numRoutes ; r++ ) {
		var route = dirObj.getRoute(r);
		var startGeoCode = dirObj.getGeocode(r);//route.getStartGeocode();
		var endGeoCode = dirObj.getGeocode(r+1);//route.getEndGeocode();
		var endLanLng = route.getEndLatLng();
		var routeSummaryHTML = route.getSummaryHtml();
		var routeDistance = route.getDistance();
		var routeDuration = route.getDuration();
		html += '<div class="routeSummaryDiv" onclick="toggleSteps('+r+')" title="Click to view steps">';
		html += '<table cellspacing="0" cellpadding="2" width="100%">';
		html += '<tr>';
		html1 = '<tr>';
		if (r == 0) {
			html1 += '<td valign="top"><img src="/images/greenCircle.png"><br><img src="/images/yellowSquare.png"></td>';
		}
		else if (r == numRoutes - 1) {
			html1 += '<td valign="top"><img src="/images/yellowSquare.png"><br><img src="/images/redCircle.png"></td>';
		}
		else {
			html1 += '<td valign="top"><img src="/images/yellowSquare.png"><br><img src="/images/yellowSquare.png"></td>';
		}
		html += '<td valign="top"><b>' + startGeoCode.address + '</b> to <b>' + endGeoCode.address + '</b>: '+routeDistance.html+ ' (' + routeDuration.html +  ')</td>';
		html += '<tr>';
		html += '</table></div>';

		var numSteps = route.getNumSteps();
		html += '<table cellspacing="0" cellpadding="0" id="routeTable_'+r+'" style="border:1px silver solid;" width="100%"><tr><td>';
		html += '<table cellspacing="0" cellpadding="0" width="100%">';
		for (var s = 0 ; s < numSteps ; s++ ) {
			var step = route.getStep(s);
			var stepLatLng = step.getLatLng();
			var stepPolylineIndex = step.getPolylineIndex();
			var stepDescriptionHTML = step.getDescriptionHtml();
			var re = new RegExp(pattern,'g');
			stepDescriptionHTML = stepDescriptionHTML.replace(re,'<b style="color:#CA0039">$1</b>')
			var stepDistance = step.getDistance();
			var stepDuration = step.getDuration();
			html += '<tr class="stepRow"><td>&nbsp;&nbsp;' + (s+1) + '.</td><td> ' + stepDescriptionHTML + '</td><td>' + stepDistance.html + '</td></tr>';

		}
		html += '</table>';
		html += '</td></tr></table>';
	}
	
	// This element "mapContainer" is from views/coulomb/content/forms/deviceroute.php
	// Need to display this map div if there is valid address.
	if($('mapContainer'))
		$('mapContainer').style.display = "block";
	
	directionsInfoDiv.innerHTML = html;
//	loading = false;
	showPOIs(); //calls get poi

}

function onDirectionsError() {
//	loading = false;
	directionsInfoDiv.innerHTML = 'Error: ' + dirObj.getStatus().code;
}

function toggleSteps(routeNo) {
	oRouteTable = $('routeTable_' + routeNo);
	oRouteTable.style.display = oRouteTable.style.display == 'none' ? '' : 'none';
}

function showStep(r,s) {
	map.closeInfoWindow();
	var step = dirObj.getRoute(r).getStep(s);
	var stepLatLng = step.getLatLng();
	var stepDescriptionHTML = step.getDescriptionHtml();
	var re = new RegExp(pattern,'g');
	stepDescriptionHTML = stepDescriptionHTML.replace(re,'<b style="color:#CA0039">$1</b>')
	var stepDistance = step.getDistance();
	var stepDuration = step.getDuration();

	var infoHTML = '<div id="tab1" class="bubble">';
	infoHTML += '<table>';
	infoHTML += '<tr class="stepRow"><td>&nbsp;&nbsp;' + (s+1) + '.</td><td> ' + stepDescriptionHTML + '</td><td>' + stepDistance.html + '</td></tr>';
	infoHTML += '<tr class="stepRow"><td>&nbsp;&nbsp;</td colspan="2"><td> ' + stepLatLng + '</td></tr>';
	infoHTML += '</table>';
	infoHTML += '</div>';



	var tab1 = new GInfoWindowTab("Location", '<div id="detailmap"></div>');
	var tab2 = new GInfoWindowTab("Info", infoHTML);
	var infoTabs = [tab1,tab2];

	map.openInfoWindowTabsHtml(stepLatLng,infoTabs);

//	detailmap = null;
// Minimap for driving directions
	var dMapDiv = $("detailmap");
	detailmap = new GMap2(dMapDiv);
	detailmap.setCenter(stepLatLng,15);

	detailmap.addOverlay(pLine);

	var CopyrightDiv = dMapDiv.firstChild.nextSibling;
	var CopyrightImg = dMapDiv.firstChild.nextSibling.nextSibling;
	CopyrightDiv.style.display = "none"; 
	CopyrightImg.style.display = "none"; 

	detailmap.addControl(new GSmallMapControl());


}

function getPOIs(proximity, chargerLevelOptions) {
			var threshhold = proximity * 1609 * 0.1;
			//var url = 'http://localhost/ctech/index.php/device/poi.html';
			var url = Coulomb_deviceroutepoi_uri;
			var qString = '';
            
            //var map = map || new GMap2($("deviceroutemap"));
			qString += 'lat=' + map.getCenter().lat().toFixed(6);
			qString += '&lon=' + map.getCenter().lng().toFixed(6);
			qString += '&proximity=' + proximity;
			qString += '&chargerLevelOptions=' + chargerLevelOptions;

			var lineString = '';
			var lastPoint = new GLatLng(0,0);
			var added = 0;
			if (pLinePoints && pLinePoints.length) {
//GLog.write('points: ' + pLinePoints.length);
				var ptsReduced = Array();
				for (n = 0 ; n < pLinePoints.length ; n++) {
					var p = pLinePoints[n];
					if (p.distanceFrom(lastPoint) > threshhold) {
						ptsReduced.push(p);
						lineString += p.lat().toFixed(6) + ',' + p.lng().toFixed(6) + 'x';
						lastPoint = p;
						added++;
					}
				}

//				buildLines(ptsReduced,radius);



//GLog.write(pLinePoints.length + ' - ' + added);
//GLog.write(lineString);
				qString += '&pline=' + lineString;
//GLog.write(qString);
//				indicateLoading();
//				getData(url,'POIs',qString);
			}
			else {
				url += '?' + qString;
//				indicateLoading();
//				getData(url,'POIs');
			}
			postURLFunc(url, qString, 'markPOIs');
}

function getData(url,type,qString) {
	var http_request = false;

//	debug('Request sent: ' + url);

	if (window.XMLHttpRequest) { // Mozilla, Safari, ...
		http_request = new XMLHttpRequest();
		if (http_request.overrideMimeType) {
			http_request.overrideMimeType('text/xml');
			// See note below about this line
		}
	} else if (window.ActiveXObject) { // IE
		try {
			http_request = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try {
				http_request = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e) {}
		}
	}

	if (!http_request) {
		alert('Giving up :( Cannot create an XMLHTTP instance');
		return false;
	}


/*
     http_request.onreadystatechange = alertContents;
      http_request.open('POST', url, true);
      http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      http_request.setRequestHeader("Content-length", parameters.length);
      http_request.setRequestHeader("Connection", "close");
      http_request.send(parameters);

*/


	http_request.onreadystatechange =  function() { processXML(http_request,type); };
	if (qString) { // POST
		http_request.open('POST', url, true);
		http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');  //For POST Method
http_request.setRequestHeader("Content-length", qString.length);
//http_request.setRequestHeader("Connection", "close");
		http_request.send(qString);

	}
	else {
		http_request.open('GET', url, true);
		http_request.send(null);
	}
}

function processXML(http_request,type) {
	if (http_request.readyState == 4) {
		if (http_request.status == 200) {
			if (type == 'POIs') {
				readPOIs(http_request);
			}

			loading = false;
		
		}
		else {
			alert('Request Failed: ' + http_request.status);
		}
	}
}

// ---------------- AJAX READ ------------------------------------------ //

function readPOIs(http_request) {
	var xmlDoc = http_request.responseXML;
//GLog.write(http_request.responseText)

	var results = xmlDoc.documentElement.getElementsByTagName("p");
	var bounds = new GLatLngBounds();

	for (var i = 0 ; i < results.length ; i++) {
		var hv = new Array();
		var attrs = results[i].attributes;

		for ( var n = 0; n < attrs.length ; n++) {
			hv[attrs[n].name] = attrs[n].value;
		}

		var html = '<div>';
		html += 'distance: ' + hv['d'] + ' miles<br><br>';
		html += 'Some text about ' + hv['n'];
		html += '</div>';

		var point = new GLatLng(hv['y'], hv['x']);
		bounds.extend(point);
		var marker = createMarker(point,hv['n'],html,poiIcons['icon_'+hv['c']]) ;

		if (!poiMarkers['cb_'+hv['c']]) {
			poiMarkers['cb_'+hv['c']] = Array();
		}
		
		
		poiMarkers['cb_'+hv['c']].push(marker);
		map.addOverlay(marker);
	}

	markSearchArea();

//	map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds)); 
}

function markPOIs(jsonObj) {
//	jsonObj = responseText.parseJSON();

	recCount = jsonObj.count;
	
	if (recCount > 0) { // if there are devices to be marked on the map
		for (var ctr=0; ctr<recCount; ctr=ctr+1) {

			jsonRec = jsonObj.result[ctr];
			lat = jsonRec.lat;
			lon = jsonRec.lon;
			imageName = jsonRec.deviceImage;
			markerTitle = jsonRec.deviceGUID;
			numPorts = (jsonRec.numPorts == null) ? '' : ( jsonRec.numPorts );
			port1Status = (jsonRec.port1 == null) ? '' : ( jsonRec.port1 );
			port2Status = (jsonRec.port2 == null) ? '' : ( jsonRec.port2 );
            description = (jsonRec.statusName == null) ? '' : ( jsonRec.statusName );
            address = (jsonRec.address == null) ? '' : ( jsonRec.address );
            port1description = (jsonRec.port1description == null) ? '' : (jsonRec.port1description);
            port2description = (jsonRec.port2description == null) ? '' : (jsonRec.port2description);
            action = (jsonRec.submitButton == null) ? '' : (jsonRec.submitButton) + '<br/>';

            lastKnown = (jsonRec.lastKnown == null) ? '' : (jsonRec.lastKnown);
            lastKnownDate = (jsonRec.lastKnownDate == null) ? '' : (jsonRec.lastKnownDate);
            
            markerHtml = "<div><div class='mapInfoWindow'><b> Name: </b>"+ jsonRec.deviceName + "<br/> <b> Address: </b>"+ address + "<br/>";
			markerHtml += (description !=''? "<b> Description: </b>" + description +" <br />" : '');
			
            if(lastKnown != '' && lastKnownDate != '')
            {
                markerHtml += "<strong>" + lastKnown + ":</strong> " + lastKnownDate + "<br/>";
            }
                    
            if (numPorts == 2) {
                markerHtml += "<b>Port 1: </b>" + port1description + ": <strong><i>" + port1Status + "</i></strong><br/>";
                markerHtml += "<b>Port 2: </b>" + port2description + ": <strong><i>" + port2Status + "</i></strong><br/>";
            }
            else if (port2Status != '') {
                markerHtml += "<b>Port 2: </b>" + port2description + ": <strong><i>" + port2Status + "</i></strong><br/>";
            }
            else {
                markerHtml += "<b>Port 1: </b>" + port1description + ": <strong><i>" + port1Status + "</i></strong><br/>";
            }
            /* markerHtml += action; */
            markerHtml += "</div>";
			markerTooltip = jsonRec.address;

			addDeviceToMap(map, lat, lon, imageName, "", markerTitle, markerHtml, markerTooltip, "", "", "", "", "", "");
		}
	}
	markSearchArea(jsonObj.proximity);

	GEvent.addListener(map, "zoomend", function() {
		map.removeOverlay(searchAreaHighlight);
		markSearchArea(jsonObj.proximity);
	});

}




function createMarker(point,markerName,markerHtml,mIcon) {
	var htmlInfo = '<div class="bubble">';
	htmlInfo += '<b>' + markerName + '</b><br>';
	htmlInfo += markerHtml;	
	htmlInfo += '</div>';	
	
	var marker = new GMarker(point,{icon:mIcon, title:markerName});
	GEvent.addListener(marker, "click", function() {
		marker.openInfoWindowHtml(htmlInfo);
	});
	return marker;
}

function markSearchArea(proximity) {
//return;
//	map.removeOverlay(searchAreaHighlight);

	var displaySearch = 0;

	var center = map.getCenter();
	var zoom = map.getZoom();

	if (pLinePoints && pLinePoints.length) {

		for (n = 0 ; n < pLinePoints.length ; n++) {
			var p = pLinePoints[n];
		}
		var centerPx = normalProj.fromLatLngToPixel(center, zoom);
		var nextPxLatLon =  normalProj.fromPixelToLatLng(new GPoint(centerPx.x+1,centerPx.y), zoom);
		var dPx = nextPxLatLon.distanceFrom(center) / 1609.344;
		var pxWidth = Math.ceil(proximity / dPx) * 2;

		//GPolyline(points,  color?,  weight?,  opacity?)
		searchAreaHighlight = new GPolyline(pLinePoints,'#FFFF00',pxWidth, 0.30);
		map.addOverlay(searchAreaHighlight);
	}
	else {
		var circlePoints = drawCircle(center,radius,'MI')

		//	GPolygon(points,  strokeColor?,  strokeWeight?,  strokeOpacity?,  fillColor?,  fillOpacity?)
		searchAreaHighlight = new GPolygon(circlePoints, '#00C000', 2 , 0.5 , '#00C000', 0.10);	
		map.addOverlay(searchAreaHighlight);
	}
}
