//<![CDATA[
    
// Google maps browser support
// http://local.google.com/support/bin/answer.py?answer=16532&topic=1499

// (c) Mikael Högqvist, ZIB 2006-2007

var timer = null;
var host = window.location.hostname + ':' + window.location.port;

var site_timer = null;
var site_markers = new Array();
var map = null;
var map_service = null;
var queryModel = new Model();

function htmlForm(hostname, lat, lng) {
    form_str = '<form action="/update" method="POST">';
    form_str += 'Latitude, Longitude:<br/>';
    form_str += '<input type="text" name="lat" size="8" maxlength="8" value="' + lat + '" class="textinput"/>'; 
    form_str += '<input type="text" name="lng" size="8" maxlength="8" value="' + lng + '"class="textinput"/><br/>';
    form_str += '<input type="hidden" name="site" value="' + hostname + '"/>';
    form_str += '<input type="submit" class="submitinput" value="update">';

    return form_str;	
}
	
function Queue(queue_type, queue_name, total_cpus, free_cpus, waiting_jobs, running_jobs, total_jobs) {
    this.type = queue_type;
    this.name = queue_name;
    this.free_cpus = free_cpus;
    this.total_cpus = total_cpus;
    this.waiting_jobs = waiting_jobs;
    this.running_jobs = running_jobs;
    this.total_jobs = total_jobs;
}
	
function showDetailedJobInfo(jobid) {
    var siteNode = document.getElementById('detailedjobinfo');      

    if(siteNode.childNodes.length > 1) {
        siteNode.innerHTML = ' ';
    }

    jobInfoCb = function(json) {
        div = document.createElement('div');
        div.setAttribute('id', 'maptab');

        table = document.createElement('table');
        div.appendChild(table);
        caption = document.createElement('caption');
        caption.appendChild(document.createTextNode(jobid.replace('http://www.gac-grid.org/jobs/','')));
        table.appendChild(caption);
        table.appendChild(detailedJobInfo(json));
        siteNode.appendChild(div);
    }

    queryModel.detailedJobInfo(jobid, jobInfoCb);	  	
}
	
function detailedJobInfo(jsonJob) {
    var jobObj = eval('(' + jsonJob + ')');
	    
    results = jobObj.results.bindings;
    vars = jobObj.head.vars;
	    
    if(results.length == 0) {
        p = document.createElement('p');
        p.appendChild(document.createTextNode('The job was not found.'));
        return p;
    }
	    
    // this should only return one binding
    for(i=0; i<vars.length; i++) {
        tr = document.createElement("tr");
        table.appendChild(tr);

        td = document.createElement('td');
        b = document.createElement('b');
        b.appendChild(document.createTextNode(vars[i].replace('_', ' ') + ': '));
        td.appendChild(b);
        tr.appendChild(td);
            
            
        td = document.createElement('td');
        try {
            var value = results[0][vars[i]].value;
        } catch (e) {
            td.appendChild(document.createTextNode(''));
            value = ''
                } finally {
            td.appendChild(document.createTextNode(value));
        }
        tr.appendChild(td);
    }
        
    return document.createElement('p');
}
	
function jobInfo(jsonJobs) {
    //	    var jsonJobs = map_service.jobs(hostname);
    var jobObj = eval('(' + jsonJobs + ')');
	    
    results = jobObj.results.bindings;

    div = document.createElement('div');
    div.setAttribute('id', 'maptab');

    table = document.createElement('table');
    div.appendChild(table);
    caption = document.createElement('caption');
    caption.appendChild(document.createTextNode('Active jobs'));
    table.appendChild(caption);
        
    if(results.length == 0) {
        p = document.createElement('p');
        p.appendChild(document.createTextNode('No active jobs found.'));
        div.appendChild(p);
        return div;
    }
        
    tr = document.createElement('tr');
    table.appendChild(tr);
        
    for(var i=0; i<jobObj.head.vars.length; i++) {
        th = document.createElement("th");
        tr.appendChild(th);
        th.appendChild(document.createTextNode(jobObj.head.vars[i]));            
    }
        
    for(var i=0; i<results.length; i++) {
        var tr_class = "even";
            
        if(i % 2 == 1)
            tr_class = "odd";
                  
        if(results[i].name.value != undefined && results[i].jobid.value != undefined && results[i].state.value != undefined) {
            tr = document.createElement('tr');
            tr.setAttribute('class', tr_class);
            table.appendChild(tr);

            td = document.createElement('td');
            td.appendChild(document.createTextNode(results[i].name.value));
            tr.appendChild(td);

            td = document.createElement('td');
            td.appendChild(document.createTextNode(results[i].state.value));
            tr.appendChild(td);
                
            td = document.createElement('td');
            link = document.createElement('a');
            link.setAttribute('href', '#');
            link.setAttribute('onClick', 'showDetailedJobInfo(\'' + results[i].jobid.value + '\'); return false');
                
            link.appendChild(document.createTextNode(results[i].jobid.value.replace('http://www.gac-grid.org/jobs/','').substring(0,8) + "..."));
                
            td.appendChild(link);
            tr.appendChild(td);                
        }

    }
        
    return div;
}
	
