/*
 * JavaScript for the Dobson Teleco Network Map
 * by Brandon McKinney / STAPLEGUN
 * 2008 10 22
 
 * Utilizes the Google Maps API
 */

// Set up some Global GMap settings
// we'll use this array to keep track of what's loaded
var loadedLayers = {
	'exchanges' : false,
	'exchangeLabels' : false,
	'coverage' : false,
	'counties' : false,
	'pops' : true,
	'fiber' : true
};
var countyPolygons = new Array();
var map = new Object; // make the map global

// make a blank polyline so we can draw new polygons
var drawPoly = new GPolyline([],"#000",3,1);

window.addEvent('domready', function(){
	// Set up some easy to change settings for the Google Map
	var config = new Object;
	config.apikey = 'ABQIAAAAhReARJN--gmto58QTIHMohTR74pudMFlkD0MaPzHrRxcM3B6pRTrkAoUJiA-rTX-qjHgUX8edx4W4Q';
	config.mapId = 'networkmap';
	config.startLat = '35.7240';
	config.startLng = '-99.3798';
	config.startZoom = 7;

	// Set up the Google Map
	_mPreferMetric = false; // We're in America, no metric
	map = new GMap2($(config.mapId));
	var start = new GLatLng(config.startLat,config.startLng);
	map.setCenter(start, config.startZoom);
	map.addControl(new GLargeMapControl());
	map.addControl(new GScaleControl(250));
	map.addControl(new GMapTypeControl(0));
	map.addMapType(G_PHYSICAL_MAP);
	map.setMapType(G_PHYSICAL_MAP);

	// Set up GMap Events
	// map.zoomend - Fires when the map ends changing zoom level
	GEvent.addListener(map, 'zoomend', function(oldlvl,newlvl){
		// if we're zoomed out more than level 9, [0:out; 18:in]
		if (newlvl < 9 && loadedLayers['exchangeLabels'] == true){
			hideExchangeLabels();
		} else if (loadedLayers['exchangeLabels'] == true){
			showExchangeLabels();
		}
	});
	
	// Add our drawing polygon
	map.addOverlay(drawPoly);
	
	// By default, load fiber areas
	loadFiber();
	// and make sure the coverage checkbox is checked while all others are not
	$$('#mapcontrols input').each(function(o){
		o.checked = true;
	});


	// By default, load pop areas
	loadPops();
	// and make sure the coverage checkbox is checked while all others are not
	$$('#mapcontrols input').each(function(o){
		o.checked = true;
	});



	// Show the Dobson HQ Marker
	//dobsonMarker = new GMarker(start);
	//map.addOverlay(dobsonMarker);
	
	/*
	 * SET UP EVENT HANDLERS FOR THE MAP CONTROLS ON THE RIGHT
	 */
	// Counties Checkbox . Click
	$('chkCounties').addEvent('click', function(){
		if (this.checked == true){
			loadCountyLines();
			var p = this.getParent('div');
			p.setStyles({
				backgroundColor: '#DDE4DD',
				fontWeight: 'bold'
			});
		} else {
			unloadCountyLines();
			var p = this.getParent('div');
			p.setStyles({
				backgroundColor: 'transparent',
				fontWeight: 'normal'
			});
		}
	});
	
	// Coverage Checkbox . Click
//	$('chkCoverage').addEvent('click', function(){
//		if (this.checked == true){
//			loadCoverage();
//			var p = this.getParent('div');
//			p.setStyles({
//				backgroundColor: '#5555FF',
//				color: '#FFF',
//				fontWeight: 'bold'
//			});
//		} else {
//			unloadCoverage();
//			var p = this.getParent('div');
//			p.setStyles({
//				backgroundColor: 'transparent',
//				color: '#707070',
//				fontWeight: 'normal'
//			});
//		}
//	});

	// Prefix Checkbox . Click
	$('chkPrefix').addEvent('click', function(){
		if (this.checked == true){
			loadExchanges();
			var p = this.getParent('div');
			p.setStyles({
				backgroundColor: '#F6F6F6',
				fontWeight: 'bold'
			});
		} else {
			unloadExchanges();
			var p = this.getParent('div');
			p.setStyles({
				backgroundColor: 'transparent',
				fontWeight: 'normal'
			});
		}
	});
	
	// Pop Checkbox . Click
	$('chkPop').addEvent('click', function(){
		if (this.checked == true){
			loadPops();
			var p = this.getParent('div');
			p.setStyles({
				backgroundColor: 'transparent',
				color: '#707070',
				fontWeight: 'normal'
			});
		} else {
			unloadPops();
			var p = this.getParent('div');
			p.setStyles({
				backgroundColor: 'transparent',
				color: '#707070',
				fontWeight: 'normal'
			});
		}
	});
	
	// Fiber Checkbox . Click
	$('chkFiber').addEvent('click', function(){
		if (this.checked == true){
			loadFiber();
			var p = this.getParent('div');
			p.setStyles({
				backgroundColor: 'transparent',
				color: '#707070',
				fontWeight: 'normal'
			});
		} else {
			unloadFiber();
			var p = this.getParent('div');
			p.setStyles({
				backgroundColor: 'transparent',
				color: '#707070',
				fontWeight: 'normal'
			});
		}
	});
	
	
	
	// zoom to regions
	$('zoomMcloud').addEvent('click', function(){
		map.setCenter(new GLatLng(35.4126,-97.0999));
		map.setZoom(10);
	});
	
	$('zoomDobson').addEvent('click', function(){
		map.setCenter(new GLatLng(35.6082,-99.6735));
		map.setZoom(9);
	});
	
	
	mapsizeFx = new Fx.Tween('networkmap');
	$('controlsToggle').setProperty('mapstate', 'small');
	// toggle the map size (cover the controls)
	$('controlsToggle').addEvent('click', function(){
		if (this.getProperty('mapstate') == 'small'){
			this.setProperty('mapstate', 'big');
			mapsizeFx.start('width', 708);
			this.innerHTML = '&gt;&gt;';
		} else {
			this.setProperty('mapstate', 'small');
			mapsizeFx.start('width', 550);
			this.innerHTML = '&lt;&lt;';
		}
	});
	
	
	
	
	/*
	// get the coordinate list for the polyline
	$('btnDrawGetPts').addEvent('click', function(){
		var ptCnt = drawPoly.getVertexCount();
		for (var i=0; i<ptCnt; i++){
			var latlng = drawPoly.getVertex(i);
			$('dumphere').innerHTML += '<br />new GLatLng(' + latlng.lat() + ',' + latlng.lng() + '),';
		}
	});
	
	$('btnDrawStart').addEvent('click', function(){
		drawPoly.enableDrawing();
	});
	
	GEvent.addListener(drawPoly, 'endline', function(){
		drawPoly.enableEditing();
	});
	*/
	/* USED FOR TESTING TO GET VERY SPECIFIC LAT,LNG POINTS */
	/*GEvent.addListener(map, "click", function(overlay, latlng, overlaylatlng){
		if (latlng) ll = latlng;
		else if (overlaylatlng) ll = overlaylatlng;
		
		if (ll) $('dumphere').innerHTML = '<br />' + latlng.lat() + ', ' + latlng.lng();
	});*/
});




