var source = "/monitor/";
// Location of data files
var range = 12;
// Hours to display (max 24)
var interval = 5;
// Monitoring interval (minutes)
var pxperrecord = 1;
// Pixels per record measured
var height = 100
// Height of each host graph
var titles_width = 60
// Width of titles section at LHS
var timer_height = 20
// Height of time div at top

var priorities = new Array (0,1,2,3,4,5,6)
var hosts = new Array ('JUNO','ARES','DIANA','LAYLA','PETER','FRED','PAN')
var locns = new Array ('AUS','USA','AUS','USA','USA','USA','USA')

// No more cgi variables after this point

var styles = new Array ('Server Load','Page Speed','MySQL','Disk space','Free memory','Swap memory')

data_div_width = (60 / interval) * pxperrecord + 1
// Width of each data div (add 1 for border)
var graphs_height = (priorities[priorities.length - 1] + 1) * height
// Total height of all graph divs - used for wrappers in css
var total_height = graphs_height + timer_height
// Total height of all divs including timer - used for wrappers in css
var data_width = range * data_div_width + 2
// Width of all data divs
var total_width = data_width + titles_width
// Total width of data plus titles divs - used for wrappers in css



document.write('<style type="text/css">\n')

for (var priority in priorities) {
// Here we write the style info specific to each host
	var host=hosts[priority]
	var position=priority * height
	document.write('div#monitor_host_' + host + ' {\n')
	document.write('position: absolute;\n')
	document.write('top: ' + position + 'px;\n')
	document.write('left: 0;\n')
	document.write('width: ' + (titles_width - 1) + 'px;\n')
	document.write('}\n')
	document.write('#monitor div div.m_h_' + host + ' { margin-top: ' + position + 'px }\n')
}

document.write('#monitor_hosts, #monitor, #monitor div {\n')
	document.write('height: ' + graphs_height + 'px;\n')
document.write('}\n')
document.write('#monitor_wrapper {\n')
	document.write('height: ' + total_height + 'px;\n')
	document.write('width: ' + total_width + 'px;\n')
document.write('}\n')
document.write('#monitor {\n')
	document.write('left: ' + titles_width + 'px;\n')
	document.write('top: ' + timer_height + 'px;\n')
	document.write('width: ' + data_width + 'px;\n')
document.write('}\n')
document.write('#monitor_time {\n')
	document.write('left: ' + titles_width + 'px;\n')
	document.write('top: 0;\n')
	document.write('width: ' + data_width + 'px;\n')
document.write('}\n')
document.write('#monitor_hosts {\n')
	document.write('left: 0;\n')
	document.write('top: ' + timer_height + 'px;\n')
	document.write('width: ' + titles_width + 'px;\n')
document.write('}\n')

// End of style information, start content divs

document.write('</style>\n')


document.write('<div id="monitor_wrapper">\n')
document.write('<div id="monitor_time">&nbsp;</div>\n')
document.write('<div id="monitor_hosts">\n')

for (var priority in priorities) {
// Here we write the divs for each host
	var host = hosts[priority]
	var locn = locns[priority]
	document.write('<div id="monitor_host_' + host + '" class="monitor_host">\n')
	document.write('<div class="monitor_host_location_' + locn + '">' + locn + '</div>\n')
	document.write('<div class="monitor_host_name">' + host + '</div>\n')
	document.write('<div id="monitor_data_' + host + '" class="monitor_data"> </div>\n')
	document.write('</div>\n')
}

document.write('</div>\n')
// End of monitor_hosts div

document.write('<div id="monitor">\n')
for (j = 0; j <= range; j++) document.write('<div id="m_hour_' + j + '"></div>\n')
// Write one more div than the maximum range to show  to allow for partially-filled div at each end
document.write('</div>\n')
// End of monitor div

document.write('<div id="monitor_summary">\n')
document.write('</div>\n')
document.write('<div id="monitor_last_summary">\n')
document.write('</div>\n')
// Invisible monitor_summary divs

for (var style in styles) {
	var re = / /
	var style = styles[style]
	var astyle = style.replace(re,'_')
	document.write('<div id="' + astyle + '" title="' + style +'">\n')
	document.write('</div>\n')
	document.getElementById(astyle).onclick = setActiveStyleSheet
}
// Style-changer divs

