var LayerStack = Class.create();
LayerStack.prototype = {
        initialize: function(){
                this.data = {'layers':[]};
                this.id = 1;
        },
        initLayer: function(name,obj){
                this.data['layers'].push({
                        'title' : name,
                        'object': obj,
                        'id'    : this.getID(),
								'visibility': true
                });
        },
        get: function(name){
                lyr = this.data['layers'].detect(function(num){return num['title'] == name;});
                if(lyr){return lyr['object'];}
        },
        addLayer: function(name){
                lyr = new OpenLayers.Layer.Markers(name);
                this.initLayer(name,lyr);
                map.addLayer(this.get(name));
        },
        add: function(name,marker){
                if(this.exists(name)){
                        lyr = this.get(name);
                        lyr.addMarker(marker);
                }else{
                        this.addLayer(name);
                        this.add(name,marker);
                }
        },
        hide: function(name){
                lyr = this.get(name);
                if(this.isObj(lyr)){
                  lyr.setVisibility(false);
                }
        },
		  hideAll: function(){
                this.data['layers'].each(function(num, index){
                        lyr = num['object'];
								lyr.setVisibility(false); 
					 });
		  },
        show: function(name){
                lyr = this.get(name); if(this.isObj(lyr)){ lyr.setVisibility(true); }
        },
        clear: function(name){
                 lyr = this.get(name);
                 if(this.isObj(lyr)){
                        lyr.destroy();
                        this.data['layers'].splice(this.getIndex(name),1);
                 }
        },
        clearAll: function(){
                this.data['layers'].each(function(num, index){
                        lyr = num['object'];
                        lyr.destroy();
                        num['object'] = '';
                });
                this.data['layers'] = [];
        },
        exists: function(name){
                 el = this.data['layers'].detect(function(num,index){return num['title'] == name;});
                return el ? true : false;
        },
        getIndex: function(name){
                 this.data['layers'].detect(function(num,index){if(num.title == name)idx = index; });return idx;
        },
        getID: function(){
                this.id ++;
        },
        isObj: function(obj){
                return obj != undefined ? true : false;
        },
		  isVisible: function(name){
					lyr = this.get(name);
					return lyr.getVisibility();
		  },
		  getDataExtent: function(name) {
					lyr = this.get(name);
					return lyr.getDataExtent();
		  }
};

OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {               
            defaultHandlerOptions: {
                'single': true
            },

            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.onClick
                    }, this.handlerOptions
                );
            },

            onClick: function(evt) {
              addData(evt);
            }
  });


TextLayer = OpenLayers.Class(OpenLayers.Marker.Label, {

    labelClass: "olTextLabel",

    initialize: function(lonlat, icon, label, options) {
     var newArguments = [];

     OpenLayers.Util.extend(this, options);
     newArguments.push(lonlat, icon, label);
     OpenLayers.Marker.prototype.initialize.apply(this, newArguments);

     this.label = label;
     this.labelDiv = OpenLayers.Util.createDiv(this.icon.id + "_Text", null, null);
     this.labelDiv.innerHTML = "<DIV><IMG style='display:block;' src='/images/call_out.png'/></DIV><DIV class='olTextLabel'>" + label + "</DIV>";
    }
});