/*
 * FUNCTIONS FOR HANDLING THE LOADING/UNLOADING OF LAYERS
 */
// Load the county lines
function loadCountyLines(){
	var i = 0;
	countyPolygons = new Array(); // clear the polygons array
	$$('state').each(function(o){
		var pts = stripslashes(o.getProperty('points'));
		var lvl = stripslashes(o.getProperty('levels'));
		
		countyPolygons[i] = new GPolygon.fromEncoded({
			polylines: [{
				points: pts,
				levels: lvl,
				opacity: .4,
				weight: .5,
				numLevels: 18,
				zoomFactor: 2,
				color: "#000"
			}],
			fill: true,
			outline: true,
			color: "#666"
		});
		map.addOverlay(countyPolygons[i]);
		i++;
	});
	loadedLayers['counties'] = true;
}

// Unload county lines
function unloadCountyLines(){
	for(var i=0; i<countyPolygons.length; i++){
		map.removeOverlay(countyPolygons[i]);
	}
	countyPolygons = new Array();
	loadedLayers['counties'] = false;
}

// Load Coverage Areas
function loadCoverage(){
	for (i=0; i<aryCoverage.length; i++){
		map.addOverlay(aryCoverage[i]);
	}
	loadedLayers['coverage'] = true;
}

// Unload Coverage Areas
function unloadCoverage(){
	for (i=0; i<aryCoverage.length; i++){
		map.removeOverlay(aryCoverage[i]);
	}
	loadedLayers['coverage'] = false;
}

// Load Exchange Boundaries (Prefixes)
function loadExchanges(){
	for (i=0; i<aryExchanges.length; i++){
		map.addOverlay(aryExchanges[i]);
	}
	loadedLayers['exchanges'] = true;
	loadExchangeLabels();
}

// Unload Exchange Boundaries
function unloadExchanges(){
	for(i=0; i<aryExchanges.length; i++){
		map.removeOverlay(aryExchanges[i]);
	}
	loadedLayers['exchanges'] = false;
	unloadExchangeLabels();
}

// Load Exchange Labels
function loadExchangeLabels(){
	for (i=0; i<aryExchangeLabels.length; i++){
		map.addOverlay(aryExchangeLabels[i]);
		if (map.getZoom() < 9) aryExchangeLabels[i].hide();
	}
	loadedLayers['exchangeLabels'] = true;
} 
    
// Unload Exchange Labels
function unloadExchangeLabels(){
	for (i=0; i<aryExchangeLabels.length; i++){
		map.removeOverlay(aryExchangeLabels[i]);
	}
	loadedLayers['exchangeLabels'] = false;
}

// Show Exchange Labels
function showExchangeLabels(){
	for (i=0; i<aryExchangeLabels.length; i++){
		aryExchangeLabels[i].show();
	}
} 

// Hide Exchange Labels
function hideExchangeLabels(){
	for (i=0; i<aryExchangeLabels.length; i++){
		aryExchangeLabels[i].hide();
	}
}

// Load Pops
function loadPops(){
	for (i=0; i<aryPops.length; i++){
		map.addOverlay(aryPops[i]);
	}
}

// Unload Pops
function unloadPops(){
	for (i=0; i<aryPops.length; i++){
		map.removeOverlay(aryPops[i]);
	}
}

// Load Fiber Network Polylines
function loadFiber(){
	for (i=0; i<aryFiberLines.length; i++){
		map.addOverlay(aryFiberLines[i]);
	}
}

// Load Fiber Network Polylines
function unloadFiber(){
	for (i=0; i<aryFiberLines.length; i++){
		map.removeOverlay(aryFiberLines[i]);
	}
}
/*
 * END LAYER CONTROL FUNCTIONS
 */



/*
 * UTILITY FUNCTIONS FROM GOOGLE
 */

// Decode an encoded polyline string.
// This function is from Google's polyline utility.
function decodeLine (encoded) {
 encoded = encoded.replace(/\\\\/g, "\\");
 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;
}


// Decode an encoded levels string into a list of levels.
function decodeLevels(encoded) {
	var levels = [];
	for (var pointIndex = 0; pointIndex < encoded.length; ++pointIndex) {
		var pointLevel = encoded.charCodeAt(pointIndex) - 63;
		levels.push(pointLevel);
	}
	
	return levels;
}
