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); 
                }
                if(layer == "bmtctrack" && ls.exists("big10")) {
                    ls.clear("big10");
                }
                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") {
                    if(ls.exists(layer)) { 
                        bounds = ls.getDataExtent(layer);
                    }
                    if(ls.exists("big10")) {
                        bounds = ls.getDataExtent('big10');
                    }
                    recenterMap();
                }
                else { 
                    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")
                    {
                        if(traffic_delays == undefined) { traffic_delays = "";}
                        //traffic_delays = traffic_delays + "<a href='javascript:void(null);'>" + result[keys['label']] + "&nbsp; (" + result['smscode'] + ")</a><br/>";
                        traffic_delays = traffic_delays + result[keys['label']] + "&nbsp; (" + result['smscode'] + ")<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){ Element.show("result-div");$("cam-img").src = "/cameras/images/"+result.id+".jpg";$("cam-name").innerHTML = result[keys['label']].toUpperCase();if(result['locn'] != null) { $("cam-locn").innerHTML = result['locn'].toUpperCase(); } else { $("cam-locn").innerHTML = ""; } camera_id = result.id;});
                                }
                                else
                                    {
                                        marker.events.register('click', marker, function(e){ get('/camera/show?id='+result.id);}); 
                                    }
                                }
                                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];
                                                            $('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() {
                                                            /*alert(camera_id);
                                                            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>";
                                                                }
                                                                if($('cam-name')) { $('cam-name').innerHTML = cam_name; }
                                                                if($('cam-locn')) { 
                                                                    $('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") && camera_id != undefined) {
                                                                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 show_road_congestion(roads) {   
                                                                    roads_congestionLayer.destroyFeatures();
                                                                    if (ls.exists("markers")) ls.clear("markers");                                                                                                        
                                                                    var line_features = [];
                                                                    var bounds = null;                                                                                                                               
                                                                    try {
                                                                        var response = eval("(" + roads + ")");                                                                        
                                                                    }
                                                                    catch(e) {                                                                        
                                                                        var response = eval(roads);
                                                                    }                                                                    
                                                                    var results = response.locations;
                                                                    var _time = response.time;
                                                                    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);                                                                    
                                                                }
                                                                
                                                                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 load_cameras(data) {                                                                     
                                                                    var _keys = { lat : 'lat', lon : 'lon', label : 'label', root : 'locations' };
                                                                    try {
                                                                        var response = eval("(" + data + ")");                                                                        
                                                                    }
                                                                    catch(e) {                                                                        
                                                                        var response = eval(data);
                                                                    }                                                                             
                                                                    LIVE_CAMERAS = response.cams;
                                                                    BtisMap.showLocations(data, _keys, 'cameras', false);
                                                                    toggle_layer(['cameras'], false);                                           
                                                                }
                                                                
                                                                function load_camera_locations() {
                                                                    new Ajax.Request("/main/cameras", {asynchronous:true, evalScripts:true, method:"get"});
                                                                }
                                                                
                                                                function show_traffic_status(locations, lat, lon, zoom)
                                                                {
                                                                    var _keys = { lat : 'lat', lon : 'lon', label : 'label', root : 'locations' };
                                                                    BtisMap.showLocations(locations, _keys, 'traffichotspots', false);
                                                                    if (lat != undefined && lon != undefined && zoom != undefined) {
                                                                        map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
                                                                    }
                                                                    if($('delays')) { 
                                                                        $("delays").innerHTML = traffic_delays.gsub(/$<br\/>/, '');
                                                                    }
                                                                }
                                                                
                                                                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;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() { $('loading_indicator_text').innerHTML = 'Loading traffic hot spots'; $('loading_indicator').show(); },
                                                                        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; }
                                                                            hideLoadingIndicator();
                                                                        }});
                                                                    }
                                                                    
                                                                    function plot_bmtc_track_data() 
                                                                    {
                                                                        var _keys = { lat : 'lat', lon : 'lon', label : 'desc', root : 'locations' };
                                                                        if ($('t_routeno').selectedIndex == 0)
                                                                            {
                                                                                new Ajax.Request('/bus_track_cache.txt', { method: 'get', asynchronous:true, evalScripts:true, 
                                                                                    onLoading: function() { showLoadingIndicator('Loading bus positions...'); $('loading_indicator').show();}, 
                                                                                    onFailure: function(response) { showLoadingIndicator("Failed to load the bus positions. Please try later.");setTimeout(hideLoadingIndicator(), 10000);},
                                                                                    onSuccess: function(response)
                                                                                    {
                                                                                        BtisMap.showLocations(response.responseText, _keys, 'bmtctrack', false);
                                                                                        map.zoomTo(12);
                                                                                        ls.hide('bmtctrack');
                                                                                        hideLoadingIndicator();
                                                                                    }});
                                                                                }
                                                                                else
                                                                                    {
                                                                                        var sel_index = $('t_routeno').options.selectedIndex;
                                                                                        var route_no = $('t_routeno').options[sel_index].value;
                                                                                        new Ajax.Request('/bus/track_route?t_routeno=' + route_no, { method: 'get', asynchronous: true, evalScripts: true, 
                                                                                            onLoading: function()
                                                                                            { 
                                                                                                showLoadingIndicator('Loading bus positions...');
                                                                                            },
                                                                                            onSuccess: function(response) { hideLoadingIndicator(); }});
                                                                                    }
                                                                                }
                                                                                
                                                                                function plot_bmtc_route_track(route_no)
                                                                                {
                                                                                    new Ajax.Request('/bus/track_route?t_routeno=' + route_no, { method: 'get', asynchronous: true, evalScripts: true, onLoading: function() { showLoadingIndicator('Loading bus positions');}, onSuccess: function() {  hideLoadingIndicator(); }  });
                                                                                }
                                                                                
                                                                                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() {
                                                                                                                                        showLoadingIndicator("Loading...");
                                                                                                                                    },
                                                                                                                                    onSuccess:function(response){
                                                                                                                                        BtisMap.showLocations(response.responseText, _keys, 'parking', false);
                                                                                                                                        hideLoadingIndicator();
                                                                                                                                    },
                                                                                                                                    onFailure: function(response) {
                                                                                                                                        $('parking_status').innerHTML = "Sorry! Could not fetch the parking status at this moment. Please try after sometime.";
                                                                                                                                        Element.show('parking_status');
                                                                                                                                        hideLoadingIndicator();
                                                                                                                                    }
                                                                                                                                });
                                                                                                                            }
                                                                                                                            
                                                                                                                            function setDefaultMapPosition() {
                                                                                                                                map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
                                                                                                                            }
                                                                                                                            
                                                                                                                            var map;
                                                                                                                            var zoom = 12;
                                                                                                                            var lat = 12.9600;
                                                                                                                            var lon= 77.60181;
                                                                                                                            
                                                                                                                            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;                                                                                                                       
                                                                                                                            