document.write('</div>\n')
// End of monitor_wrapper div









var hwidth = 1 + (60 / interval) * pxperrecord;
//  Width of one hour's data (add 1 pixel for border)
var width = range * hwidth;
// Total width of display

var req, url, dest, func, currentdiv, postproc;
var load, start, loaded;
// Temporary storage date variables

initialize();


function initialize() {
	load = new Date();
	load.setUTCMinutes(0)
	// Round down to this hour
	start = new Date(load.getTime() - 1000 * 60 * 60 * range);
	// start is range hours earlier
	currentdiv = 0;
	// div to load into
	loaded = new Date();
	positionall();
	postproc='displayuptime';
	// post-processing - function called after all else
	loadall();
}

function loadlatest() {
// Load current data (to run every interval minutes)
	load = new Date();
	load.setUTCMinutes(0)
// Round down to this hour
	var hourshift = Math.round(( load.getTime() - loaded.getTime() ) / 1000 / 60 / 60 );
	if ( hourshift != 0 ) {
// We've moved on to another hour - transfer data
//alert ('hour changed by ' + hourshift)
		postproc='displayuptime';
// After each new hour, reset the uptime displays
		if ( hourshift >= range ) {
// Delayed so long that all divs are out of date - just reload as new
			initialize()
			return
		}
		for (var i = hourshift; i <= range; i++) {
// Where possible, don't reload a div, just move its contents
			var sourcediv = 'm_hour_' + i
			var destdiv = 'm_hour_' + (i - hourshift)
			document.getElementById(destdiv).innerHTML = document.getElementById(sourcediv).innerHTML;
			setEvents(destdiv);
// Reset the event handler for moved divs
		}
                currentdiv -= hourshift
        }
        start.setTime(loaded.getTime())
// reload from where we left off last time
        positionall();
        loadall();
}

function positionall() {
// Position all divs to place current data at right of display
	var stime = new Date();
	stime.setTime(stime.getTime() - range * 60 * 60 * 1000);
// Time at left of data range
	var offset = Math.floor( stime.getUTCMinutes() / interval * pxperrecord);
// Monitoring divs offset based on UTC minutes only
	var localoffset = Math.floor( stime.getHours() * hwidth + (stime.getMinutes() / interval) * pxperrecord);
	document.getElementById('monitor_time').style.backgroundPosition = '-' + localoffset + 'px 0';
// Time scale displays local time
	for (var i = 0; i <= range; i++) {
// position all divs
		var h = 'm_hour_' + i
		var x = i * hwidth - offset
		while (x < -hwidth) x += width;
// negative value less than one hour's width is acceptable - the left end element
		document.getElementById(h).style.left = x + 'px';
	}
}
function loaddone() {
//alert('done')
	currentdiv = range;
	if (postproc) {
		setTimeout(postproc + '()',1000)
	}
	setTimeout('loadlatest()',interval * 60 * 1000)
}

function loadall() {
// Load data into each visible hour div
	var d = start.getUTCFullYear() + '-' + pad(start.getUTCMonth()+1,2) + '-' + pad(start.getUTCDate(),2);
// 2006-05-25 for May 25th
	var h = start.getUTCHours()
	url = source + d + '-' + pad(h,2) + '?r=' + Math.random();
	dest = 'm_hour_' + currentdiv
//if (! confirm('load hour ' + h)) return

	loaded.setTime(start.getTime())
// Keep track of divs already loaded

	start.setTime(start.getTime() + 1000 * 60 * 60);
// one hour later
	currentdiv++
	func = (currentdiv > range) ? ('loaddone()') : ('loadall()');
// return function - stops after loading latest
	request(url)
}

function loadsum() {
// Load summary data into invisible divs
	var d = start.getUTCFullYear() + '-' + pad(start.getUTCMonth()+1,2);
// 2006-05 for May 2006 (summary data for current month)
	url = source + d + '?r=' + Math.random();
	dest = 'monitor_summary'
	func = 'loadlsum()';
// Run loadlsum and displaysum on completion
	request(url)
}