var BtisMap = {
	keys : { lat : 'lat', lon : 'lon', label : 'label', root : 'locations' },

   showLocations: function(locations, _keys, _layer, zoom_to_bounds) {
	  if(zoom_to_bounds == undefined) { zoom_to_bounds = true; }
	  var layer = (_layer == undefined)? "markers" : _layer;
     if (_keys != undefined && _keys != null) {
		 keys = _keys;
	  }
	  try {
     		var results = eval("(" + locations + ")");
	  }
	  catch(e) {
     		var results = eval(locations);
	  }
     results = results[keys['root']];
	  if(layer == "parking") { build_parking_listing(results); }
	  if (ls.exists(layer)) { ls.clear(layer); }
	  var id_ref = 0;
     results.each(function (result){
				if(result[keys['label']] != "LIVE_GPS_TRACK_DATA") {
					BtisMap.displayMarker(result, id_ref, layer);id_ref++;
				}
			}
	  );
	  if( ((_layer == "traffichotspots") || (_layer == "cameras"))  && zoom_to_bounds){
	  		bounds = ls.getDataExtent(_layer);
         map.zoomTo(12);
	  		//bounds = layer.getDataExtent();
	  		//recenterMap();
		}
		else if(zoom_to_bounds) { // if(_layer != "bmtctrack") {
			bounds = ls.getDataExtent(layer);
			recenterMap();
		}
   },

    displayMarker: function(result, i, layer) {
      var loc = new OpenLayers.LonLat(result[keys['lon']],result[keys['lat']]);
      var m_image = (layer == 'cameras') ? '/images/cam.gif' : ( (result['status'] != undefined) ? getIcon(result['status']) : (layer == "carpool") ? getGenderIcon(result['gender']) : (layer == 'tracers') ? '/images/green.gif' : (layer == "parking") ? getParkingIcon(result['availability']) : '/images/marker.png' )
      
      // If BMTC tracking, create separate layers for different types of buses
      if (layer == 'bmtctrack')
      {
        tuple = getBusIconLayer(result[keys['label']]);
        m_image = tuple[0];
        layer = tuple[1];
      }

      if (result['status'] != undefined && result['status'] == "Delay" && result[keys['label']] != "LIVE_GPS_TRACK_DATA")
      {
        traffic_delays = traffic_delays + "<a href='javascript:void(null);'>" + result[keys['label']] + "&nbsp; (" + result['smscode'] + ")</a><br/>";
        traffic_delays_marquee = traffic_delays_marquee + "<span class='clstsu'>&nbsp;&#183;&nbsp;" + result[keys['label']] + " &nbsp; (" + result['smscode'] + ") </span>";
      }
      marker = this.createMarker(loc,result[keys['label']],false, m_image);
      if (layer == "cameras") 
      {
        if (camera_display_mode=="quick") 
        {
          marker.events.register('click', marker, function(e){ $("cam-img").src = "/camera/images/"+result.id; $("cam-name").innerHTML = result[keys['label']].toUpperCase();$("cam-locn").innerHTML = result['locn'].toUpperCase();$("result-div").show();camera_id = result.id; new PeriodicalExecuter(function() { refreshCamera();}, 20);});
        }
        else
        {
		      marker.events.register('click', marker, function(e){ get('/camera/show?id='+result.id);show_tab('traffic');}); 
        }
      }
		else if(layer == "cities") {
		      marker.events.register('click', marker, function(e){ window.open(result['url']);}); 
		}
      ls.add(layer, marker);
    },

  /*
   * create a default maker
   */
   createMarker: function(loc,desc,highlight,m_image){
		if(m_image == "/images/cam.gif") {
			var offset = function(size) { return new OpenLayers.Pixel(-12,-12);};
			icon = new OpenLayers.Icon(m_image, new OpenLayers.Size(24,12), null, offset);
		}
		else if(m_image == "/images/genderM.gif" || m_image == "/images/genderF.gif") {
      	var offset = function(size) {return new OpenLayers.Pixel(-16,-14);};
      	icon = new OpenLayers.Icon(m_image,new OpenLayers.Size(12,24),null,offset);
		}
		else if(m_image == "/images/blue_carpooler.png" || m_image == "/images/pink_carpooler.png") {
        var offset = function(size) {return new OpenLayers.Pixel(-20,-14);};
        icon = new OpenLayers.Icon(m_image,new OpenLayers.Size(24,24),null,offset);
     	}
		else if(m_image == "/images/redbus.gif" || m_image == "/images/bus-icon.gif" || m_image == "/images/bus-icon_green.gif") {
			var offset = function(size) { return new OpenLayers.Pixel(-12,-12);};
			icon = new OpenLayers.Icon(m_image, new OpenLayers.Size(24,19), null, offset);
		}
		else if(m_image == "/images/highlight.gif") {
			var offset = function(size) { return new OpenLayers.Pixel(-22,-27);};
			icon = new OpenLayers.Icon(m_image, new OpenLayers.Size(45,45), null, offset);
		}
		else if(m_image == "/images/marker.png") {
      	var offset = function(size) {return new OpenLayers.Pixel(-16,-14);};
      	icon = new OpenLayers.Icon(m_image,new OpenLayers.Size(32,29),null,offset);
      }
		else {
      	//var m_image = getIcon(status) 
      	var offset = function(size) {return new OpenLayers.Pixel(-12,-12);};
      	icon = new OpenLayers.Icon(m_image,new OpenLayers.Size(12,12),null,offset);
      }
      var options = {"mouseOver":true};
		if (m_image == "/images/redbus.gif" || m_image == "/images/bus-icon.gif") {
      	return  new OpenLayers.Marker.Label(loc,icon,"<div style='font-weight:bold;background-color:#FFF;border:1px solid #000;color:#000;text-align:center;font-size:12px;width:100px;'>"+desc+"</div>",options);
		}
		else {
			_text = "<DIV><IMG style='display:block;' src='/images/call_out.png'/></DIV><div style='padding:3px;font-family:Arial;font-weight:bold;background-color:#000;color:#FFF;text-align:center;font-size:10.5px;width:110px;'>" + desc + "</div>";
      	return  new OpenLayers.Marker.Label(loc,icon,_text,options);
		}
   },

   drawRoute: function() {
   },

	clearRoute: function() {
		vectorLayer.setVisibility(false);
	},

    showRoute: function(rpoints) {
     vectorLayer.destroyFeatures();
     if (ls.exists("markers")) ls.clear("markers");
     
     var calculate_offset = function(size) { return new OpenLayers.Pixel(-10,-14); };
     var points = [];
     var offset = function(size) {return new OpenLayers.Pixel(-6,-12);};
     startIcon = new OpenLayers.Icon("/images/start.png", new OpenLayers.Size(12,12), null, offset);
     endIcon = new OpenLayers.Icon("/images/end.png", new OpenLayers.Size(12,12), null, offset);

     var i=0;
     var options = {"mouseOver":false};

     for(var i=0;i<rpoints.length;i++) {
       if (i == 0) { var startPnt = new OpenLayers.LonLat(rpoints[i].lon, rpoints[i].lat); ls.add("markers", new OpenLayers.Marker.Label(startPnt, startIcon, "", options));}
       points.push(new OpenLayers.Geometry.Point(rpoints[i].lon,rpoints[i].lat));
       if (i==points.length-1) { var endPnt = new OpenLayers.LonLat(rpoints[i].lon, rpoints[i].lat);ls.add("markers", new OpenLayers.Marker.Label(endPnt, endIcon, "", options));} 
         
     }
     var lineFeature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points),null,style_route);
     vectorLayer.addFeatures([lineFeature]);
     map.addLayer(vectorLayer);
     map.zoomToExtent(createEnvelope(points[0].x, points[0].y, points[points.length - 1].x, points[points.length -1].y));
    vectorLayer.setVisibility(true);

    },

    showLocation: function(lon, lat, name, show_marker, _layer, _zoom) {
      layer = (_layer == undefined) ? "markers" : _layer;
	  	//if (ls.exists(layer)) { ls.clear(layer); }
      loc = new OpenLayers.LonLat(lon, lat);
      
      // Check whether marker is to be displayed or not
      if (show_marker == undefined || show_marker == null || !show_marker)
      {
        m_image = "/images/transparent.png";
        var offset = function(size) {return new OpenLayers.Pixel(-4, -11);};
        icon = new OpenLayers.Icon(m_image, new OpenLayers.Size(9, 11), null, offset);
      }
      else
      {
        m_image = "/images/marker.png";
        var offset = function(size) {return new OpenLayers.Pixel(-16,-14);};
        icon = new OpenLayers.Icon(m_image, new OpenLayers.Size(32, 29), null, offset);
      }
      
      var options = {"mouseOver": false};
		  zoom = (_zoom == undefined) ? 15 : _zoom
      map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
    	if (marker != undefined) { marker.destroy(); }
      marker = new OpenLayers.Marker.Label(loc, icon, name, options);
      ls.add(layer, marker);
    },

    clearRoutes: function() {
      vectorLayer.destroyFeatures();vectorLayer.removeFeatures([lineFeature]);
    }
}

