//////////////////////////////////////////////////////////////////////////////////
//
//  Global Variables
//

var sites = new Array();
var markers = new Array();

var map;
var site_list_html = "";
var tooltip;

var visible_graphs_id="graphs-all";
var visible_site_id="site-home";
var visible_definition="definition-default";

var highlighted_marker;
var highlightedSiteName;
var definitionTop = 340;

/////////////////////////////////////////////////////////////////////////////////
//
//  Function 'load'
//
//  Loads the Google Map at the requested zoom level.
//
//  Args:
//      zoom: google maps zoom level (integer)
//

function load( zoom ) {

    if (GBrowserIsCompatible()) {

        // Create the map, add controls, and center it

        map = new GMap2(document.getElementById("map"));
        map.addControl(new GSmallMapControl());
        map.addControl(new GMapTypeControl());
        if( document.body.id == 'sitemap' ) {  // different center point for large map
            var point = new GLatLng(26.701196, -81.624000);
            map.addControl( new GOverviewMapControl( new GSize( 300, 200 ) ) );
        } else {
            var point = new GLatLng(26.581196, -82.024000);
        }
        map.setCenter( point, zoom, G_NORMAL_MAP);

        //  Enable scroll wheel zooming and disable default page scroll
        //  when scroll zooming map.

        map.enableScrollWheelZoom();
        var mapDiv = document.getElementById("map");
        GEvent.addDomListener(mapDiv, "DOMMouseScroll", wheelevent);
        mapDiv.onmousewheel = wheelevent; 

        //  Create the SCCF Lab icon and marker

        var point = new GLatLng( 26.44208, -82.08287 );
        var labicon = new GIcon( G_DEFAULT_ICON, "/i/marker.png" );
        labicon.iconSize = new GSize(32, 32);
        var marker = new GMarker(point, { clickable:false, title:"SCCF Marine Lab", icon:labicon } );
        var html = '<div style="width:180px;background:white">SCCF Marine Laboratory</div>'
        map.addOverlay(marker);

        //  Create the icon used by all markers

        var icon = new GIcon();
        icon.image = "/i/sccf-pin-dark-30x46.png";
        icon.shadow = "/i/sccf-shadow-50x42.png";
        icon.iconSize = new GSize(30, 46);
        icon.shadowSize = new GSize(50, 42);
        icon.iconAnchor = new GPoint(15, 46);
        icon.infoWindowAnchor = new GPoint(15,23);

        //  Create a document element for displaying marker tooltip

        tooltip = document.createElement("div");
        map.getPane(G_MAP_FLOAT_PANE).appendChild(tooltip);
        tooltip.style.visibility="hidden";

        //  Show the 'recent' graph element that plots all sites

        if( document.body.id == 'recent' ) {
            showGraph( "all" );
        }

        //  Initialize the site selection list

        site_list_html += '<h1 style="margin:0; padding:0; padding-bottom: 4px;">Sites</h1>\n';
        site_list_html += '<div style="float:left;">\n';
        site_list_html += '<table>\n';

        // Download XML sites data from server root and add a map marker for each

        GDownloadUrl( "/sites.xml", function( data, responseCode ) {

            var xmlDoc = GXml.parse( data );
            var sitexml = xmlDoc.documentElement.getElementsByTagName("site");

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

                // obtain the attribues of each marker

                var site = new Object;
                site.id = sitexml[i].getAttribute("id");
                site.name = sitexml[i].getAttribute("name");
                site.color = sitexml[i].getAttribute("color");
                site.latitude = parseFloat(sitexml[i].getAttribute("latitude"));
                site.longitude= parseFloat(sitexml[i].getAttribute("longitude"));
                sites[i] = site;

                //  Add a marker for the site

                var marker = addMarker( zoom, map, site.id, site.name, icon, site.latitude, site.longitude );
                markers[i] = marker;

                //  Add and entry to the site selecetion list

                site_list_html += '<tr style="cursor:pointer;" onmouseover="mouseOver(' + sites[i].id + ');"';
                site_list_html += 'onmouseout="mouseOut(' +  sites[i].id + ');">'
                site_list_html += '<td style="width:20px;"><div style="font-size:0px;height:2px;background:' + site.color + ';" /></td>';
                site_list_html += '<td id=sitename-' + i + '>' + site.name + '</td></tr>\n';

                //  Start a new column half way through the list
                var len = Math.round( sitexml.length / 2 ) - 1;

                if( i == len ) {
                    site_list_html += '\n</table> </div>\n';
                    site_list_html += '<div style="margin-left:30px;float:left;">\n';
                    site_list_html += '<table>\n';
                }

            }

            // If this is the home page, add a line for rollover to 'home' main text pane

            if( document.body.id == 'home' ) {
                site_list_html += '<tr style="cursor:pointer;" onmouseover="mouseOverHome();">'; 
                site_list_html += '<td style="width:20px;"><div style="font-size:0px;height:2px;background:white" /></td>';
                site_list_html += '<td id=homeLink>Home</td></tr>\n';
            }

            // If this is the graphs page, add a line for 'all sites'

            if( document.body.id == 'recent' ) {
                site_list_html += '<tr style="cursor:pointer;" onmouseover="mouseOverAllSites();">'; 
                site_list_html += '<td style="width:20px;"><div style="font-size:0px;height:2px;background:white" /></td>';
                site_list_html += '<td id=allSitesLink>All Sites</td></tr>\n';
            }

            //  Close the site selection list and write it to the document

            site_list_html += '\n</table>\n';
            site_list_html += '</div>\n';

            site_list_html += '<br clear="all">\n';

            site_list_html += '<div style="font-size:11px;padding:0; margin:0; padding-top: 10px;">\n';

            if( document.body.id == 'recent' ) {
                site_list_html += 'Roll over any RECON map icon or site name to see ';
                site_list_html += 'graphs of recent sensor measurements from that location.';
            }
            if( document.body.id == 'home' ) {
                site_list_html += 'Roll over any RECON map icon or site name for ';
                site_list_html += 'information and latest sensor measurements for that location.';
            }

            site_list_html += '</div>\n';


            if( document.body.id != 'sitemap' ) {
                document.getElementById("site_list").innerHTML = site_list_html;
            }

            if( document.body.id == 'home' ) {
                setFooterTop();
               ( document.getElementById( 'homeLink' ) ).style.fontWeight = 'bold';
            }

            if( document.body.id == 'recent' ) {
               ( document.getElementById( 'allSitesLink' ) ).style.fontWeight = 'bold';
            }

        } ); 

    }
}

