addDOMLoadEvent(maps);

var mymap;

function loadAltitudeGraph(data, labels, colour) {
    if($('altitudegraph')) {
        var series = new Array();
        for(var i=0;i<data.length;i++) {
            series[i] = {data: data[i], label: labels[i], color: '#'+colour[i]
                };
        }
        Flotr.draw($('altitudegraph'), series,{legend: {basckgroundOpacity: 0}} );
    }
}

function maps()
{
    if($('iframe-footer')) {
        height = document.viewport.getHeight();
        $('map').setStyle({height: height - 64 + 'px'});
    }  
    if($('map')&&!$('map').hasClassName('loaded')) {
        $('map').addClassName('loaded');
        mymap  = new Map();
    }
}

function Marker(lat,lng,infowindow,icon,image)
{
    this.lat = lat;
    this.lng = lng;
    this.infowindow = infowindow;
    this.icon = icon;
    this.image = image;

    this.geticonurl = function (i, last, type) {
        if(this.icon=='multi') url='/assets/images/markers/multi-';
        else if(this.icon=='blob') url='/assets/images/markers/blob-';
        else if(this.icon=='tweet') url='/assets/images/markers/twitter-';
        else if(this.icon=='twitpic'||this.icon=="instagram"||this.icon=="twitter_photo"||this.icon=="smugmug"||this.icon=="picasa"||this.icon=='twitgoo'||this.icon=='yfrog'||this.icon=='picplz'||this.icon=='flickr') url='/assets/images/markers/camera-';
        else if(this.icon=='audioboo'||this.icon=='ipadio') url='/assets/images/markers/microphone-';
        else if(this.icon=='gowalla') url='/assets/images/markers/checkin-';
        else if(this.icon=='qik'||this.icon=='bambuser') url='/assets/images/markers/video-';
        else if(this.icon=='rss') url='/assets/images/markers/screen-';
        else if(this.icon=='mountain') url='/assets/images/markers/mountain.png';
        else if(this.icon=='camp') url='/assets/images/markers/camp.png';
        else if(this.icon=='peak') url='/assets/images/markers/peak.png';
        else if(this.icon=='generic') url='/assets/images/markers/generic.png';
        else if(this.icon=='info') url='/assets/images/markers/info.png';
        else if(this.icon=='pub') url='/assets/images/markers/pub.png';
        else if(this.icon=='food') url='/assets/images/markers/food.png';
        else if(this.icon=='castle') url='/assets/images/markers/castle.png';
        else if(this.icon=='house') url='/assets/images/markers/house.png';
        else if(this.icon=='mapmarker') url='/assets/images/markers/mapmarker.png';
        else return null;

        if(url.indexOf('.png')==-1) {
            if(i==0) url += 'green.png';
            else if (i==last) url += 'red.png';
            else url += 'blue.png';
        }

        if(this.image!='') {
            url = this.image;
        }
        return url;
    }
}

