/**
 * Map Javascript
 * This file contains all of the map related functions, including map initialization, identify, zoom to a location, markers, and popups.
 * 
 * @version 	v3.0.0  30 August 2009
 * @author 		Rajendra Sarangi
 * @license 	RoadsofIndia.com
 */

/**
 * OpenLayers Map Initialization
 */
OpenLayers.Lang.code = "en";
var map,baselayer;
// Variables  required for ROUTING     
     var SinglePoint = OpenLayers.Class.create();
          SinglePoint.prototype = OpenLayers.Class.inherit(OpenLayers.Handler.Point, {
            createFeature: function(evt) {
                this.control.layer.removeFeatures(this.control.layer.features);
                OpenLayers.Handler.Point.prototype.createFeature.apply(this, arguments);
            }
        });
//
        var start_style = OpenLayers.Util.applyDefaults({
            externalGraphic: "images/start.png",
            graphicWidth: 18,
            graphicHeight: 26,
            graphicYOffset: -26,
            graphicOpacity: 1
        }, OpenLayers.Feature.Vector.style['default']);

        var end_style = OpenLayers.Util.applyDefaults({
            externalGraphic: "images/stop.png",
            graphicWidth: 18,
            graphicHeight: 26,
            graphicYOffset: -26,
            graphicOpacity: 1
        }, OpenLayers.Feature.Vector.style['default']);

	   var direction_style = OpenLayers.Util.applyDefaults({
            externalGraphic: "images/arrow.gif",
            graphicWidth: 8,
            graphicHeight: 8,
          //  graphicYOffset: -26,
            graphicOpacity: 1
        }, OpenLayers.Feature.Vector.style['default']);

		var dir_style = new OpenLayers.StyleMap({
							"default": {
											 externalGraphic: "images/arrow.gif",
											 graphicWidth: 8,
											 graphicHeight: 8,
											 graphicYOffset: 0,
											 rotation: "${angle}"
	//                                   //  fillOpacity: "${opacity}"
										}
							});
	//  styleMap: 

		var street_marker_style = OpenLayers.Util.applyDefaults({
				externalGraphic: "images/AQUA.png",
				graphicWidth: 20,
				graphicHeight: 34,
				graphicYOffset: -29,
				graphicOpacity: 1
			}, OpenLayers.Feature.Vector.style['default']);
		
		var result_style=OpenLayers.Util.applyDefaults(
			{	strokeWidth:5,
				strokeColor:"#CC66FF", // "#66FFFF"
				fillOpacity:0,
				strokeOpacity:0.6
			},
			OpenLayers.Feature.Vector.style['default']
		);
		var popupClass=OpenLayers.Class(OpenLayers.Popup.FramedCloud,{'autoSize':true});
		var parser,mark,result,controls,bikelane,output_text,blImage,gwImage,routeDirection;
		var geocodeStart,geocodeFinish,theTable,headerTable,startToggle,goButton;
		var startImage,stopImage,startImagebw,stopImagebw,printDirections,bikeshops;
		var therouteLink,drag;
		var startpoint=null;
		var finalpoint=null;
		var standard_route="STANDARD";
		var alternate_route="ALT";