function hostInfo(jsonClusters) {
    //          jsonClusters = map_service.clusters(hostname);
    clusterObj = eval('(' + jsonClusters + ')');


    results = clusterObj.results.bindings;
    //		  var ce_str = '<div class="maptab">';

                   
    //		  var ce_str = '<div class="maptab" style="width: ' + width + 'px;"><b>' + host.getName() + '</b><br/><br/>';
          
    var ce_str = '<div id="maptab">';
    var queues = {};

    div = document.createElement('div');
    div.setAttribute('id', 'maptab');

    //          siteNode.appendChild(div);
    for(var i=0;i<results.length;i++) {
        var cluster_addr = results[i].queue.value.split('/');
			
        queue_name = cluster_addr[cluster_addr.length-1];
        queue_name = queue_name.replace(/\+/g, " ");
        queue_type = cluster_addr[cluster_addr.length-2];
            
        if(results[i].freecpus != undefined && results[i].totalcpus != undefined) {

            if(queues[queue_type] == undefined) {
                queues[queue_type] = new Array();
            }

            queues[queue_type].push(new Queue(queue_type, queue_name, results[i].totalcpus.value, results[i].freecpus.value, results[i].waitingjobs.value, results[i].runningjobs.value, results[i].totaljobs.value));
        }
    }

    for(queue_type in queues) {
        var tr_class = "even";          
        //            ce_str += '<table>';
        //            ce_str += '<caption>' + queue_type + '</caption>';

        table = document.createElement('table');
        div.appendChild(table);
        caption = document.createElement('caption');
        caption.appendChild(document.createTextNode(queue_type));
        table.appendChild(caption);
            
            
        for(queue_index in queues[queue_type]) {
            queue = queues[queue_type][queue_index];
              
            if(queue_index % 2 == 1)
                tr_class = "odd";
                  
            if(queue.free_cpus != undefined && queue.total_cpus != undefined) {
                tr = document.createElement('tr');
                tr.setAttribute('class', tr_class);
                table.appendChild(tr);
                td = document.createElement('td');
                b = document.createElement('b');
                b.appendChild(document.createTextNode(queue.name));
                td.appendChild(b);
                tr.appendChild(td);
                
                td = document.createElement('td');
                
                cpu_status = queue.free_cpus + '/' + queue.total_cpus + ' CPUs\n';
                td.appendChild(document.createTextNode(cpu_status));
                td.appendChild(document.createElement('br'));
                                
                if(queue.waiting_jobs != undefined && queue.running_jobs != undefined && queue.total_jobs != undefined)
                    job_status = queue.waiting_jobs + ' waiting, ' + queue.running_jobs + ' running of ' + queue.total_jobs + ' total jobs.';
                    td.appendChild(document.createTextNode(job_status));
                    

                tr.appendChild(td);
                              
                //ce_str += '<tr class="' + tr_class + '"><td>';
                //ce_str += '<b>' + queue.name + '</b>: </td><td>';
                //ce_str += queue.free_cpus + '/' + queue.total_cpus + ' CPUs';
                //ce_str += '</td></tr>';
                tr_class = "even";
            }
        }
        ce_str += '</table>';
    }

    /*            ce_str += '<b>' + cluster_name + '</b> [' + queue_name + ']: '
                  ce_str += results[i].freecpus.value + '/' + results[i].totalcpus.value + ' CPUs'
                  ce_str += '<br/>'
    */

    ce_str += '</div>';
	
    //return ce_str;
    return div
	}
	
function showJobInfo(hostname) {
    var siteNode = document.getElementById('jobinfo');

    jobInfoCb = function(json) {
        siteNode.appendChild(jobInfo(json));
    }

    queryModel.jobs(hostname, jobInfoCb);	  
}
	