function Media()
{
    var mediaupdates = new Array();
    urlparts = window.location.href.split('/');
    var mediacheckurl = urlparts[0] + "//" + urlparts[2] + "/" + urlparts[3] + "/checkmedia/" + urlparts['5'] + "/" + urlparts['6'] + "&r=" + Math.floor(Math.random()*1000000);
    var mediaurl = urlparts[0] + "//" + urlparts[2] + "/" + urlparts[3] + "/media/" + urlparts['5'] + "/" + urlparts['6'] + "&r=" + Math.floor(Math.random()*1000000);
    var maplive;
    if($('map_live')&&$('map_live').getValue()=='SET') maplive = true; else maplive = false;

    updatemedia = function(type, difference, firstload) {
        if(!firstload)
        {
          new Ajax.Updater($(type+'page').down('.media_update_area'),mediaurl+"&type="+type,{evalScripts: true, onSuccess: function(transport)
              {
                  $(type+'tab').down('.media_loading').hide();
                  if($(type+'tab').down('.counter').innerHTML!=""&&$(type+'tab').down('.counter').innerHTML!="L") difference = parseInt(difference) + parseInt($(type+'tab').down('.counter').innerHTML);
                  else if ($(type+'tab').down('.counter').innerHTML=="L") difference = 0;
                  else {
                      difference = parseInt(difference);
                      //alert(difference);
                  }
                  if(difference>9) difference = '+';
                  $(type+'tab').down('.counter').innerHTML = difference;
                  $(type + 'tab').show();
                  if(!firstload&&!$(type+'tab').hasClassName('active')&&difference>0) {
                      Effect.Appear($(type+'tab').down('.counter'));
                  } else $(type+'tab').down('.counter').innerHTML = 0;
                  mymap.loadwatchers();
              }});
        } else {
            $(type + 'tab').show();
            $(type+'tab').down('.counter').innerHTML = "";
        }
    }

    loadmedia = function(firstload) {
        var x = $$('.tabs li');
        for (var i=0; i<x.length;i++)
        {
            var id = $(x[i]).identify();
            if(id!='mapstatstab') {
                  new Ajax.Request(mediacheckurl+"&type="+id.replace('tab', ''),
                  {
                    onSuccess: function(transport) {
                        var response = transport.responseText.split(',');
                        
                        if((mediaupdates[response[0]]==undefined && response[1]>0)||response[1]>mediaupdates[response[0]]) {
                            if(mediaupdates[response[0]]==undefined) {
                              mediaupdates[response[0]]=0;
                            }
                            difference = response[1] - mediaupdates[response[0]];
                            mediaupdates[response[0]]=response[1];
                            updatemedia(response[0], difference, firstload);
                        }
                    }
                  });
            }
        }
    }

    var x = $$('.tabs li');
    for (var i=0; i<x.length;i++)
    {
        var id = $(x[i]).identify();
        Event.observe($(x[i]), 'click', function(e)     {
            Event.stop(e);
            $('subpages').select("div.page").each(function(s){
                    s.setStyle({visibility: 'hidden'});
            });
            $('pagetabs').select("li").each(function(s){
                    s.removeClassName('active');
            });
            targetid = this.identify().replace('tab', 'page');
            if(targetid=='mapstatspage') targetid='mapstats';
            $(targetid).setStyle({visibility: 'visible'});
            this.addClassName('active');
            var counter = this.down('.counter');
            Effect.Fade(this.down('.counter'), {afterFinish: function() {counter.innerHTML = 0;}});
        }, false);
    }

    this.loadwatchers = function () {
        if(maplive) {
            new PeriodicalExecuter(function() {loadmedia(false);}, 60);
        }
    }

    this.loadmedia = function (firstload) {
        loadmedia(firstload);
        if(maplive) this.loadwatchers();
    }    
}

