    <div id="HPCDashboard">
    <h1>CDN Operations View</h1>
    <span id="hpcSummary">
        <span class="summary-attr"><b>Allocated Instances:</b> <span id="active-instances-value"> </span> </span>
        <span class="summary-attr"><b>CDN Bandwidth:</b> <span id="overall-throughput-value"> </span>  </span>
        <span class="summary-attr-util"><b>CDN Load:</b> <span id="cpu-utilization-value"> </span>  </span>
    </span>
    <div id="map-us" ></div>
    <div style="line-height: 30%"><br></div><table border=0><tr>
    <td>Least Loaded&nbsp;&nbsp;</td>
    <td bgcolor="#0000FF" width=40>&nbsp;</td>
    <td bgcolor="#00FFFF" width=40>&nbsp;</td>
    <td bgcolor="#00FF00" width=40>&nbsp;</td>
    <td bgcolor="#FFFF00" width=40>&nbsp;</td>
    <td bgcolor="#FF0000" width=40>&nbsp;</td>
    <td>&nbsp;&nbsp;Most Loaded</td>
    </tr></table>
    </div>

    <div id="confirmNodeAdded" title="Added Node to Site"><p>Added Node to Site</p></div>
    <div id="confirmNodeRemoved" title="Removed Node from Site"><p>Added Node to Site</p></div>

<script>
$( "#confirmNodeAdded" ).dialog({ autoOpen: false,
                    modal: true,
                    buttons: {
                        Ok: function() {
                           $( this ).dialog( "close" );
                        }
                    }});
$( "#confirmNodeRemoved" ).dialog({ autoOpen: false });

L.Map = L.Map.extend({
    openPopup: function(popup) {
        this._popup = popup;

        return this.addLayer(popup).fire('popupopen', {
            popup: this._popup
        });
    }
});


//Iterate through data and find the max/min coordinates to include all of our points to start
var map = L.map('map-us'); //.setView([0, 0], 1);
map.scrollWheelZoom.disable();

//
// Great tiles, but starting to occasionally see 403 errors on certain tiles causing grey out effect
//L.tileLayer('http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png', {
//
// Swapping out cloudmade tiles to openstreetmap - too many grey tiles showing
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 18,
    attribution: 'Test'
}).addTo(map);

var arrayOfLatLngs = [];
var mapData = {{ cdnData|safe }};
log.debug( mapData );

for ( var key in mapData ) {
    arrayOfLatLngs.push([mapData[key]['lat'],mapData[key]['long']]);
    log.debug( arrayOfLatLngs );

    mapData[key]['marker'] = L.marker([mapData[key]['lat'], mapData[key]['long']], {icon: getIcon(mapData[key]['numNodes'], mapData[key]['numHPCInstances'], 0, mapData[key]['hot']) });
    mapData[key]['marker'].addTo(map).bindPopup(setPopupVals(key, mapData[key]));

}
var bounds = new L.LatLngBounds(arrayOfLatLngs);
map.fitBounds(bounds);

var popup = L.popup();


function setPopupVals (site, siteData) {
    var retVal = '<span class="SiteDetail"><b>' + site + '</b></span>' +
                   '</br><a href="' + siteData['siteUrl'] + '">' + siteData['siteUrl'] + '</a>' +
                   '</br><b>HPC Instances: </b>' + siteData['numHPCInstances'] +
                   '</br><b>Total Nodes: </b>' + siteData['numNodes'] +
//                   '</br><b>Hot: </b>' + Math.round(siteData['hot']*100) +
                   '</br><b>Measured Load: </b>' + siteData['load'] + '%' +
                   '<span id="addInstances"></br><a href="#" id="addHPCInstance" data-site="' + site + '" data-availNodes="' + siteData['numNodes'] +'">Add HPC Instances</a> </span>' +
                   '<span id="remInstances"><a href="#" id="remHPCInstance" data-site="' + site + '">Remove HPC Instances</a> </span>';

   return retVal;
}

$('#map-us').on('click', '#remHPCInstance', function() {

    $.ajax({
        url : '/dashboardaddorreminstance/',
        dataType : 'json',
        data: {site: $(this).data('site'),
               actionToDo: "rem",
               csrfmiddlewaretoken: "{{ csrf_token }}",   // < here
               state:"inactive" },
        type : 'POST',
        success:function(){
            confirmDialog("Info","Removed an HPC Instance from Site ");
        },
        error:function (xhr, textStatus, thrownError){
            errorDialog("Error", textStatus + " " + xhr.responseText);
        }
    });
});