function highlightMarker(lon, lat, desc, layer){
	  if($('map')) {
	  	var loc = new OpenLayers.LonLat(lon,lat);
	  	if (ls.exists('highlights')) { ls.clear('highlights'); }
		if (layer == "cameras") {
     		marker = BtisMap.createMarker(loc, desc, true, "/images/cam.gif"); 
		}
		else {
     		marker = BtisMap.createMarker(loc, desc, true, "/images/highlight.gif"); 
		}
	  	ls.add('highlights', marker);
     	map.raiseLayer(ls.get(layer),12);
	  	/*map.setCenter(loc, map.getZoom());*/
	}
}

function getMapCenter() {
	return map.getCenter();
}

function setMapCenter(lat, lon, zoom) {
    map.setCenter(new OpenLayers.LonLat(lon, lat),zoom);
}

function init_map()
{
  map = new OpenLayers.Map($('map'),{projection:"EPSG:4326", numZoomLevels:18 });
  map.addLayer(new OpenLayers.Layer.GTileGrid("India",tile_url));
  map.setCenter(new OpenLayers.LonLat(lon, lat),zoom);
  map.addControl( new OpenLayers.Control.MapunityText());
  map.addControl( new OpenLayers.Control.MousePosition() );
  click = new OpenLayers.Control.Click();
  map.addControl(click);
  ls.addLayer("traffichotspots");
  ls.addLayer("trafficroads");
  ls.addLayer("highlights");
  ls.addLayer("cameras");
  ls.addLayer("markers");
  custommaps = new OpenLayers.Layer.Markers('custommaps');
  custommap_highlights = new OpenLayers.Layer.Markers('custommap_highlights');
  map.addLayer(custommap_highlights);
  map.addLayer(custommaps);

  //map.addControl( new OpenLayers.Control.LayerSwitcher());
  click = new OpenLayers.Control.Click();
  map.addControl(click);
}

