/////////////////////////////////////////////////////////////////////////
/// Copyright Eric Zavesky @ zavesky.org (c) 2008
/// 
/// This software was created exclusively by Eric Zavesky and not
/// for public release in any form.
/// 
/// Any commercial use of the materials, without the written permission 
/// of Eric Zavesky, is strictly prohibited. For permission to use 
/// specific materials, please contact Eric Zavesky (eric@zavesky.org).
/// 
/// Eric Zavesky is not, under any circumstances, responsible for 
/// the unauthorized use or redistribution of digital collections 
/// found on this Web site.
///
/// NOTE: Many code samples here are taken from the FLOT example code.
/// 
/////////////////////////////////////////////////////////////////////////

$(function () {
	$('#placeholder').html(
		'<h1>Initializing data environment, please wait...</h1>'+
		'<strong>If this page does not work...</strong><br />'+
		'Try opening <a href="http://zavesky.org/2008/12/01/uselog-demo-with-jquery" title="uselog blog entry">this blog entry</a> directly!');

	//get your free loader here... http://www.ajaxload.info/
	$("input[@name='show_data']").change(function(){
		update_selection();
	});
	$('#usetime_prev,#usetime_next').click(function() {
		update_selection(null, $(this).attr('id')=='usetime_prev' ? -1 : +1);
	});

	//force a delay for the load...
	update_selection($("input[@name='show_data']:checked").val());
});

//update data on this selection
function update_selection(newType, pageMove) {
	//update our new type...
	if (newType==undefined || newType==null) 
		newType = $("input[@name='show_data']:checked").val();

	$('#placeholder').html(
		'<h1>Retrieving your new results, please wait...</h1>');
	//'<div style="margin:auto;width:40%" ><img style="width:64px;margin:auto;" src="/tools/uselogs/demo_busy.gif" alt="Busy icon..." /></div>');
	$("#usetime_forms").hide();

	//how muhc shoudl we move the time?
	var reqParam = { plot_mode: newType };      //demo data
	if (pageMove!=undefined && $('#overview').data('start')!=undefined)  {
		reqParam.time_start = $('#overview').data('start');	
		reqParam.page_offs = pageMove;
	}

	$.getJSON(
   		'/tools/uselogs/demo.php',  reqParam, //demo url/data
    	function(jData){  //process result
        	if (jData.name && jData.name=='usage') {
				var actData = [];
				$.each(jData.output, function(fancyName, dataVal) {
					actData.push(dataVal);
				});
            	initGraphs(actData, jData.range, [jData.max], jData.tick);
				$("#overview").data('start', jData.input);
				$("#usetime_forms").show();
				showTime(jData.range.xaxis.from);
         	}
		 	else {
         		var resText = 'Sorry, there was a server error. ';
				resText += ' Please check back later!';
				$('#overview').text(resText);
				$('#placeholder').text(resText);
		 	}
    });
}

//once the data is found, populate the graphs
function initGraphs(d, mainAxisZoom, d_max, tickType, forceOffset) {
	var needRange = false;
	if (!tickType) tickType='';
	if (!mainAxisZoom) {
		needRange = true;
	}

    // first correct the timestamps - they are recorded as the daily
    // midnights in UTC+0100, but Flot always displays dates in UTC
    // so we have to add one hour to hit the midnights in the plot
	if (needRange) { 
		//wrap as an array
		d = [ { data:d } ];
		d_max = d;
		//find min/max
		mainAxisZoom = find_minmax(d, forceOffset);
	}
	
	//master options
    var mainOptions = {
        xaxis: { mode: "time" },
        yaxis: { tickFormatter: function (v, axis) { 
			return v.toFixed(axis.tickDecimals) + tickType }}, 
        selection: { mode: "x" },
        grid: { markings: importantArea }
    };

	//generate the two different plots
    var mainPlot = $.plot($("#placeholder"), d, mainOptions);
    var globalPlot = $.plot($("#overview"), d_max, {
        lines: { show: true, lineWidth: 1 },
        shadowSize: 0,
        xaxis: { mode: "time" },
        yaxis: { ticks: [], min: mainAxisZoom.yaxis.from, max: mainAxisZoom.yaxis.to },
        selection: { mode: "x" },
        grid: { markings: importantArea }
    });

    // now connect the two
    $("#placeholder").bind("plotselected", function (event, ranges) {
		//generate new axis zoom
		var newRange = find_minmax(
			d, forceOffset, ranges.xaxis.from, ranges.xaxis.to);

        // do the zooming
        mainPlot = $.plot($("#placeholder"), d,
          $.extend(true, {}, mainOptions, {
            xaxis: { min: newRange.xaxis.from, max: newRange.xaxis.to },
            yaxis: { min: newRange.yaxis.from, max: newRange.yaxis.to }
          }));
		
        // don't fire event on the overview to prevent eternal loop
        globalPlot.setSelection(ranges, true);
		showTime(newRange.xaxis.from); //from CALI TIME
    }).dblclick(function() {
        globalPlot.setSelection(mainAxisZoom);
		mainPlot.clearSelection();
		globalPlot.clearSelection();
	});
    
    $("#overview").bind("plotselected", function (event, ranges) {
        mainPlot.setSelection(ranges);
    }).dblclick(function() {
        globalPlot.setSelection(mainAxisZoom);
		mainPlot.clearSelection();
		globalPlot.clearSelection();
	});
}