function map_init(){		
	// Declare Variables and initialize alues
	var india_bounds = new OpenLayers.Bounds(68.172966003418,7.89929580688477,97.3550567626953,37.0504837036133);		
	var bounds = new OpenLayers.Bounds( -180.0,-90.0,180.0,90.0);
	var MapTitle = "Roads of India";
	var MapTiles= new Array("http://roadsofindia.com/tmsv5/","http://roadsofindia.com/tmsv4r1/","http://roadsofindia.com/tmsv4r2/","http://roadsofindia.com/tmsv4r3/"); 
	var MapTileLayer="roi"; 
	var maxRes = 1.406250; // 0.703125; 
	// Set options and initialize map
	var options = {			
			//maxExtent: bounds, 
			numZoomLevels: 22, 
			minZoomLevel: 5, 
			maxZoomLevel: 22,
			units: 'degrees',
			projection:"EPSG:4326",
			restrictedExtent: india_bounds,
			// maxResolution: maxRes, 
			controls: []
		     };
		// OpenLayers.Util.onImageLoadErrorColor = "transparent";
		map = new OpenLayers.Map('map', options);            		
		OpenLayers.IMAGE_RELOAD_ATTEMPTS = 4;	
		OpenLayers.Util.onImageLoadError = function()
				{
					this.style.backgroundColor= null;
					this.src = "./images/nomaps.png";  
				}
 	// Add map layers
	// Base layer
	// Add India Map Layer
	baselayer = new OpenLayers.Layer.TileCache( MapTitle,MapTiles,MapTileLayer,
			{ 	format: 'image/png', 	transparent: "true",'displayInLayerSwitcher':true, 
		        serverResolutions:[1.406250,0.703125, 0.3515625, 0.17578125, 0.087890625, 0.0439453125, 0.02197265625, 0.010986328125, 0.0054931640625, 0.00274658203125, 0.001373291015625, 0.0006866455078125, 0.00034332275390625, 0.000171661376953125, 8.58306884765625e-05, 4.291534423828125e-05, 2.1457672119140625e-05, 1.0728836059570312e-05, 5.3644180297851562e-06, 2.6822090148925781e-06, 1.3411045074462891e-06, 6.7055225372314453e-07, 3.3527612686157227e-07, 1.6763806343078613e-07, 8.3819031715393066e-08, 4.1909515857696533e-08],
				maxResolution:  0.087890625, 
				minResolution: 2.6822090148925781e-06,
				attribution: '<a href="http://www.roadsofindia.com/" target="_blank" alt="RoadsofIndia"><img src="./images/roadsofindia_logo_sm.png"></a>'
			},{buffer: 0, gutter: 15,transitionEffect:'resize'}			
		);	
	window.status="Please wait while the maps download...";
	map.addLayer(baselayer);
	window.status="RoadsofIndia, Where The Traffic Never Stops...";	
		
	// Map Markers Layers
	smarker_layer = new OpenLayers.Layer.Markers( "Map Markers", {'displayInLayerSwitcher':false} );
	imarker_layer = new OpenLayers.Layer.Markers( "Map Markers", {'displayInLayerSwitcher':false} );
	fmarker_layer = new OpenLayers.Layer.Markers( "Map Markers", {'displayInLayerSwitcher':false} );
		
	//------------------------ ROI Route Layers -------------------------------------------------------------
	/* ----- Route Layer Variables & Styles --- */
	// Map Routing related Layers
	startPoint_layer = new OpenLayers.Layer.Markers("Start Point", {transparent:true,opacity: 0.8, 'displayInLayerSwitcher':false});
    endPoint_layer = new OpenLayers.Layer.Markers("End Point", {transparent:true,opacity: 0.8, 'displayInLayerSwitcher':false});
//	street_markers=new OpenLayers.Layer.Vector('Street markers',{style:street_marker_style,'numZoomLevels':18,'maxZoomLevel':18,'displayInLayerSwitcher':false});
	routepath = new OpenLayers.Layer.Vector("Routing Results", {style: result_style,'displayInLayerSwitcher':false});	
    routeDirection  =new OpenLayers.Layer.Vector("Route Direction",{ minScale:20000, styleMap: dir_style,'displayInLayerSwitcher':false});
	
	// ---- end of ROI Routing Layers --
map.addLayers([smarker_layer,imarker_layer,fmarker_layer,startPoint_layer,endPoint_layer,routepath,routeDirection]);

	

	// Add map controls		
	map.addControl(new OpenLayers.Control.PanZoomBar({'div':OpenLayers.Util.getElement('paneldiv')}));
	map.addControl(new OpenLayers.Control.ScaleLine());
	map.addControl(new OpenLayers.Control.MouseDefaults());
	map.addControl(new OpenLayers.Control.KeyboardDefaults());
	map.addControl(new OpenLayers.Control.Attribution());
	
	// Logger Tracking Code --//---------------------------------------------------------------------
	 // updateFormats();
	var tracking_options = {hover: true}; // To Display Popup  onSelect: serialize
	tracking_layer = new OpenLayers.Layer.Vector("Tracking Layer",{'displayInLayerSwitcher':false});
	map.addLayer(tracking_layer);
    tracking_select = new OpenLayers.Control.SelectFeature(tracking_layer, tracking_options);
	map.addControl(tracking_select);
	tracking_select.activate();
	// - end of Tracking code-----------------------------------------------	
	
	var click = new OpenLayers.Control.Click();
	map.addControl(click);
	click.activate();

	// Zoom to county level
	map.zoomToExtent(india_bounds);
	// Create icons for map markers
    var size = new OpenLayers.Size(25,25);
    var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
    sIcon = new OpenLayers.Icon('images/home_marker.png',size,offset);
    var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
    fIcon = new OpenLayers.Icon('images/facility_marker.png',size,offset);
    var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
    iIcon = new OpenLayers.Icon('images/identify_marker.png',size,offset);
	var size1 = new OpenLayers.Size(18,26);
	var offset1 = new OpenLayers.Pixel(-(size1.w/2), -size1.h);
    spIcon = new OpenLayers.Icon('images/start.png',size1,offset1);
	epIcon = new OpenLayers.Icon('images/stop.png',size1,offset1);

 }