function showHostInfo(hostname, lat, lng) {
    var siteNode = document.getElementById('hostinfo');      
	        
    hostInfoCb = function(json) {
        //var siteNode = document.getElementById('siteinfo');	

        b = document.createElement('b');
        br = document.createElement('br');
        host = document.createTextNode(hostname.replace("http://", "")+" ("+
                                       lat.toFixed(2)+", "+lng.toFixed(2)+")");
        b.appendChild(host);
        siteNode.appendChild(b);
        siteNode.appendChild(br);
          
        //          html_str += '<b>' + hostname.replace("http://", "") + '</b><br/>';
        //    	  html_str += hostInfo(json);
        siteNode.appendChild(hostInfo(json));
        //    	  html_str += '<br/>';
        //    	  html_str += jobInfo(hostname);
        //    	  html_str += '<br/>';
        //    	  html_str += htmlForm(hostname, lat, lng);
        //    	  html_str += '</div>';
        //    	  siteNode.innerHTML = html_str;
    };
	  
    queryModel.clusters(hostname, hostInfoCb);

	  
    //return html_str;
}
	
function showInfo(hostname, lat, lng) {
    var siteNode = document.getElementById('siteinfo');      
	  
    for(var i=0; i<siteNode.childNodes.length; i++) {
        siteNode.childNodes[i].innerHTML = ' ';
    }
	          	
    showHostInfo(hostname, lat, lng);
    showJobInfo(hostname);
}
	
function SiteMarker(map_marker, hosts, lat, lng) {
    //alert(site_obj.site);
    this.marker = map_marker;
    this.hosts = hosts;
    this.lat = lat;
    this.lng = lng;
    this.infoTimer = null;

    // _this points to the local object instance (works inside callbacks)
    var _this = this;
    // acts as callback when the local marker is clicked
    // issues a SPARQL query to get the clusters belonging to the site
    // each cluster have a separate tab containing a table of the
    // available queues.
    this.callback = function() {
        var errorNode = document.getElementById('errormsg');
        var infoTabs = [];
        var width = 90*_this.hosts.length;

        if(width <= 180)
            width = 180;		
        if(_this.hosts.length == 1) {
            host = _this.hosts[0];
            //		    html_str += '<div class="maptab" style="width: ' + width + 'px;"><b>' + host.getName() + '</b><br/><br/>';
            //showHostInfo(host.getName(), host.lat, host.lng);
            //showJobInfo(host.getName());
            
            showInfo(host.getName(), host.lat, host.lng);
            /*
              tab_name = host.getName();
              tab_name = tab_name.replace("http://", "");
              tab_name = tab_name.substring(0,8) + "..."; */
        } 
        else {
            var html_str = '<div id="maptab">';
            var tab_name = 'Site';
		
            for(var host_index = 0; host_index < _this.hosts.length; host_index++) {
                host = _this.hosts[host_index];
                //alert(host_index + " " + _this.hosts.length);
                //		  alert(host_index + " - " + host.getName() + ": " + host);
    	  
                //alert(host.getName());

                /*    	  site_tab = host.getName();
    	
                site_tab = site_tab.replace("http://", "");
                site_tab = site_tab.substring(0,8) + "...";
        
                start_str = '<div class="maptab" style="width: ' + width + 'px;">';
                start_str += '<b>' + host.getName() + '</b><br/><br/>';


                end_str = '</div>';

                siteNode.innerHTML = ce_str + "<br/>" + form_str;
                */
                //"' + host.getName() + '",' + host.lat + ',' + host.lng + '
                html_str += '<a href="#" onClick="showInfo(\'' + host.getName() + '\',' + host.lat + ',' + host.lng + '); return false">' + host.getName().replace("http://", "") + '</a><br/>';
                //infoTabs.push(new GInfoWindowTab("Location", form_str))
            }	
            html_str += '</div>';
            //            alert(html_str);
            infoTabs.push(new GInfoWindowTab(tab_name, html_str));        
            this.openInfoWindowTabsHtml(infoTabs);

        }
		
        //alert(_this.site.site);
    };
}
	
// Host class, has a host address and coordinates (lat, lng)
function Host(hostname, lat, lng) {
    this.hostname = hostname;
    this.lat = lat;
    this.lng = lng;
}
	
Host.prototype.getName = function() {
    return this.hostname;
};
	
Host.prototype.toString = function() {
    return this.lat.toString() + ":" + this.lng.toString();
};
		