//update the start of the current time
function showTime(newTime, utcOffs) {
	var curDateObj = $('#lastdate');
	if (curDateObj) {
		if (utcOffs==undefined) utcOffs = 0;
		var newD = new Date(newTime + utcOffs*60*60*1000);
		var strDate = //newD.toUTCString();
		(newD.getUTCMonth() + 1)+'/'+newD.getUTCDate()+'/'+newD.getUTCFullYear();
		curDateObj.text('Starting Date: '+strDate);
	}
}
// helper for returning the weekends in a period
function importantArea(axes) {
    var markings = [];
    var d = new Date(axes.xaxis.min);
    // go to the first Saturday
    d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 1) % 7))
    d.setUTCSeconds(0);
    d.setUTCMinutes(0);
    d.setUTCHours(0);		//about midnight EST
    var i = d.getTime();
    do {
        // when we don't set yaxis the rectangle automatically
        // extends to infinity upwards and downwards
        markings.push({ xaxis: { from: i, to: i + 6 * 60 * 60 * 1000 } });
        //markings.push({ xaxis: { from: i, to: i + 2 * 24 * 60 * 60 * 1000 } });
        i += 1 * 24 * 60 * 60 * 1000;
        //i += 7 * 24 * 60 * 60 * 1000;
    } while (i < axes.xaxis.max);

    return markings;
}

//given a specified area, find the range
function find_minmax(d, forceOffset, offBegin, offEnd) {
	var checkX = (offBegin!=undefined && offEnd!=undefined);
	var mainAxisZoom = {
		xaxis: { from: -1, to: -1 },
       	yaxis: { from: -1, to: -1 }
	};

	//find min/max
   	for (var k = 0; k < d.length; ++k) {
		//iterate through all members of this set
		for (var i=0; i<d[k].data.length; i++) {
			//skip data we're not zoomed on if set
			if (checkX && (offBegin>d[k].data[i][0] || offEnd<d[k].data[i][0]))
				continue;
			//add offset if needed
 			if (forceOffset)
     				d[k].data[i][0] += 60 * 60 * 1000;
			//otherwise find min/max at start
  			if (mainAxisZoom.xaxis.from==-1) {
				mainAxisZoom.xaxis.from = d[k].data[i][0];
				mainAxisZoom.xaxis.to = d[k].data[i][0];
				mainAxisZoom.yaxis.from = d[k].data[i][1];
				mainAxisZoom.yaxis.to = d[k].data[i][1];
			}
			else {
				if (mainAxisZoom.xaxis.to<d[k].data[i][0])
					mainAxisZoom.xaxis.to = d[k].data[i][0];
  				if (mainAxisZoom.xaxis.from>d[k].data[i][0])
					mainAxisZoom.xaxis.from = d[k].data[i][0];
				if (mainAxisZoom.yaxis.to<d[k].data[i][1])
					mainAxisZoom.yaxis.to = d[k].data[i][1];
  				if (mainAxisZoom.yaxis.from>d[k].data[i][1])
					mainAxisZoom.yaxis.from = d[k].data[i][1];
			}
		}
	}
	return mainAxisZoom;
}