/**
  * Click event handler for the map
  */
 OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {                
    defaultHandlerOptions: {
        'single': true,
        'double': false,
        'pixelTolerance': 0,
        'stopSingle': false,
        'stopDouble': false
    },
    initialize: function(options) {
        this.handlerOptions = OpenLayers.Util.extend(
            {}, this.defaultHandlerOptions
        );
        OpenLayers.Control.prototype.initialize.apply(
            this, arguments
        ); 
        this.handler = new OpenLayers.Handler.Click(
            this, {
                'click': this.trigger
            }, this.handlerOptions
        );
    }, 
    trigger: function(e) {
        var lonlat = map.getLonLatFromViewPortPx(e.xy);		
		getaddress_fm_point(lonlat);
    }
});
 
 
/**
 * Handle widget map creation and panning
 * @param {string} maptype
 * @param {Object} longlat
 * @param {boolean} reset
 */
function widgetMaps(maptype, longlat, reset) {
	if (maptype == "Virtual Earth") {
		if (vemap == null) {
			vemap = new VEMap('vemap');
			vemap.LoadMap(new VELatLong(longlat.lat, longlat.lon), map.getZoom() + 9,VEMapStyle.Hybrid);
		}
		if (reset) vemap.SetMapMode(VEMapMode.Mode2D);
		vemap.SetZoomLevel(map.getZoom() + 9);
		vemap.PanToLatLong(new VELatLong(longlat.lat, longlat.lon));
	}
	else if (maptype == "Google Street View") {
          if (streetview == null || reset) {
			streetview = new GStreetviewPanorama(document.getElementById("streetview"));			
		}
		var theloc = new GLatLng(longlat.lat,longlat.lon);
          panoClient = new GStreetviewClient(); 
		panoClient.getNearestPanorama(theloc, showPanoData)
	}
	else { return; }
}


/**
 *These functions support google street view.
 *Principally for setting the street view angle relative to map center.
 */
function showPanoData(panoData) {
    if (panoData.code == 600) {
        $("#streetview").html("Street View Not Available For This Location");
    }
    else {
        var longlat = map.getCenter();
        var theloc = new GLatLng(longlat.lat,longlat.lon);
        var angle = computeAngle(theloc, panoData.location.latlng);
        streetview.setLocationAndPOV(panoData.location.latlng, {yaw: angle});
    }
}
function computeAngle(endLatLng, startLatLng) {
      var DEGREE_PER_RADIAN = 57.2957795;
      var RADIAN_PER_DEGREE = 0.017453;

      var dlat = endLatLng.lat() - startLatLng.lat();
      var dlng = endLatLng.lng() - startLatLng.lng();
      // We multiply dlng with cos(endLat), since the two points are very closeby,
      // so we assume their cos values are approximately equal.
      var yaw = Math.atan2(dlng * Math.cos(endLatLng.lat() * RADIAN_PER_DEGREE), dlat)
             * DEGREE_PER_RADIAN;
      return wrapAngle(yaw);
}
function wrapAngle(angle) {
    if (angle >= 360) {
      angle -= 360;
    } else if (angle < 0) {
     angle += 360;
    }
    return angle;
}


/** 
 * This sets the layers in the opacity drop down lists.
 */
function setOpacityDDL() {			
    for (var i=0; i<map.layers.length; i++) {
        if (!map.layers[i].isBaseLayer && map.layers[i].displayInLayerSwitcher) {
            $('#opacitydll').append('<option value="' + i + '">' + map.layers[i].name + '</option>');  
        }
    }
}

/**
 * Gets information on a facility. Used for the facility marker.
 * @param {string} layer
 * @param {string} fields
 * @param {string} parameters
 */
function getFacility (layer, fields, parameters) {
	url = wsbase + "ws_roi_attributequery.php?format=json&geotable=" + layer + "&parameters=" + urlencode(parameters) + "&fields=" + urlencode(fields) + '&callback=?';
	$.getJSON(url, function(data){
		$.each(data.rows, function(i, item){
		     setFacility (item.row.long, item.row.lat, item.row.label);
		  });
	});
}