/*
 * optimal resizing to fit the marker bounds
 */
function resizeExtent(bounds){
      bounds.left *= 0.99995;
      bounds.bottom *= 0.99995;
      bounds.right *= 1.00006;
      bounds.top *= 1.00006;
      return bounds;

}

// used with zoomToExtent for showing route result.
function createEnvelope(left,bottom,right,top)
{
  var l,b,r,t;
  if (left > right) { l = right; r = left; }
  else { l = left; r = right; }
  if (top > bottom) { t=top;b=bottom }
  else { t=bottom;b=top; }
  return resizeExtent(new OpenLayers.Bounds(l,b,r,t));
}

/*
 * recenters the map 
 */
function recenterMap(){
    b2 = resizeExtent(bounds);
    map.setCenter(b2.getCenterLonLat());
    zoom = map.getZoomForExtent(bounds);
    map.zoomTo(zoom);
}

function activateClick() {
   click.activate();
}

/*function addData(e) {
   loc = map.getLonLatFromViewPortPx(e.xy);
   marker = BtisMap.createMarker(loc, "", false, "/images/marker.png"); 
   ls.add("publictags", marker);
   get('/public_tags/new?lat='+loc.lat+'&lon='+loc.lon); 

}
*/

function addData(e) {
   loc = map.getLonLatFromViewPortPx(e.xy);
   marker = BtisMap.createMarker(loc, "", false, "/images/marker.png"); 
 //  ls.add("publictags", marker);
   //get('/public_tags/new?lat='+loc.lat+'&lon='+loc.lon); 
  	if(map_click_action == "custommap") {
   	addCustomMap(loc);
	}
	else
	{
	  addLocation(loc);
	}
}

function addPublicTags() {
   get('/public_tags/new?lat='+loc.lat+'&lon='+loc.lon); 
}


function closeInfo() {
   Element.hide('popup');
}

function addLocation(loc) 
{
  custommaps.clearMarkers();	
  if (ls.exists("markers")) 
  {
    ls.clear("markers");
  }
  custommaps.addMarker(marker);
  
  if (map_click_action == "busstops")
  {
    $('add_bus_stop_lat').value = loc.lat;
    $('add_bus_stop_lon').value = loc.lon;
    $('edit_bus_stop_lat').value = loc.lat;
    $('edit_bus_stop_lon').value = loc.lon;
  }
  else if (map_click_action == "alerts")
  {
    $('alert_lat').value = loc.lat;
    $('alert_lon').value = loc.lon;
  }
}

function clearLocation() {
	custommaps.clearMarkers();
	
  if (map_click_action == "busstops")
  {
    $('add_bus_stop_name').value = "";
    $('add_bus_stop_odm_abr').value = "";
    $('add_bus_stop_lat').value = "";
    $('add_bus_stop_lon').value = "";
    $('edit_bus_stop_lat').value = "";
    $('edit_bus_stop_lon').value = "";
  }
  else if (map_click_action == "alerts")
  {
    $('alert_lat').value = "";
    $('alert_lon').value = "";
  }
}

function addCustomMap(loc) {
   custommaps.clearMarkers();
   atoken = $('auth_token').value;
   if (popup != null) { map.removePopup(popup); popup = null; }

   var content = "<span style='position:absolute;top:0px;right:0px;'><img src='/images/close.gif' onClick='closeInfo();' /></span><div id='response' style='padding:7px;border:5px solid #fbef65;height:150px;font-size:12px;background:#fff'><form action='/custom_map/create' onsubmit=\"new Ajax.Request('/custom_map/create', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\"><input type='hidden' name='authenticity_token' value=" + atoken + "><input type='hidden' name=custom_map[lat] value=" + loc.lat + "><input type='hidden' name=custom_map[lon] value=" + loc.lon + "><input type=hidden name=custom_map[zoom] value=" + map.getZoom() + "><span style='color:#000'>Enter a label</span><br/><input type='text' name='custom_map[label]' size='17'/><br/><span style='color:#000'>Notes/Details (optional)</span><br/><textarea name='custom_map[address]' rows=3 cols=20></textarea><br/><input type='submit' value='save' /><input type='button' value='cancel' onClick=\"Element.hide('popup');\" /></form></div>";
   popup = new OpenLayers.Popup("popup",
                               new OpenLayers.LonLat(loc.lon,loc.lat),
                               new OpenLayers.Size(570,510),
                               content,
                               false);
   popup.setSize(new OpenLayers.Size(210,160));
   popup.setOpacity(5.5);
   popup.setBackgroundColor('transparent');
   popup.setBorder('5px solid #4c4c4c');
   map.addPopup(popup);
}