function Map()
{
    urlparts = window.location.href.split('/');
    var map_type;
    var display_type;
    var map_format;
    var last_updated = null;
    if(!$('map_format')) map_format = urlparts[4];
    else map_format = $('map_format').getValue();
    if($('display_type')) display_type=$('display_type').getValue(); else display_type=null;
    if($('map_type')) map_type=$('display_type').getValue(); else map_type=null;

    var markerscount = 0;
    var maplive;
    if($('map_live')&&$('map_live').getValue()=='SET') maplive = true; else maplive = false;
    var mapmarkers = new Array();
    var firstload = true;

    var markersurl = urlparts[0] + "//" + urlparts[2] + "/" + urlparts[3] + "/getmarkers/" + urlparts['5'] + "/" + urlparts['6'] + "&r=" + Math.floor(Math.random()*1000000);
    var statsurl = urlparts[0] + "//" + urlparts[2] + "/" + urlparts[3] + "/getstats/" + urlparts['5'] + "/" + urlparts['6'] + "&r=" + Math.floor(Math.random()*1000000) + "&type=" + map_format;
    var updatedurl = urlparts[0] + "//" + urlparts[2] + "/" + urlparts[3] + "/last_updated/" + urlparts['5'] + "/" + urlparts['6'] + "&r=" + Math.floor(Math.random()*1000000);

    loadroutelayer = function() {
        if($('route')&&$('route').getValue()!='') {
            routeurlparts = $('route').getValue().split('/');
            routeurl = routeurlparts[0] + '/getmarkers/' + routeurlparts[2] + '/' + routeurlparts[3];
            GDownloadUrl(routeurl, function(data) {
                var xml = GXml.parse(data);
                var lines = xml.documentElement.getElementsByTagName("line");
                for (var i = 0; i < lines.length; i++) {
                    if($('routecolour')&&$('routecolour').getValue()!="") colour = $('routecolour').getValue();
                    else colour = lines[i].getAttribute("colour");
                    points = lines[i].getElementsByTagName("point");
                    mapobj.drawroute(colour, points, false);
                }
            }); 
        }
    }

    loadmap = function() {
        if($('maploading')) $('maploading').show();
        if($('show_all')&&$('show_all').getValue()=='SET') var showall = true; else var showall = false;
        if(firstload) {
            var media = new Media();
        }
        GDownloadUrl(markersurl, function(data) {
            var xml = GXml.parse(data);
            var mapmarkers = xml.documentElement.getElementsByTagName("markerset");
            var lines = xml.documentElement.getElementsByTagName("line");
            if(map_format!='iframe'&&maplive&&!firstload) {
                if($('mapstats')) {
                    new Ajax.Updater($('mapstats').down('.media_update_area').identify(), statsurl, {
                        method: 'post', evalScripts: true
                    });
                }
            }
            
            mapobj.loadmap(lines, mapmarkers, maplive, firstload, showall, map_type);

            if(firstload) media.loadmedia(true);
            firstload = false;
               
            loadroutelayer();

            if($('maploading')) $('maploading').hide();
        });

    }

    isupdated = function() {
          new Ajax.Request(updatedurl,
          {
            onSuccess: function(transport) {
                var response = transport.responseText;
                if(last_updated==null||last_updated!=response) {
                    last_updated = response;
                    loadmap();
                }
            }
          });
    }

    var mapobj;

    this.loadwatchers = function () {
        var x = $$('.jump');
        for (var i=0; i<x.length;i++)
        {
            $(x[i]).stopObserving('click');
            Event.observe($(x[i]), 'click', function(e)     {
                Event.stop(e);
                mapobj.jumpto(this.getAttribute('data-lat'),this.getAttribute('data-lng'));
            }, false);
        }
    }

    set_mapobj = function(type)
    {
        if(type=='os') mapobj = new OSMap();
        else mapobj = new GoogleMap();
        
        if($('map')) isupdated();
        mapobj.clearmap();
    }
    
    if(display_type=="os") {
        var supportService = new OpenSpace.SupportService(); 
        function tileCountResults(tilesUsed, maxTiles) 
        { 
            if(tilesUsed/maxTiles>0.99) {
                if(map_format!='iframe') alert('Sorry our OS API allowance has been used up - switching to Google Maps');
                set_mapobj('google');
            } else set_mapobj('os');
        }
        supportService.getTileCount(tileCountResults);
        
    }
    
    else set_mapobj('google');
    this.loadwatchers();
    
    if(maplive) {
        new PeriodicalExecuter(function() {isupdated();}, 60);
    }
}