/**
 * Zoom to a latlong at a particular zoom level
 * @param {float} long
 * @param {float} lat
 * @param {integer} zoom
 */
function zoomTo (lon, lat, zoom) {
	map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
}

/**
 * Sets an identified parcel to the selected parcel. Activated from identify popup.
 */
function idPopupSelect () {
	setSelected(identifyArray[0],identifyArray[1], identifyArray[2],identifyArray[3],identifyArray[4],identifyArray[5],identifyArray[6],identifyArray[7],identifyArray[8]);
	MarkerCleaner(imarker_layer, 1);
    processData(currenttab);
}
 
 /*	All the proceeding crap is for markers and popups. */

 /*	All the proceeding crap is for markers and popups. */
/**
 * Add marker for the selected address
 * @param {float} long
 * @param {float} lat
 */
function selectedAddressMarker(long, lat) {
	var popMarker = selectedArray[0]+","+selectedArray[1]+","+ selectedArray[2]+","+selectedArray[3]+","+selectedArray[4]+",'"+selectedArray[5].replace(/'/g, "\\'")+"','"+selectedArray[6]+"','"+selectedArray[7]+"','"+selectedArray[8].replace(/'/g, "\\'")+"'";
	popupHTML = selectedArray[5] + '<br /><a href="#" onclick="map.zoomIn();">Zoom</a> | <a href="#" onclick="setStartPoint('+popMarker+');" >Start From here</a> &nbsp;|&nbsp; <a href="#" onclick="setEndPoint('+popMarker+');" >Go To</a>';
	addMarker(new OpenLayers.LonLat(long,lat), sIcon, popupHTML, smarker_layer, 3)
}

/**
 * Create facility marker
 * @param {float} long
 * @param {float} lat
 */
function facilityMarker(long, lat) {
	popupHTML = facilityArray[2]+ '<br /><a href="#" onclick="map.zoomIn();">Zoom</a> | <a href="#" onclick="startPointMarker('+long+','+ lat+');" >Start From here</a> &nbsp;|&nbsp; <a href="#" onclick="endPointMarker('+long+','+ lat+');" >Go To</a>';
	fMarker = addMarker(new OpenLayers.LonLat(long,lat), fIcon, popupHTML, fmarker_layer, 2)
}
/**
 * Make identify marker
 * @param {float} long
 * @param {float} lat
 */
function identifyMarker(long, lat) {
	var popMarker = identifyArray[0]+","+identifyArray[1]+","+ identifyArray[2]+","+identifyArray[3]+","+identifyArray[4]+",'"+identifyArray[5]+"','"+identifyArray[6]+"','"+identifyArray[7]+"','"+identifyArray[8]+"'";
	popupHTML = identifyArray[5]+ '<br />'+ identifyArray[6] + ' '+ identifyArray[7] + '<br /> <a href="#" onclick="map.zoomIn();">Zoom</a> | <a href="#" onclick="setStartPoint('+popMarker+');" >Start From here</a> &nbsp;|&nbsp; <a href="#" onclick="setEndPoint('+popMarker+');" >Go To</a>';
	addMarker(new OpenLayers.LonLat(long,lat), iIcon, popupHTML, imarker_layer, 1);
}

/**
 * Clean up markers and popups
 * @param {Map Layer} marker_layer   Marker Layer to Clean
 * @param {Integer} popup_array_num    Popup to clean
 */
function MarkerCleaner(marker_layer, popup_array_num) {
	popuplen = map.popups.length;
    for (var i=0; i < popuplen; i++) {
		try {if (popupArray[popup_array_num] == map.popups[i].id) map.removePopup(map.popups[i]);}
		catch(err) {}
    }
	marker_layer.clearMarkers();
}


/**
 * Function to create and clean up markers and popups
 * @param {latlong} ll            OpenLayers LatLong
 * @param {Object} icon          Icon (set up in map init)
 * @param {string} popupContentHTML     Content to display in the popup
 * @param {maplayer} marker_la;er  Marker layer to add the marker to
 * @param {integer} popup_array_num  	Array number for the popup type
 */	
function addMarker(ll, icon, popupContentHTML, marker_layer, popup_array_num) {
	// Clean up popups and markers
	MarkerCleaner(marker_layer, popup_array_num)

	// Create Feature
    var feature = new OpenLayers.Feature(marker_layer, ll); 
    feature.closeBox = true;
    feature.popupClass = OpenLayers.Class(OpenLayers.Popup.FramedCloud, { 'autoSize': true });
	feature.data.popupContentHTML = popupContentHTML;
    feature.data.icon = icon;
	
    // Create Marker and Popup and zoom if necessary
	feature.createMarker();
	feature.createPopup(true);
	if (!feature.onScreen()) map.setCenter(feature.lonlat, 7); 
	
	// add the popup and marker to the map. 
	map.addPopup(feature.popup);
	popupArray[popup_array_num] = feature.popup.id;
	marker_layer.addMarker(feature.marker);

	// toggle the popup.
	feature.marker.events.register("mousedown", feature, function (evt) {
		feature.popup.toggle();       
		OpenLayers.Event.stop(evt);
	});
 }
//--- ROI Specific Marker Functions ----
/**
 * Make startPoint marker
 * @param {float} long
 * @param {float} lat
 */
function startPointMarker(long, lat) {		
	popupHTML = '<b>START POINT</b>: '+startPointArray[5]+ '<br />'+startPointArray[6]+' '+ startPointArray[7] +'<br />[<I><a href="#" onclick="changeMarker('+long+','+ lat+','+ "'sptoep'"+');" >Change to End Point</a></I>]';
	addMarker(new OpenLayers.LonLat(long,lat), spIcon, popupHTML, startPoint_layer, 4);
	setStartPoint_Address(startPointArray[5]+','+startPointArray[6]+','+startPointArray[7]);
}
/**
 * Make endPoint marker
 * @param {float} long
 * @param {float} lat
 */
function endPointMarker(long, lat) {
	popupHTML = '<b>END Point</b>: '+endPointArray[5]+ '<br />'+ endPointArray[6] +' '+ endPointArray[7] +'<br />[<I><a href="#" onclick="changeMarker('+long+','+ lat+','+"'eptosp'"+');">Change to Start Point</a></I>]';
	addMarker(new OpenLayers.LonLat(long,lat), epIcon, popupHTML, endPoint_layer, 5);
	setEndPoint_Address(endPointArray[5]+','+endPointArray[6]+','+endPointArray[7]);
}

function changeMarker(long,lat,stype){
	if (stype == "sptoep") // Start Point to End Point
	{  
		MarkerCleaner(startPoint_layer,4);
        setStartPoint_Address("");		
		//spIcon.display('hide');
		endPointArray = startPointArray.slice();
		endPointMarker(long,lat);
		
	}
	else if (stype =="eptosp") // end point to Start Point
	{		
		MarkerCleaner(endPoint_layer,5);
		setEndPoint_Address("");
		//epIcon.display('hide');
		startPointArray = endPointArray.slice();
		startPointMarker(long,lat);
		
	}
			
}


//-----------------GETADDRESS_FM_POINT-------------Reverse GEOCODING ------------------------
  function getaddress_fm_point(sp) {
	var lonlat = sp; // map.getLonLatFromViewPortPx(sp);
	  //  $('#debugmsg').html("x="+lonlat.lon+" y="+lonlat.lat );
		if (map.getScale() < 75000) { 
				url = wsbase + pointoverlay +"?x="+lonlat.lon+"&y="+lonlat.lat +"&format=json&callback=?";
				$.getJSON(url, function(data){
					if (data.total_rows > 0 ) { 
						$.each(data.rows, function(i, item){
							url = wsbase + poi_geocode + "?format=json&callback=?";
							args = "&pid=" + urlencode(item.row.gid);
							url = url + args;
							$.getJSON(url, function(data) {
								if (data.total_rows > 0 ) {
								  $.each(data.rows, function(i, item){
									var address ="";
									if(trim(item.row.house_number).length > 0) address = address + item.row.house_number + ",";
									if(trim(item.row.bldgname).length > 0) address =  address + item.row.bldgname + ",";
									if(trim(item.row.roadname).length > 0) address =  address + item.row.roadname + ",";
									if(trim(item.row.locality).length > 0) address =  address + item.row.locality ;
									address =  address + "<br />";
									if(trim(item.row.district).length > 0) address =  address + item.row.district + ",";
									if(trim(item.row.state).length > 0) address =  address + item.row.state ;
									if(trim(item.row.zip).length > 0) address =  address + " " + item.row.zip + " ";									
									 setIdentify(item.row.objectid , item.row.x_coordinate , item.row.y_coordinate ,item.row.longitude , item.row.latitude, item.row.name , item.row.locality , item.row.city, address);		
								   });
								}
							});// end of getJson
						}); //end of for each
					}//end of if
				});// end of get json
			}// end of if
} // end of function getaddress_fm_point