function loadlsum() {
// Load summary data into invisible divs
	var m = start.getUTCMonth()
	var y = start.getUTCFullYear()
	if ( --m < 0) {
		m = 11
		y--
	}
	var d = y + '-' + pad(m+1,2);
// 2006-04 for May 2006 (summary data for last month)
	url = source + d + '?r=' + Math.random();
	dest = 'monitor_last_summary'
	func = 'displaysum()';
// Run displaysum on completion
	request(url)
}

function request(url)
{
// Make XMLHttpRequest for url u
// branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        req.onreadystatechange = processReqChange;
        req.open("GET", url, true);
        req.send(null);
// branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.onreadystatechange = processReqChange;
            req.open("GET", url, true);
            req.send();
        }
    }
}

function displaysum()
{
	sumdata = document.getElementById("monitor_summary").getElementsByTagName('div');
	for (var i in sumdata) {
		var content=sumdata[i].innerHTML
		if ( ! content ) continue
		var classElem = sumdata[i].className.substr(4).split(' ')
		var host = classElem[0]
		var type = classElem[1]
		if (! document.getElementById('monitor_data_' + host) ) continue
		if ( type == 'm_uptime_monthly' ) document.getElementById('monitor_data_' + host).innerHTML = content
		if ( type == 'm_status' ) document.getElementById('monitor_host_' + host).className += " " + content
	}
	sumdata = document.getElementById("monitor_last_summary").getElementsByTagName('div');
	for (var i in sumdata) {
		var content=sumdata[i].innerHTML
		if ( ! content ) continue
		var classElem = sumdata[i].className.substr(4).split(' ')
		var host = classElem[0]
		var type = classElem[1]
		if ( type == 'm_status' ) continue
		if (! document.getElementById('monitor_data_' + host) ) continue
		document.getElementById('monitor_data_' + host).innerHTML += '<br />\n' + content
	}
	displayupdays()
}

function displayuptime()
{
	postproc=''
// Clear postproc function until required again (next hour)
	loadsum()
// Loadsum loads summary data and runs displaysum on completion
// displaysum shows data and runs displayupdays on completion	
}

function displayupdays()
{
	var last = (currentdiv == 0) ? 'm_hour_0' : 'm_hour_' + (currentdiv-1)
// Previous hour will contain uptime data for all servers, but if it's
// midnight UTC just use current hour
	var lastdata = document.getElementById(last).getElementsByTagName('div')
	var upcount = 0
	for (var i in lastdata) {
		if ( ! lastdata[i].className ) continue
		var classElem = lastdata[i].className.substr(4).split(' ')
		if ( classElem[2] != "m_updays" ) continue
		var host = classElem[0]
		var n = lastdata[i].innerHTML
		var days = ( n==1 ) ? ' day' : ' days'
		var content = document.getElementById('monitor_data_' + host).innerHTML
		content += "<br />\nUp " + n + days
		document.getElementById('monitor_data_' + host).innerHTML = content
		if ( upcount++ > hosts.length ) break
	}

}

function processReqChange() 
{
    // only if req shows "complete"
//alert(req.readyState)
	if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
		document.getElementById(dest).innerHTML=req.responseText;
		setEvents(dest)
		} else {
//			alert("Error: " + url + " : " + req.statusText);
		}
		if (func) eval (func)
    }
}

function pad(data,n) {
// Pad numeric data to n char string
	var d = data.toString()
	while (d.length < n) d = '0' + d;
	return d	
}

function setEvents(d) {
	var col = document.getElementById(d).getElementsByTagName("div")
	for (var j in col) {
		col[j].onclick = showData
	}
}
			
function showData(ev) {
// Display detailed data for a measurement
	var target = ev ? ev.target : window.event.srcElement;

	var classElem = target.className.substr(4).split(' ')
	var host = classElem[0]
	var data=target.innerHTML
	document.getElementById('monitor_data_' + host).innerHTML = data
}

function setActiveStyleSheet(ev) {
// Set stylesheet based on id of element clicked
   var target = ev ? ev.target : window.event.srcElement;
   var re = /_/
   var title = target.id.replace( re, ' ' )
   var i, a, main;
   for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
     if(a.getAttribute("rel").indexOf("style") != -1
        && a.getAttribute("title")) {
       a.disabled = true;
       if(a.getAttribute("title") == title) a.disabled = false;
     }
   }
}