function showCustomMap(result) {
   res = result.custom_map;
   loc = new OpenLayers.LonLat(res.lon, res.lat);
   var offset = function(size) {return new OpenLayers.Pixel(-16,-29);};
   //icon = new OpenLayers.Icon("/images/pink-marker.png",new OpenLayers.Size(30,30),null,offset);
   icon = new OpenLayers.Icon("/images/move.gif",new OpenLayers.Size(30,30),null,offset);
   var fy_offset = function(size) {return new OpenLayers.Pixel(-24,-37);};
   flashing_yellow_icon = new OpenLayers.Icon("/images/highlight.gif",new OpenLayers.Size(45,45),null,fy_offset);
   var options = {"mouseOver":true};
    _text = "<DIV><IMG style='display:block;' src='/images/call_out.png'/></DIV><div style='padding:3px;font-family:Arial;font-weight:bold;background-color:#000;color:#FFF;font-size:10.5px;width:110px;'>";
	 _text += "<div style='text-align:center;'>" + res.label + "</div>";
	 if(res.address != null) {
		_text += "<hr/><div style='text-align:left;'>" + res.address + "</div>";
	 }
	 _text += "</div>";
   marker=new OpenLayers.Marker.Label(loc,icon,_text,options);
	custommaps.addMarker(marker);
   yellow_marker=new OpenLayers.Marker.Label(loc,flashing_yellow_icon,"", options);
	custommap_highlights.addMarker(yellow_marker);
   map.setCenter(loc,res.zoom);
}

/* This function is not used right now. But the idea is to call this function
 * instead of camera/show when a camera is selected from the DDL below the
 * image */
function showCamera(cam_id) {
	camera_id = cam_id;
	current_live_cam_info = LIVE_CAMERAS[camera_id];
	alert($('cam-img'));
   $('cam-img').src = '/cameras/images/' + camera_id;
	stop_camera_auto_rotate();
}

function camera_not_found() {
	if(camera_auto_rotate) {
		autorotate_camera();	
	}
	else {
		$('cam-img').src = "/images/no-recent-image.jpg";
	}
}

function set_camera_meta_data() {
	//current_live_cam_info = LIVE_CAMERAS[camera_id];
	if( current_live_cam_info ) {
		cam_name = current_live_cam_info.label.toUpperCase();
		/* Add the video link next to the camera name only if the video is available for this location */
		if(current_live_cam_info.video_available) {
			cam_name += "&nbsp;<img src='/images/cam.gif' width='16px' height='8px' style='border:0;'>&nbsp;<a href='javascript:void(null);' onClick='javascript:stop_camera_auto_rotate();showVideo("+current_live_cam_info.id+");' style='font-size:8px;letter-spacing:0.1cm;'>VIDEO</a>";
		}
		$('cam-name').innerHTML = cam_name;
		$('cam-locn').innerHTML = (current_live_cam_info.location == null)? " " : current_live_cam_info.location.toUpperCase();
		highlightMarker(current_live_cam_info.lon, current_live_cam_info.lat, current_live_cam_info.label, "cameras");
	}
}

function autorotate_camera() {
	if(camera_auto_rotate) {
		Element.show('live_cam_loading');
		current_live_cam_info = LIVE_CAMERAS[camera_id];
		if(current_live_cam_info == undefined) {
			camera_auto_rotate = false;
			camera_id = 1;
			$('cam-img').src = "/images/recycle-cameras.gif";
			$('cam-name').innerHTML = "CAMERA CYCLE COMPLETE ";
			$('cam-locn').innerHTML = "<a href='javascript:void(null);' onClick='javascript:start_camera_auto_rotate();autorotate_camera();'>SEE CAMERAS AGAIN</a>";
		   return;
		}
		$('cam-img').src = "/cameras/images/" + camera_id + ".jpg?" + (new Date()).getTime();
		camera_id += 1;
	}
}

function camera_on_load() {
	set_camera_meta_data();
	Element.hide("live_cam_loading");
	src = $("cam-img").src.substring($("cam-img").src.lastIndexOf("/")+1, $("cam-img").src.length);
	if($("video_links") && src != "no-recent-image.jpg") {
		$("video_links").show();
	}
}

function camera_on_error() {
	camera_not_found();
	Element.hide("live_cam_loading");
}

function refreshVideo() {
   if($("live-camera")) {
		Element.show('live_cam_loading');
		$('cam-img').src = "/cameras/videos/" + video_id + ".gif?" + (new Date()).getTime();
	}
}