function updateSites(jsonSites) {
    var errorNode = document.getElementById('errormsg');
    var siteNode = document.getElementById('siteinfo');
    var sites = null;

    // json output cannot deal properly with optional variables...
    //      var data = '({ "head" : { "vars" : [ "site" ] }, "results" : { "ordered" : false, "distinct" : false, "bindings" : [{ "site" : {"type": "uri", "value" : "http://siemens.babylon.cs.uni-potsdam.de"}},{ "site" : {"type": "uri", "value" : "http://photon.aip.de"}}] } })';

    //      siteObj = eval(data);      
    //      jsonSites = map_service.sites();

    if(!jsonSites)
        return
            siteObj = eval('(' + jsonSites + ')');

    //alert(jsonSites);
    //alert(siteObj.results.bindings.length);
	  
    //	  siteNode.firstChild.nodeValue = jsonSites;
    //map.removeOverlays();
    // this is not good, should only remove sites which was not part of the query results
    // and add unknown sites.
    if(site_markers.length > 0) {
        site_markers.splice(0, site_markers.length);
    }
	  
    results = siteObj.results.bindings;
    var coords = new Array();
    var hosts = new Array();
    var sites = {};

    // format on json return: [[sitename, lat, long], ...]
    for(var i=0;i<results.length;i++) {
        if(results[i].site != 'undefined' || results[i].site.value != "None") {
            // alert(results[i].latitude.value);
                // alert(siteObj[i][2]);

            var center = map.getCenter();
            var radius = 5.5;
            var angle = i*5.0;
            var lat = center.lat() + radius*Math.cos(angle);
            var lng = center.lng() + radius*Math.sin(angle);
            var lat_lng_str = "";
            var tmp_host = null;
          
            if(results[i].latitude != undefined && results[i].longitude != undefined) {
                var small_radius = 0.05;
                var lat_tmp = lat = parseFloat(results[i].latitude.value);
                var lng_tmp = lng = parseFloat(results[i].longitude.value);
            
                //alert(lat.toString() + ":" + lng.toString() + " - " + lat_lng_str);
                //            coords.push(lat_lng_str);
            
    
            }
          
            tmp_host = new Host(results[i].site.value, lat, lng);          
          
            if(tmp_host.toString() in sites)
                sites[tmp_host.toString()].push(tmp_host);
            else {
                sites[tmp_host.toString()] = new Array();
                sites[tmp_host.toString()].push(tmp_host);
            }
            
            //store this host at the appropriate site

        }
        else {
            // dont do anything...
            //	  	  var center = the_map.getCenter();
            //	  	  var marker = new GMarker(new GLatLng(center.lat()-(i*0.50)+1.25, center.lng()+5.00));
            continue;
        }
    }

    // A site contains of a list of hosts with the same location
    // A host has a list of queues (Fork, PBS, LoadLeveler, ...) 
    for(var site in sites) {
        var location = site.split(":");
        var lat = location[0];
        var lng = location[1];
        var marker = new GMarker(new GLatLng(lat, lng));
        //alert(sites[site][0].getName() + ": " + sites[site][0].toString());
        var pos = site_markers.push(new SiteMarker(marker, sites[site], lat, lng));
        //alert(results[i].site.value);
        //        alert(site);
        if(pos > 0) {
            //alert(site_markers[pos-1].site.site);
            var siteMarkerObj = site_markers[pos-1];
            GEvent.addListener(siteMarkerObj.marker, "click", siteMarkerObj.callback);
            map.addOverlay(siteMarkerObj.marker);
        }
    }
}

function loadGMap() {
    map = new GMap2(document.getElementById("map"));
    var counter = 0;

    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.addControl(new GOverviewMapControl());

    map.setCenter(new GLatLng(50.40, 10.07), 5);

    // start site upload timer
    queryModel.sites(updateSites);
    //    queryModel.telescopes(updateTelescopes);

    //  	  updateSites(map);  	  
    //site_timer = setInterval(updateSites, 600000);
    // create a marker for each site and place it at the position
    // if no position is found then the marker should be placed at
    // a standard position outside germany's border.
    //      var marker = new GMarker(map.getCenter());
    //      GEvent.addListener(marker, "click", clickMarker);
      
    //      map.addOverlay(marker);
    //        marker.openInfoWindowTabsHtml(infoTabs);
		
}
		
function load() {
    if (GBrowserIsCompatible()) {
      	loadGMap();
    }
}
//]]
