﻿var map,positionTime;
var opacity=.8,lineColor = "#FFFF99";
var lineWeight = 2,baseIcon,baseIconSmall,currentPosition,loadCount=0,nextPoint;
var lastID,animateTimer,boatMarker,animatePoints=[],animateTimes=[],blogEntries=[];
var loadFromXML=true,autoChangedMapType=false;
function load() {
    if (GBrowserIsCompatible()) {
        positionTime=document.getElementById("positionTime");
        map = new GMap2(document.getElementById("map"));
        map.addControl(new GHierarchicalMapTypeControl());
        map.addControl(new GSmallMapControl());
        var scalePos = new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(10,20));
        map.addControl(new GScaleControl(),scalePos); 
        GEvent.addListener(map, "zoomend", mapZoomend);

        map.setMapType(G_SATELLITE_MAP);
        baseIcon = new GIcon();
        baseIcon.iconSize = new GSize(21, 31);
        baseIcon.iconAnchor = new GPoint(7, 31);
        baseIcon.infoWindowAnchor = new GPoint(9, 2);
        baseIcon.shadow = "images/shadow.png";
        baseIcon.shadowSize = new GSize(52, 29);
        baseIcon.infoShadowAnchor = new GPoint(10, 29);
        
        baseIconSmall = new GIcon();
        baseIconSmall.iconSize = new GSize(12, 16);
        baseIconSmall.iconAnchor = new GPoint(4, 15);
        baseIconSmall.infoWindowAnchor = new GPoint(4, 15);
        baseIconSmall.shadow = "images/shadowSmall.png";
        baseIconSmall.shadowSize = new GSize(23, 13);
        baseIconSmall.infoShadowAnchor = new GPoint(5, 12);
        loadPositions();
    }
}
function createBoatMarker(point){
    var markerIcon;
    
    markerIcon = new GIcon(baseIcon);
    markerIcon.image = "images/boat.png";

    boatMarker=new GMarker(point,{title:"Olly Hicks in the Flying Carrot", icon:markerIcon});
    map.addOverlay(boatMarker);
}
function loadPositions(){
    var url,d=new Date();
    
    if (loadFromXML)url="http://www.eventserver.co.uk/raceplayer/data/xml/oce/E/108/positions_aspx/positions_aspx_subjectType=E&subjectID=108&dateFrom=&dateTo=&app=oce&loadmode=backward";
    else url="http://www.eventserver.co.uk/raceplayer/data/positions.aspx?subjectType=E&subjectID=108&dateFrom=&dateTo=&app=oce&loadmode=backward";
    
    if (lastID!=null) url+="&lastID="+lastID;
    if (loadFromXML) url+=".xml?rnd="+d.getHours();

    GDownloadUrl(url, onLoadPositions);
}
function onLoadPositions(data, responseCode) {
    var xmlPositions, positionNodes, i,trackLine,lineStartPoints=[];
    var lat,lng,minLat=999,maxLat=-999,minLng=999,maxLng=-999;
    var swPoint,nePoint,bounds,zoom,numNodes,dat,msec,points=[];
    
    if (responseCode == 200) {
        xmlPositions= GXml.parse(data);
        positionNodes = xmlPositions.documentElement.getElementsByTagName("p");
        numNodes=positionNodes.length;
        loadCount++;
        if (numNodes>0){
            lastID=xmlPositions.documentElement.getAttribute("lastID");
            for (i = 0; i < numNodes; i++) {
                lat=parseFloat(positionNodes[i].getAttribute("a"));
                lng=parseFloat(positionNodes[i].getAttribute("o"));
                msec=parseInt(positionNodes[i].getAttribute("t"));
                minLat=Math.min(minLat,lat);
                maxLat=Math.max(maxLat,lat);
                minLng=Math.min(minLng,lng);
                maxLng=Math.max(maxLng,lng);
                point = new GLatLng(lat,lng);
                if (currentPosition==null){
                    currentPosition=point;
                    map.setCenter(currentPosition, 3);
                    dat=new Date();
                    dat.setTime(msec); 
                }
                points.push(point);
                if (loadCount==1){
                    animatePoints.unshift(point);
                    animateTimes.unshift(msec);
                }
            }
            
            if (loadCount==1){
                swPoint=new GLatLng(minLat-0.5,minLng-0.5);
                nePoint=new GLatLng(maxLat+0.5,maxLng+0.5);

                bounds=new GLatLngBounds(swPoint,nePoint);
                zoom=map.getBoundsZoomLevel(bounds);
                if (zoom>17)zoom=17;
                if (zoom<5)zoom=5;
                if (numNodes>100){
                    nextPoint=numNodes-100;
                    for (i=0;i<nextPoint+1;i++){
                        lineStartPoints.push(animatePoints[i]);
                    }
                    trackLine = new GPolyline(lineStartPoints,lineColor,lineWeight,opacity);
                    //boatMarker.setLatLng(animatePoints[nextPoint]);
                    map.addOverlay(trackLine);
                }else { 
                    nextPoint=0;
                }
                createBoatMarker(animatePoints[nextPoint]);
                //map.setCenter(new GLatLng((swPoint.lat()+nePoint.lat())/2,(swPoint.lng()+nePoint.lng())/2), zoom);
                map.setCenter(animatePoints[animatePoints.length-1], zoom);
                animateTimer=setTimeout(drawNextPoint,5000);
            }else{
                trackLine = new GPolyline(points,lineColor,lineWeight,opacity);
                map.addOverlay(trackLine);
                loadFromXML=true;
                loadPositions();
            }
        }else{
            document.getElementById("progress").style.display="none";
            document.getElementById("progress").style.visibility="hidden"
            map.addMapType(G_SATELLITE_3D_MAP);
            overlayBlog();
        }
    }else{//load failed
        if (loadFromXML){//were attempting to load from xml, try from .net
            loadFromXML=false;
            loadPositions();
        }else{
            document.getElementById("progress").style.display="none";
            document.getElementById("progress").style.visibility="hidden"
            map.addMapType(G_SATELLITE_3D_MAP);
            overlayBlog();        
        }
    }
}
function mapZoomend(oldLevel,newLevel){
    var currentMapType=map.getCurrentMapType();
    
    if (currentMapType.getName()=="Satellite" && oldLevel<newLevel && newLevel==9){
        map.setMapType(G_NORMAL_MAP);
        autoChangedMapType=true;
    }else if (currentMapType.getName()=="Map" && autoChangedMapType && oldLevel>newLevel && newLevel==8){
        map.setMapType(G_SATELLITE_MAP);
        autoChangedMapType=false;
    }
}
function overlayBlog(){
    var url="http://www.eventserver.co.uk/virginglobalrow/requesthandler.aspx?url=http://admin.octracker.net/rss/vgr.xml";
    var d=new Date();
    
    url+="?rnd="+d.getMilliseconds();
    GDownloadUrl(url, onLoadBlog);
}
function onLoadBlog(data, responseCode) {
    var xmlEntries= GXml.parse(data),entryNodes, i;
    var lat,lng,positionText,txt,caption='entry',blogIcon,blog,summary,url;
    
    entryNodes = xmlEntries.documentElement.getElementsByTagName("entry");
    blogIcon = new GIcon(baseIconSmall);
    blogIcon.image = "images/blogSmall.png";
    
    for (i=0;i<entryNodes.length;i++){
        positionText=getElementText(entryNodes[i],"georss:point");
        caption=getElementText(entryNodes[i],"title");
        summary=getElementText(entryNodes[i],"content");
        url=getElementText(entryNodes[i],"feedburner:origLink");
        if (positionText!=undefined){
            blog=new BlogEntry(summary,url,caption,positionText);
            blogEntries.push(blog);
            createBlogMarker(blog,blogIcon);
        }
    }
}
function BlogEntry(summary,url,caption,positionString){
    var values=positionString.split(" "),lat,lng;
    
    lat=values[0];
    lng=values[1];
    this.point=new GLatLng(parseFloat(lat),parseFloat(lng));
    this.summary=summary;
    this.url=url;
    this.caption=caption;
}
function createBlogMarker(blog,icon){
    var blogMarker=new GMarker(blog.point,{title:blog.caption,icon:icon});
    var html="<div class='blogSummary'><h3>"+blog.caption+"</h3>";
    
    html+=stripAllLinks(blog.summary).substring(0,200)+"...<br/>";
    html+="<a target='_blank' href='"+blog.url+"'>read more</a></div>";
    map.addOverlay(blogMarker);
    GEvent.addListener(blogMarker, "click", function() {blogMarker.openInfoWindowHtml(html);});
    
    return blogMarker;
}
function stripAllLinks(input){
    var output=input,temp='';
    
    while (output!=temp){
        temp=output;
        output=stripLinks(output);
    }
    return output;
}
function stripLinks(input){
    var lnkStart=input.indexOf("<a href="),lnkEnd;
    var output=input;
    
    if (lnkStart>-1){
        lnkEnd=input.indexOf("</a>",lnkStart);
        if (lnkEnd>-1){
            output=input.substring(0,lnkStart)+input.substring(lnkEnd+4,input.length);
        }
    }
    return output;
}
function getElementText(el,name){
    var txt,nodes=el.getElementsByTagName("*"),i;
    
    for (i=0;i<nodes.length;i++){
        if (nodes[i].nodeName==name){
            txt=nodes[i].firstChild.nodeValue;
            break;
        }
    }
    return txt;
}
function drawNextPoint(){
    var point,trackLine,interval,dat,lineSegment=[];
    
    point=animatePoints[nextPoint];
    boatMarker.setLatLng(point);
    dat=new Date();
    dat.setTime(animateTimes[nextPoint]);
    positionTime.innerHTML=dat.toUTCString();
    if (nextPoint>0){
        lineSegment.push(animatePoints[nextPoint-1]);
        lineSegment.push(animatePoints[nextPoint]);
        trackLine = new GPolyline(lineSegment,lineColor,lineWeight,opacity);
        map.addOverlay(trackLine);
    }
    nextPoint++;
    if (nextPoint<animatePoints.length){
        interval=(animateTimes[nextPoint]-animateTimes[nextPoint-1])/100000;
        animateTimer=setTimeout(drawNextPoint,interval);
    }else{
        loadFromXML=true;
        map.panTo(point);
        loadPositions();
    }
}