function OSMap()
{
    this.errormessage = "It looks like the Ordnance Survey Openspace site is down - please try again later!";
    if ($('map')) {
        try {
            this.map = new OpenSpace.Map('map');
            var gridProjection = new OpenSpace.GridProjection();
            var myLonLat = new OpenLayers.LonLat($('map').getAttribute('data-startlng'), $('map').getAttribute('data-startlat'));
            this.map.setCenter(gridProjection.getMapPointFromLonLat(myLonLat), 1);
        } catch(err) {
            //alert(this.errormessage);
            //return null;
        }
    }

    this.loadmap = function (lines, markers, maplive, firstload, showall, type) {
        this.clearmap();
        for (var i = 0; i < lines.length; i++) {
            colour = lines[i].getAttribute("colour");
            points = lines[i].getElementsByTagName("point");
            this.drawroute(colour, points, true);
        }
        
        
        for (i = 0; i < markers.length; i++) {
            mapmarkers = new Array();
            markerset = markers[i].getElementsByTagName("marker");
            for (var p = 0; p < markerset.length; p++) {
                infowindow = GXml.value(markerset[p].getElementsByTagName("infowindow")[0]);
                mapmarkers[p] = new Marker(markerset[p].getAttribute("lat"),markerset[p].getAttribute("lng"),infowindow,markerset[p].getAttribute("icon"),markerset[p].getAttribute("image"));
            }
            lastmarker = this.loadmarkers(mapmarkers, showall,type);
        }  

        if(getURLVariable('lat')!=''&&getURLVariable('lng')!='') {
            myLonLat = new OpenLayers.LonLat(getURLVariable('lng'), getURLVariable('lat'));
            myMapPoint = gridProjection.getMapPointFromLonLat(myLonLat);
            this.map.setCenter(myMapPoint, 7);
            if(lastmarker!=null) this.map.openInfoWindow(lastmarker[0],lastmarker[1],lastmarker[2],lastmarker[3]);
        } else if(maplive&&firstload&&lastmarker!=null&&type!='challenge') {
            this.map.setCenter(lastmarker[1], 7);
            this.map.openInfoWindow(lastmarker[0],lastmarker[1],lastmarker[2],lastmarker[3]);
        } else if(!maplive||type=='challenge') {
            this.map.setCenter(this.bounds.getCenterLonLat(), 5);
            this.bounds.toBBOX();
            this.map.zoomToExtent(this.bounds);
        }
    }

    this.jumpto = function (lat, lng) {
        myLonLat = new OpenLayers.LonLat(lng, lat);
        myMapPoint = gridProjection.getMapPointFromLonLat(myLonLat);
        this.map.setCenter(myMapPoint, 7);
    }

    this.loadmarkers = function (markers, showall,type) {
       lastmarker = null;
        
       mymarkers = new Array();
       for (var i = 0; i < markers.length; i++) {
            mymarkers[i] = markers[i];    
       }

        for(i=0;i<mymarkers.length;i++) {

            if(!(mymarkers[i].icon=="blob" && i>0&&i!=mymarkers.length-1&&!showall)) {
                useIcon = this.createmarker(mymarkers[i], i, mymarkers.length-1, type);
                if(useIcon!=null) {
                    myLonLat = new OpenLayers.LonLat(mymarkers[i].lng, mymarkers[i].lat);
                    myMapPoint = gridProjection.getMapPointFromLonLat(myLonLat);
                    if(mymarkers[i].icon=="blob") infoWindowSize = new OpenLayers.Size(300,175);
                    else infoWindowSize = new OpenLayers.Size(400,250);
                    this.map.createMarker(myMapPoint, useIcon, mymarkers[i].infowindow, infoWindowSize);
                    if ((getURLVariable('lat')==""&&getURLVariable('lng')=="")||(getURLVariable('lat')==parseFloat(mymarkers[i].lat)&&getURLVariable('lng')==parseFloat(mymarkers[i].lng)))
                        lastmarker = new Array(useIcon, myMapPoint, mymarkers[i].infowindow, infoWindowSize);
                }
            }
        }

       return lastmarker;
    }

    this.createmarker = function(marker, i, last, type) {
        if(marker.image!='') {
            iconSize = new OpenLayers.Size(30,30);
            iconOffset = new OpenLayers.Pixel(-15,-15);
            infoWindowAnchor = new OpenLayers.Pixel(15,15);
        } else if(marker.icon=='blob') {
            iconSize = new OpenLayers.Size(12,12);
            iconOffset = new OpenLayers.Pixel(-6,-6);
            infoWindowAnchor = new OpenLayers.Pixel(6,6);
        } else {
            iconSize = new OpenLayers.Size(20,20);
            iconOffset = new OpenLayers.Pixel(-10,-10);
            infoWindowAnchor = new OpenLayers.Pixel(10,10);
        }

        url = marker.geticonurl(i, last, type);
        if(url!=null) return new OpenSpace.Icon(url, iconSize, iconOffset, null, infoWindowAnchor);
        else return null;
    }

    this.drawroute = function (colour, points, bounds) {
       var map_points = new Array();
       var style = {
            strokeOpacity: 0.7,
            strokeWidth: 8
       };
       style.strokeColor = "#" + colour;
       var linesLayer = this.map.getVectorLayer();
       this.map.addLayer(linesLayer); 
       
       for (var i = 0; i < points.length; i++) {

           myLonLat = new OpenLayers.LonLat(points[i].getAttribute('lng'), points[i].getAttribute('lat'));
           myMapPoint = this.gridProjection.getMapPointFromLonLat(myLonLat);
           map_points[i] = new OpenLayers.Geometry.Point(myMapPoint.getEasting(), myMapPoint.getNorthing());
           if(bounds) this.bounds.extend(myMapPoint);
       }

       if(!($('show_lines')&&$('show_lines').getValue()=="0")) {
           // SYA-4: O/S library dislikes empty point array on Android browser
           if(map_points.length > 0) {
               var lineFeature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(map_points), null, style);
               linesLayer.addFeatures([lineFeature]);
           }
       }
    }

    this.clearmap = function () {
        this.map.destroyFeatures();
        this.map.clearMarkers();
        this.bounds = new OpenSpace.MapBounds();
        this.gridProjection = new OpenSpace.GridProjection();
    }
}