function showVideo(loc_id) {
	Element.show('live_cam_loading');
	stop_camera_auto_rotate();
	video_id = loc_id;
	url = "/cameras/videos/" + video_id + ".gif";
	cam_name = current_live_cam_info.label.toUpperCase();
	cam_name += "<span id='video_links' style='display:none;'>&nbsp;<img src='/images/cam.gif' width='16px' height='8px' style='border:0;'>&nbsp;<a href='javascript:void(null);' style='font-size:8px;letter-spacing:0.1cm;'>VIDEO</a>";
	cam_name += "&nbsp;<a href='javascript:void(null);' onClick='javascript:playVideo();' style='font-size:8px;letter-spacing:0.1cm;'>PLAY</a>";
	cam_name += "&nbsp;<a href='javascript:void(null);' onClick='javascript:refreshVideo();' style='font-size:8px;letter-spacing:0.1cm;'>RELOAD</a></span>";
   $("cam-img").src = url;
	$("cam-name").innerHTML = cam_name;
}

function playVideo() {
	url = "/cameras/videos/" + video_id + ".gif";
   $("cam-img").src = url;
}


function refreshCamera() {
	if($("live-camera")) {
		Element.show('live_cam_loading');
		$('cam-img').src = "/cameras/images/" + camera_id + ".jpg?" + (new Date()).getTime();
	}
}

function stop_camera_auto_rotate() {
	camera_auto_rotate = false;
}

function start_camera_auto_rotate() {
	camera_auto_rotate = true;
}

//short cut for new ajax request - to avoid the length and repetitive 
function get(url){
   new Ajax.Request(url, {method: 'get',asynchronous:true, evalScripts:true,onSuccess:function(transport){transport.responseText.evalScripts();}});
}

//like the above - short cut for ajax updater
function upd(url,target){
    new Ajax.Updater(target, url, {method: 'get',asynchronous:true, evalScripts:true});
}

function getIcon(status) {
   switch (status) {
     case 'Smooth': return '/images/green.gif';break;
     case 'Slow':return '/images/orange.gif';break;
     case 'Delay': return '/images/red.gif';break;
   }
}

function getGenderIcon(gender) {
	if( gender == 'm') {
		return '/images/blue_carpooler.png';
	}
	else if(gender == 'f') {
		return '/images/pink_carpooler.png';
	}
}

function getBusIcon(label) {
	if(label == "VOLVO" || label.startsWith("V")) {
		return '/images/redbus.gif';
	}
	else if(label == "Big10" || label.startsWith("Big10")) {
		return '/images/bus-icon_green.gif';
	}
	return '/images/bus-icon.gif'; 
}

function getBusIconLayer(label)
{
  var image = '/images/bus-icon.gif', layer = 'bmtctrack';
  if (label == "VOLVO" || label.startsWith("V"))
  {
    image = '/images/redbus.gif';
  }
  else if(label == "Big10" || label.startsWith("Big10"))
  {
    layer = 'big10';
    image = '/images/bus-icon_green.gif';
  }

  return [image, layer];
}

function get_congestion_data() {
	var reqURL = '/road_congestion_cache.txt?d=' + (new Date()).getTime();
	new Ajax.Request(reqURL, {method: 'get', asynchronous:true, evalScripts:true, 
								onLoading: function() {
									if ($('loading_indicator')) { Element.show('loading_indicator');}
								},
								onSuccess: function(response) {
     								roads_congestionLayer.destroyFeatures();
     								if (ls.exists("markers")) ls.clear("markers");
	  								try {
     									var response = eval("(" + response.responseText+ ")");
	  								}
	  								catch(e) {
     									var response = eval(response.responseText);
	  								}
									var results = response.locations;
									var _time = response.time;
									var line_features = [];
									var bounds = null;
									results.each(function (result){
										points = [];
										
										rpoints = result["points"];
										for(var i=0;i<rpoints.length;i++) {
       									points.push(new OpenLayers.Geometry.Point(rpoints[i].lon,rpoints[i].lat));
     									}
										lineString = new OpenLayers.Geometry.LineString(points);
										if(!bounds){bounds = lineString.getBounds();}
										bounds.extend(lineString.getBounds());
										line_features.push(new OpenLayers.Feature.Vector(lineString,null,get_style_route(result["speed"])));
										
									});
     								roads_congestionLayer.addFeatures(line_features);
     								map.addLayer(roads_congestionLayer);
	  								roads_congestionLayer.setVisibility(true);
//									map.setCenter(bounds.getCenterLonLat(),map.getZoomForExtent(bounds));	
									if ($('last_updated_at')) { 
										$('last_updated_at').innerHTML = response.time;
									}
									if ($('loading_indicator')) { Element.hide('loading_indicator');}
								}
							});
}