//----- Stop page scrolling if wheel over map ----
function wheelevent(e) {
    if (!e) e = window.event;
    if (e.preventDefault) e.preventDefault();
    e.returnValue = false;
} 

////////////////////////////////////////////////////////////////////////////////
//
//  Function: getStyle
//
//  Return the style component of the identified document element
//

function getStyle( id ){
    if ( document.getElementById ) {
        return document.getElementById( id ).style
    } else if (document.all) {
        return document.all.pane.style
    }
}


////////////////////////////////////////////////////////////////////////////////
//
//  Function: addMarker
//
//  Add a marker to the map at the given position. Add listeners for mouseover
//  events.
//

function addMarker ( zoom, map, id, title, icon, lat, lng ) {

    var graphs_id = "graphs-" + id;
    var point = new GLatLng(lat, lng);
    var marker = new GMarker(point, {icon: icon});
    map.addOverlay( marker );

    marker.tooltip = '<div class="tooltip">'+title+'</div>';
 
    var url = "http://recon.sccf.org/";

    GEvent.addListener(marker, "mouseover", function() {
        mouseOverMarker( id ); 
    });

    GEvent.addListener(marker, "mouseout", function() {
        mouseOut( id );
    });

    return marker;
    
}

////////////////////////////////////////////////////////////////////////////////
//
//  Function: showToolTip
//
//  Show a tooltip on the given marker stating the site name
//

function showTooltip(marker) {

    tooltip.innerHTML = marker.tooltip;
    
    var pt = map.getCurrentMapType().getProjection().fromLatLngToPixel(map.fromDivPixelToLatLng(
        new GPoint(0,0),true),map.getZoom());
    var offset = map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),map.getZoom());
    var anchor = marker.getIcon().iconAnchor;
    var wd = marker.getIcon().iconSize.width;
    var ht = tooltip.clientHeight;
    var pos = new GControlPosition(
        G_ANCHOR_TOP_LEFT, new GSize(offset.x - pt.x - anchor.x + wd, offset.y - pt.y -anchor.y -ht)); 

    pos.apply(tooltip);
    tooltip.style.visibility="visible";
}

////////////////////////////////////////////////////////////////////////////////
//
//  Function: hideToolTip
//
//  Hide the marker tool tip
//

function hideTooltip() {
    tooltip.style.visibility="hidden";
}

/////////////////////////////////////////////////////////////////////////////////
//
//  Function: mouseOverMarker
//
//  Called when mouse is over a map marker. Doesn't pan map before executing
//  actions.
//

function mouseOverMarker( id ) {
    ix = getIndexFromId( id );
    mouseOverAction( id, ix );
}

/////////////////////////////////////////////////////////////////////////////////
//
//  Function: mouseOverHome
//
//  Called when mouse is over a the home link. Shows the 'home' text pane.
//