$('#map-us').on('click', '#addHPCInstance', function() {

    $.ajax({
        url : '/dashboardaddorreminstance/',
        dataType : 'json',
        data: {site: $(this).data('site'),
               actionToDo: "add",
               csrfmiddlewaretoken: "{{ csrf_token }}",   // < here
               state:"inactive" },
        type : 'POST',
        success: function(response)
        {
            confirmDialog("Info","Added an HPC Instance to Site ");
        },
        error:function (xhr, textStatus, thrownError){
            errorDialog("Error", textStatus + " " + xhr.responseText);
        }
    });
});

function getIcon(numNodes, numHPCInstances, currentBW, hot) {
    //var colorChoices = ["#007FFF", "#0000FF", "#7f00ff", "#FF00FF", "#FF007F", "#FF0000"];
    var colorChoices = ["#0000FF", "#00FFFF", "#00FF00", "#FFFF00", "#FF0000"];

    var ratio = hot * 100; //(numHPCInstances/numNodes) * 100;
    var numColors = colorChoices.length;
    var colorBands = 100/numColors;

    //Algorithm for color tone should consider the number of available nodes
    // on the site, and then how much the current dedicated nodes are impacted
    //var iconColor = 0;
    var iconColor = colorChoices.length-1;
    for (colorBand = 0; colorBand < numColors; colorBand ++) {
        if (ratio < colorBands * colorBand+1) {
            iconColor = colorBand
            break;
        }
    }

    if (numHPCInstances < 1) {
        iconColor = "#7F7F7F";
    } else {
        iconColor = colorChoices[iconColor];
    }

    var icon = L.MakiMarkers.icon({icon: "star-stroked", color: iconColor , size: "s"});
    return icon;
}

function updateMaps() {
    log.debug("Attempting to update Maps");
    $.ajax({
    url : '/hpcdashboard',
    dataType : 'json',
    type : 'GET',
    success: function(newData)
    {
        log.debug("Successfully got data back...");
        log.debug(newData);
        log.debug("Still have old data too");
        log.debug(mapData);
        updateMapData(newData);
    }
});
    setTimeout(updateMaps, 30000)

}

function updateMapData(newData) {
    for ( site in newData ) {
        var isNewSite = false;
        //check to see if the site is new or not
        if (site in mapData) {
            log.debug("Site " + site + " already mapped");
            //take ownership of marker
            newData[site]['marker'] = mapData[site]['marker'];
            delete mapData[site];
            newData[site]['marker'].setIcon(getIcon(newData[site]['numNodes'], newData[site]['numHPCInstances'],  0, newData[site]['hot']));
            // workaround, markers currently don't have a setPopup Content method -- so have to grab object directly
            newData[site]['marker']._popup.setContent(setPopupVals(site, newData[site]));
        }
        else {
            isNewSite = true;
            log.debug("New Site detected: " + site);
            newData[site]['marker'] = L.marker([newData[site]['lat'], newData[site]['long']],
                                              {icon: getIcon(newData[site]['numNodes'], newData[site]['numHPCInstances'],  0, newData[site]['hot']) });
            newData[site]['marker'].addTo(map).bindPopup(setPopupVals(site, newData[site])); //.openPopup();
            log.debug("Should have added the new site");

        }
    }

    // Anything still in data needs to be removed since it is no longer a valid site
    for (remSite in mapData) {
        log.warn("Site: " + remSite + " is no longer valid, removing from map");
        map.removeLayer(data[remSite]['marker']);
    }
    mapData = newData;
}

function onMapClick(e) {
    popup
    .setLatLng(e.latlng)
    .setContent("You clicked the map at " + e.latlng.toString())
    .openOn(map);
}

setTimeout(updateMaps, 5000)

// from stackexchange
function setInnerText (elementId, text) {
    var element;
    if (document.getElementById) {
        element = document.getElementById(elementId);
    } else if (document.all) {
        element = document.all[elementId];
    }
    if (element) {
        if (typeof element.textContent != 'undefined') {
            element.textContent = text;
        } else if (typeof element.innerText != 'undefined') {
            element.innerText = text;
        } else if (typeof element.removeChild != 'undefined') {
            while (element.hasChildNodes()) {
                element.removeChild(element.lastChild);
            }
            element.appendChild(document.createTextNode(text)) ;
        }
    }
}

function updateLabelData(summaryData) {
    setInnerText("active-instances-value", summaryData["total_instances"]);
    setInnerText("overall-throughput-value", (summaryData["total_bandwidth"]*8/1024/1024/1024).toFixed(2) + " Gbps");
    setInnerText("cpu-utilization-value", summaryData["average_cpu"] + "%");
}

function updateLabels() {
    log.debug("Attempting to update Labels");
    $.ajax({
    url : '/hpcsummary',
    dataType : 'json',
    type : 'GET',
    success: function(newData)
    {
        updateLabelData(newData);
    }
});
    setTimeout(updateLabels, 30000)

}

setTimeout(updateLabels, 5000)


</script>