function get_style_route(speed) {
	if (speed < 10) {
      return {
			  strokeColor: "#FF0000",
  			  strokeOpacity: 1,
  			  strokeWidth: 5,
  			  pointRadius: 6,
  			  pointerEvents: "visiblePainted"
		};
	}
	else if (speed > 30) {
      return {
			  strokeColor: "#4AFF1F", //"#99FF33",
  			  strokeOpacity: 1,
  			  strokeWidth: 5,
  			  pointRadius: 6,
  			  pointerEvents: "visiblePainted"
		};
	}
	else {
      return {
			  strokeColor: "#FF9933",
  			  strokeOpacity: 1,
  			  strokeWidth: 5,
  			  pointRadius: 6,
  			  pointerEvents: "visiblePainted"
		};
	}
}

function get_traffic_status(show_traffic_layer, lat, lon, zoom) {
	var _keys = { lat : 'lat', lon : 'lon', label : 'label', root : 'locations' };
	traffic_delays = "<div style='text-align:left;color:#FFDF00;font-weight:bold;margin-bottom:5px;padding:0;'>Delays at &nbsp;&nbsp;";
	traffic_delays_marquee = "<strong> Current Delays at </strong>"
	var reqURL = '/trafficstatus_cache.txt?d=' + (new Date()).getTime();
	new Ajax.Request(reqURL, {method: 'get', asynchronous:true, evalScripts:true, onLoading:function() { if($("trafficstatus")) { $("trafficstatus").innerHTML = "<img src='/images/loading.gif'> Updating";} },
							onSuccess:function(response){ 
								if (lat != undefined && lon != undefined && zoom != undefined) {
									map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
								}
								var _response = eval( "(" + response.responseText + ")" );
								traffic_delays += _response.time.gsub(/-/, ' ') + "</div>";
								BtisMap.showLocations(_response, _keys, 'traffichotspots', false);
								if($('delays')) { 
									$("delays").innerHTML = traffic_delays.gsub(/$<br\/>/, '');
								}
								if(show_traffic_layer != undefined && show_traffic_layer == false) {
									ls.hide('traffichotspots');
									$('traffichotspots').checked = '';
								}
								if($('trafficstatus')) { $('trafficstatus').innerHTML = _response.time; }
							}});
}

function plot_bmtc_track_data() {
	var _keys = { lat : 'lat', lon : 'lon', label : 'desc', root : 'locations' };
  var sel_index = $('routeno').options.selectedIndex;
	var route_no = $('routeno').options[sel_index].value;
  if ($('routeno').selectedIndex == 0)
  {
		new Ajax.Request('/bus_track_cache.txt', { method: 'get', asynchronous:true, evalScripts:true, 
		  onLoading: function() { Element.show("spinner"); }, 
		  onSuccess: function(response)
      {
        BtisMap.showLocations(response.responseText, _keys, 'bmtctrack', false);
        map.zoomTo(12);
        ls.hide('bmtctrack');
        Element.hide("spinner");
      }});
	}
	else
	{
		new Ajax.Request('/bus/track_route?routeno=' + route_no, { method: 'get', asynchronous:true, evalScripts:true, 
      onLoading: function()
      { 
        Element.show("spinner");
        Element.hide("status");
			},
			onSuccess: function(response) { Element.hide("spinner"); }});
	}
}

function setMapCentre() {
	map_center = getMapCenter();
	$('lat').value = map_center.lat;
	$('lon').value = map_center.lon;
}

function toggle_layer(layers, checkbox_status) {
	if (checkbox_status)
	{
	  // If Traffic Roads
	  if (layers == 'trafficroads')
	  {
	    roads_congestionLayer.display(true);
	  }
		else
		{
		  layers.each(function(layer) { ls.show(layer); });
		}
	}
	else
	{
	  // If Traffic Roads
	  if (layers == 'trafficroads')
	  {
	    roads_congestionLayer.display(false);
	  }
		else
		{
		  layers.each(function(layer) { ls.hide(layer); });
		}
	}
}

function setCheckboxStatus(elements, cb_status) {
	if(cb_status) {
		for(var i=0; i<elements.length; i++) {
			el = $(elements[i]);
			if(el) { el.checked = 'checked'; }
		}	
	}
	else {
		for(var i=0; i<elements.length; i++) {
			el = $(elements[i]);
			if(el) { el.checked = ''; }
		}	
	}
}

// This function adds a layer for the drawing of polygons in the Alert Generation module
function fnAddPolyLayer()
{
  alert_zones = new OpenLayers.Layer.Vector("Alert Zones");
  map.addLayer(alert_zones);
  polyControl = new OpenLayers.Control.DrawFeature(alert_zones, OpenLayers.Handler.Polygon);
  map.addControl(polyControl);
}