function mouseOverHome() {
    showSite( 'home' );
    ( document.getElementById( 'homeLink' ) ).style.fontWeight = 'bold';
    if ( highlightedSiteName ) {
        highlightedSiteName.style.fontWeight = '';
    }
}

/////////////////////////////////////////////////////////////////////////////////
//
//  Function: mouseOverAllSites
//
//  Called when mouse is over a the 'All Sites' link. Shows the combined
//  graphs for all sites.
//

function mouseOverAllSites() {
    showGraph( 'all' );
    hideTooltip();
    ( document.getElementById( 'allSitesLink' ) ).style.fontWeight = 'bold';
    if ( highlightedSiteName ) {
        highlightedSiteName.style.fontWeight = '';
    }

}

/////////////////////////////////////////////////////////////////////////////////
//
//  Function: mouseOver
//
//  Called when mouse is over a site name in the site list. Pans map to site
//  marker and then executes common actions.
//

function mouseOver( id ) {

    ix = getIndexFromId( id );

    if( id != 'all' ) {
        panMap( ix );
    }

    mouseOverAction( id, ix );
}

/////////////////////////////////////////////////////////////////////////////////
//
//  Function: getIndexFromId
//
//  Returns the site data array index for the given site id.
//

function getIndexFromId( id ) {
    for( ix = 0; ix < sites.length; ix++ ) {
        if( sites[ix].id == id ) {
            break;
        }
    }
    return ix;
}

/////////////////////////////////////////////////////////////////////////////////
//
//  Function: mouseOverAction
//
//  Actions for marker and site list mouseovers. Show the marker tool tip, then
//  show the graphs if page is 'recent', or show the site if page is 'home'.
//

function mouseOverAction( id, ix ) {

    showTooltip( markers[ix] );
    var siteName = document.getElementById( 'sitename-' + ix );
    siteName.style.fontWeight = 'bold';
    if ( highlightedSiteName && highlightedSiteName != siteName ) {
        highlightedSiteName.style.fontWeight = ''; 
    }
    
    highlightedSiteName = siteName;

    if ( highlighted_marker ) {
        highlighted_marker.setImage("http://recon.sccf.org/i/sccf-pin-dark-30x46.png");
    }
    markers[ix].setImage("http://recon.sccf.org/i/sccf-pin-30x46.png");
    highlighted_marker = markers[ix];

    switch( document.body.id ) {

    case 'recent':
        showGraph( id );
        ( document.getElementById( 'allSitesLink' ) ).style.fontWeight = '';
        break;

    case 'home': 
        showSite( id );
        ( document.getElementById( 'homeLink' ) ).style.fontWeight = '';
        break;
        
    default: 
        break;

    }
        
}

function mouseOut( id ) {

    switch( document.body.id ) {

    case 'recent':
    case 'home':
        break;

    default:
        hideTooltip();
        if ( highlighted_marker ) {
            highlighted_marker.setImage("http://recon.sccf.org/i/sccf-pin-dark-30x46.png");
        }
        break;
    }

}

/////////////////////////////////////////////////////////////////////////////////
//
//  Function: showDefinition
//
//  Show the short definition of the given measurement identifier.
//

function showDefinition( e, measurement ) {

     e = e || window.event;
     var target = e.srcElement || e.target;
     if ( !isMouseLeaveOrEnter( e, target ) ) return;
 
    //  Hide the site list if on the recent graphs page

    if( document.body.id == 'recent' ) {
        getStyle( 'site_list' ).visibility = 'hidden';
        getStyle( 'site_list' ).display = 'none';
    }

    id = 'definition-' + measurement;
    var def = document.getElementById( id );
    def.style.top = definitionTop + 'px';

    getStyle( visible_definition ).visibilty = 'hidden';
    getStyle( visible_definition ).display = 'none';

    getStyle( id ).visibility = 'visible';
    getStyle( id ).display = 'inline';

    visible_definition = id;

    if( document.body.id == 'home' ) {
        setFooterTop();
    }

}

/////////////////////////////////////////////////////////////////////////////////
//
//  Function: hideDefinition
//
//  Hide the currently visible short definition and show the default pane
//

function hideDefinition( e ) {

     e = e || window.event;
     var target = e.srcElement || e.target;
     if ( !isMouseLeaveOrEnter( e, target ) ) return;

    getStyle( visible_definition ).visibilty = 'hidden';
    getStyle( visible_definition ).display = 'none';
    
    if( document.body.id == 'recent' ) {
        id = 'site_list';
    } else {
        id = 'definition-default';
    }

    getStyle( id ).visibility = 'visible';
    getStyle( id ).display = 'inline';
    visible_definition = id;

    if( document.body.id == 'home' ) {
        setFooterTop();
    }

}