function GoogleMap()
{
    this.errormessage = "It looks like Google Maps is down - please try again later!";
    if ($('map')) {
        try {
            this.map = new GMap2($('map'));
            this.map.setCenter(new GLatLng($('map').getAttribute('data-startlat'), $('map').getAttribute('data-startlng')), 6);
            this.map.setUIToDefault();
            this.map.addMapType(G_SATELLITE_3D_MAP);

            var mapControl = new GMapTypeControl();
            this.map.addControl(mapControl);
            switch($('default_gmap').getValue())
            {
                case ("G_PHYSICAL_MAP"):type = G_PHYSICAL_MAP;break;
                case ("G_HYBRID_MAP"):type = G_HYBRID_MAP;break;
                case ("G_SATELLITE_3D_MAP"):type = G_PHYSICAL_MAP;break;
                case ("G_SATELLITE_MAP"):type = G_SATELLITE_MAP;break;
                case ("G_NORMAL_MAP"):type = G_NORMAL_MAP;break;
            }
            this.map.setMapType(type);
        } catch(err) {
            //alert(this.errormessage);
        }
    }

    this.loadmap = function (lines, markers, maplive, firstload, showall, type) {
        this.clearmap();
        for (var i = 0; i < lines.length; i++) {
            colour = lines[i].getAttribute("colour");
            points = lines[i].getElementsByTagName("point");
            this.drawroute(colour, points, true);
        }
        
        for (i = 0; i < markers.length; i++) {
            mapmarkers = new Array();
            markerset = markers[i].getElementsByTagName("marker");
            for (var p = 0; p < markerset.length; p++) {
                infowindow = GXml.value(markerset[p].getElementsByTagName("infowindow")[0]);
                mapmarkers[p] = new Marker(markerset[p].getAttribute("lat"),markerset[p].getAttribute("lng"),infowindow,markerset[p].getAttribute("icon"),markerset[p].getAttribute("image"));
            }
            lastmarker = this.loadmarkers(mapmarkers, showall,type);
        }  
        
        if(getURLVariable('lat')!=''&&getURLVariable('lng')!='') {
            point = new GLatLng(parseFloat(getURLVariable('lat')),parseFloat(getURLVariable('lng')));
            this.map.setCenter(point, 13);
            if(lastmarker!=null) this.map.openInfoWindowHtml(this.map.getCenter(), lastmarker[1]);
        } else if(maplive&&firstload&&lastmarker!=null&&type!='challenge') {
            this.map.setCenter(lastmarker[0], 13);
            this.map.openInfoWindowHtml(this.map.getCenter(), lastmarker[1]);
        } else if(!maplive||type=='challenge') {
            this.map.setCenter(this.bounds.getCenter());
            if (this.map.getBoundsZoomLevel(this.bounds)>15) zoom = 15; else zoom = this.map.getBoundsZoomLevel(this.bounds);
            this.map.setZoom(zoom);
        }
    }

    this.jumpto = function (lat, lng) {
        point = new GLatLng(parseFloat(lat),parseFloat(lng));
        this.map.setCenter(point, 13);
    }

    this.loadmarkers = function (markers, showall,type) {
       lastmarker = null;
       mymarkers = new Array();
       for (var i = 0; i < markers.length; i++) {
            mymarkers[i] = markers[i];
       }

        for(i=0;i<mymarkers.length;i++) {
            if(!(mymarkers[i].icon=="blob" && i>0&&i!=mymarkers.length-1&&!showall)) {
                useIcon = this.createmarker(mymarkers[i], i, mymarkers.length-1, type);
                if(useIcon!=null) {
                    point = new GLatLng(parseFloat(mymarkers[i].lat),parseFloat(mymarkers[i].lng));
                    marker = new GMarker(point, {icon: useIcon});
                    this.map.addOverlay(marker);
                    marker.bindInfoWindow(mymarkers[i].infowindow);
                    if ((getURLVariable('lat')==""&&getURLVariable('lng')=="")||(getURLVariable('lat')==parseFloat(mymarkers[i].lat)&&getURLVariable('lng')==parseFloat(mymarkers[i].lng)))
                        lastmarker = new Array(point, mymarkers[i].infowindow);
                }
            }
        }
       return lastmarker;
    }

    this.createmarker = function(marker, i, last, type) {
        if (marker.image!="") {
            iconSize = new GSize(30,30);
            iconAnchor = new GPoint(15,15);
            infoWindowAnchor = new GPoint(15,15);
        } else if(marker.icon=='blob') {
            iconSize = new GSize(12,12);
            iconAnchor = new GPoint(6,6);
            infoWindowAnchor = new GPoint(6,6);
        } else {
            iconSize = new GSize(20,20);
            iconAnchor = new GPoint(10,10);
            infoWindowAnchor = new GPoint(10,10);
        }

        url = marker.geticonurl(i, last, type);
        if(url!=null) {
            icon = new GIcon();
            icon.image = url;
            icon.iconSize = iconSize;
            icon.iconAnchor = iconAnchor;
            icon.infoWindowAnchor = infoWindowAnchor;
            return icon;
        }
        else return null;
    }

    this.drawroute = function (colour, points, bounds) {
       var map_points = new Array();
       for (var i = 0; i < points.length; i++) {
           var point = new GLatLng(parseFloat(points[i].getAttribute('lat')),parseFloat(points[i].getAttribute('lng')));
           map_points[i] = point;
           if(bounds) this.bounds.extend(point);
       }

       if(!($('show_lines')&&$('show_lines').getValue()=="0")) {
           var polyline = new GPolyline(map_points, "#" + colour);
           this.map.addOverlay(polyline);
       }

    }

    this.clearmap = function () {
        this.bounds = new GLatLngBounds();
        this.map.clearOverlays();
    }
}