function fnTogglePoly(chkBox)
{
  if (chkBox.checked)
  {
    polyControl.activate();
  }
  else
  {
    polyControl.deactivate();
  }
}

function fnClearZones()
{
  alert_zones.destroyFeatures();
}

function fnShowZones(zones, alert_zoom)
{
  // Convert polygon to array of points
  var points = fnConvertPoly2Points(zones);

  // Add it to the vector layer
  var ring = new OpenLayers.Geometry.LinearRing(points);
  alert_zones.addFeatures(new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon([ring])));
  
  // Zoom to saved level
//  if (alert_zoom) zoom = alert_zoom;
//  else zoom = 12;
//  
//  bounds = ls.getDataExtent("markers");
//  recenterMap();
}

function fnConvertPoly2Points(zones)
{
  var lth = zones.length;
  var points = zones.substring(9, lth - 2).split(",");
  
  var arr = new Array(points.length);
  for (var i = 0; i < points.length; i++)
  {
    var point = points[i].split(" ");
    arr[i] = new OpenLayers.Geometry.Point(point[0], point[1]);
  }
  
  return arr;
}

function fnSetZones()
{
  if (alert_zones.features.length > 0)
  {
    $('alert_zones').value = alert_zones.features[0].geometry.toString();
    $('alert_zoom').value = map.getZoom();
    alert('Selected zone has been set.');
  }
  else
  {
    alert('No zone has been selected to be set.');
  }
}

function setZoom(_zoom) {
	map.zoomTo(_zoom);
}

function getParkingIcon(status) {
   return (status>0) ? '/images/parking.png' : '/images/no-parking.jpg';
}

function build_parking_listing(locations) {
	if(locations.length == 0) {
   	$('parking_status').innerHTML = "Sorry! This service is not currently available. Please try after sometime";
   	$('parking_status').show();
		return;
	}
   _html = "<ul>";
   locations.each (function(location) {
      lat = location['lat'];
      lon = location['lon'];
      label = location['location'];
      _fn = "BtisMap.showLocation(" + lon + "," + lat + ",'" + label + "', true, 'parking')";
      _html += "<li><A href='javascript:void(null);' onClick=\"" + _fn + "\">"  + location['location'] + "</A></li>";
   } );
   _html += "</ul>";
   $('parking_status').innerHTML = _html;
   $('parking_status').show();
}

function plot_parking_availability() {
   var _keys = { lat : 'lat', lon : 'lon', label : 'location', root : 'locations' };
   new Ajax.Request('/parking_cache.txt', {method: 'get', asynchronous:true, evalScripts:true,
         onLoading:function() {
            Element.show("spinner");
         },
         onSuccess:function(response){
              BtisMap.showLocations(response.responseText, _keys, 'parking', false);
              Element.hide("spinner");
   		},
			onFailure: function(response) {
				  $('parking_status').innerHTML = "Sorry! Could not fetch the parking status at this time. Please try after sometime.";
				  Element.show('parking_status');
				  Element.hide('spinner');
			}
	});
}

var map;
var zoom = 13;
var lat = 18.51558;
var lon= 73.85614;

var ls = new LayerStack();
var markers ;
var cameras ;
var traffichotspots;
var trafficroads;
var cell_ref ;
var bounds ;
var marker;
var color = "#fafdb6";
//var ts = ".mapunity.in/tiles/oltiles";
//var tile_url = [tp+'0'+ts,tp+'1'+ts,tp+'2'+ts,tp+'3'+ts,tp+'4'+ts,tp+'5'+ts];
// The new tile url 
var ts = ".mapunity.org"
var tp = "http://tiles";
var tile_url = [tp+'0'+ts,tp+'1'+ts,tp+'2'+ts,tp+'3'+ts,tp+'4'+ts,tp+'5'+ts];
var minZoom = 10;
var dragControl;
var click;
var popup;
var vectorLayer = new OpenLayers.Layer.Vector("Routes");
var roads_congestionLayer = new OpenLayers.Layer.Vector("Traffic Roads");
var lineFeature = new OpenLayers.Feature.Vector("");
var camera_auto_rotate = true;
var camera_id;
var video_id;

var style_route = {
  strokeColor: "#FF0000",
  strokeOpacity: 1,
  strokeWidth: 3,
  pointRadius: 6,
  pointerEvents: "visiblePainted"
};

var ls = new LayerStack();
var custommaps;
var startIcon;
var endIcon;
var map_click_action;

var LIVE_CAMERAS;
var camera_id;
var traffic_delays;
var traffic_delays_marquee;
var current_live_cam_info;

var alert_zones;
var polyControl;

var camera_display_mode="detailed";
var bus_tracking_info;