/////////////////////////////////////////////////////////////////////////////////
//
//  Function: showGraph
//
//  Hide the currently visible 'latest' graphs pane, and show the one for the
//  given site.
//

function showGraph( id ) {

    // Hide the currently shown graph and show the requested one

    var graphs_id = "graphs-" + id;
    getStyle( visible_graphs_id ).visibility='hidden';
    getStyle( graphs_id ).visibility='visible';
    visible_graphs_id = graphs_id;
}

/////////////////////////////////////////////////////////////////////////////////
//
//  Function: showSite
//
//  Show the site pane for the given site and hide the previously visible one.
//  Also ensure the default definitions pane is shown.
//

function showSite( id ) {

    var site_id = 'site-' + id;
    getStyle( visible_site_id ).visibility='hidden';
    getStyle( visible_site_id ).display='none';
    getStyle( site_id ).visibility='visible';
    getStyle( site_id ).display='inline';
    visible_site_id = site_id;

    if ( id != 'home' ) {

        getStyle( 'definition-default' ).visibility='visible';
        getStyle( 'definition-default' ).display='inline';

        var d = document.getElementById('site-data-' + id);
        definitionTop = d.offsetHeight + 10;
        var def = document.getElementById( visible_definition );
        //setStyleByClass( defPane, 'definition', 'top', definitionTop + 'px');
        def.style.top = definitionTop + 'px';

    } else {

        getStyle( 'definition-default' ).visibility='hidden';
        getStyle( 'definition-default' ).display='none';
        hideTooltip();
    }

    setFooterTop( 'definition-default');

}

/////////////////////////////////////////////////////////////////////////////////
//
//  Function: setFooterTop
//
//  Additional javascipt required to locate absolutely positioned definitions 
//  because height of data table above will differ depending on which node is
//  displayed. Also must adjust the 'contentcenter' div for similar reasons so
//  that the footer will lay out correctly if any of the absolutely positioned
//  components above are taller than the 'extras' div on the left.
//

function setFooterTop() {

    var id = visible_site_id.substr(5);

    // get the combined height of the displayed data table and definition

    var data = document.getElementById('site-data-' + id);
    var defn = document.getElementById( visible_definition );

    var h1 = 0;
    if( data ) {
        h1 = data.offsetHeight + 10 + defn.offsetHeight;
    }

    // get the height of the displayed site description

    var desc = document.getElementById('site-' + id);
    var h2 = desc.offsetHeight;

    // set the 'contnentcenter' div to the tallest of either the site
    // description or the data table plus definition, so that footer
    // is below tallest component

    var tallest = Math.max( h1, h2 );
    setStyleById( 'contentcenter', 'height', tallest + 'px' );
}

////////////////////////////////////////////////////////////////////////////////
//
//  Function: panMap
//
//  Pan the map to the requested site 
//

function panMap( ix ) {

    map.panTo( new GLatLng(  sites[ix].latitude, sites[ix].longitude ) );
}


////////////////////////////////////////////////////////////////////////////////
//
//  Function: document.getElementsByClassName
//
//  XPath implementation of getElementsByClassName
//

document.getElementsByClassName = function(className, parentElement) {
if (Prototype.BrowserFeatures.XPath) {
    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
    return document._getElementsByXPath(q, parentElement);
  } else {
    var children = ($(parentElement) || document.body).getElementsByTagName('*');
    var elements = [], child;
    for (var i = 0, length = children.length; i < length; i++) {
      child = children[i];
      if (Element.hasClassName(child, className))
        elements.push(Element.extend(child));
    }
alert (i);
    return elements;
  }
};

function setStyleById(i, p, v) {
        var n = document.getElementById(i);
        n.style[p] = v;
}


function setStyleByClass(t,c,p,v){

    var children = ($(t) || document.body).getElementsByTagName('*');
    var elements = [], child;
    for (var i = 0, length = children.length; i < length; i++) {
      child = children[i];
      if (Element.hasClassName(child, c))
          eval('child.style.' + p + " = '" +v + "'");
    }

/*
    var elements = document.getElementsByClassName( c, t );

    for(var i = 0; i < elements.length; i++){
        var node = elements[i];
        for(var j = 0; j < node.attributes.length; j++) {
            eval('node.style.' + p + " = '" +v + "'");
        }
    }
*/
}

function isMouseLeaveOrEnter(e, handler) { 
    if (e.type != 'mouseout' && e.type != 'mouseover') return false; 
    var reltg = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement; 
    while (reltg && reltg != handler) {
        reltg = reltg.parentNode; return (reltg != handler); 
    }
}
