/*
    This file is part of Energy@Home.
	Copyright (C) 2009 Danny Tsang

    This file is part of Energy@Home.

    Energy@Home is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Energy@Home is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Energy@Home.  If not, see <http://www.gnu.org/licenses/>.
*/

//var data = [];
//var temperatureData = [];

var options = null;
var server = "server/server.php";
var plot;
var graphData;

var PERIOD_OF_TIME = new Array ("Hour", "Day", "Week", "Month", "Year");
var HOURS_OF_THE_DAY = new Array ("Today", "Yesterday", "Week", "Month", "Year");

function lastUpdated()
{
	document.getElementById('lastUpdated').innerHTML='<I>Last Updated: ' + new Date().toLocaleString() + '</I>';
}

// Initialises graph and page.
function init()
{
	// Get data from server and draw graph
	if (document.getElementById('graphType') != null && document.getElementById('graphType').value == "Time")
	{
		// Ensure display range is set before generating new graph
		if(document.getElementById('displayRange').value.match(/\d/g) != null)
		{
			preLoad();
			time();
		}
	}
	else if (document.getElementById('graphType') != null &&  document.getElementById('graphType').value == "Hour")
	{
		preLoad();
		hour();
	}
}

function preLoad()
{
	// Change graph to loading image
	$('#placeholder').html('<p><img src="images/ajax-loader.gif" width="220" height="19" /></p>');
	// Clear clicked data points
	$("#clickdata").text("");
	$("#clickoverlay").text("");
}

function changeGraphType()
{
	// Get data from server and draw graph
	if (document.getElementById('graphType') != null && document.getElementById('graphType').value == "Time")
	{
		// Repopulate time fram drop down with new values
		loadTimeFrame(PERIOD_OF_TIME);
		// Enable range textbox
		document.getElementById('displayRange').disabled = false;
		// Set textbox background colour to white
		document.getElementById('displayRange').style.backgroundColor="#fff";
		// Set display range if it's empty
		if(document.getElementById('displayRange').value.match(/\d/g) == null)
		{
			document.getElementById('displayRange').value = "14";
		}
		// Enable auto refresh
		document.getElementById('AutoRefresh').checked = false;
	}
	else if (document.getElementById('graphType') != null && document.getElementById('graphType').value == "Hour")
	{
		// Repopulate time fram drop down with new values
		loadTimeFrame(HOURS_OF_THE_DAY);
		// Disable range textbox
		document.getElementById('displayRange').disabled = true;
		// Make disabled textbox grey
		document.getElementById('displayRange').style.backgroundColor="#c0c0c0";
		// Disable auto refresh
		document.getElementById('AutoRefresh').checked = false;
	}
	
	init();
}

function loadTimeFrame(list)
{
	// Get drop down list
	var dropdown = document.getElementById("timeScale");
	
	// Clear drop down
	dropdown.options.length = 0;
	
	// Load drop down with array
	for (var i = 0; i < list.length; i++)
	{
		dropdown.options[dropdown.options.length] = new Option(list[i], list[i]);
	}
}

// Generate time based graph with energy and temp
function time()
{
	// Set display options for graphs
	if(document.getElementById('timeScale').value == "Hour")
	{
		options = { selection: { mode: "x" },
				grid: { hoverable: true, clickable: true, autoHighlight: true, backgroundColor: "#313030" , tickColor: "#545454" },
				legend: { show: document.getElementById('ShowLegend').checked, position: "ne", backgroundColor: "#FFFFFF" },
				yaxis: { min: 0, 
						tickFormatter: (function formatter(val, axis) { return val + "W"}) },
				xaxis: { mode: "time", timeformat: "%h:%M:%S", labelWidth: 10 },
				y2axis: { minTickSize: 1, autoscaleMargin: 2,
						tickFormatter: (function formatter(val, axis) { return val.toFixed(1) + "&deg;C"}) }
				};
	}
	else if(document.getElementById('timeScale').value == "Day")
	{
		options = { selection: { mode: "x" },
				grid: { hoverable: true, clickable: true, autoHighlight: true, backgroundColor: "#313030" , tickColor: "#545454" },
				legend: { show: document.getElementById('ShowLegend').checked, position: "ne", backgroundColor: "#FFFFFF" },
				yaxis: { min: 0, 
						tickFormatter: (function formatter(val, axis) { return val + "W"}) },
				xaxis: { mode: "time", timeformat: "%d-%b-%y %h:%M:%S", labelWidth: 10 },
				y2axis: { minTickSize: 1, autoscaleMargin: 2,
						tickFormatter: (function formatter(val, axis) { return val.toFixed(1) + "&deg;C"}) }
				};
	}
	else
	{
		options = { selection: { mode: "x" },
				grid: { hoverable: true, clickable: true, autoHighlight: true, backgroundColor: "#313030" , tickColor: "#545454" },
				legend: { show: document.getElementById('ShowLegend').checked, position: "ne", backgroundColor: "#FFFFFF" },
				yaxis: { min: 0, 
						tickFormatter: (function formatter(val, axis) { return val + "W"}) },
				xaxis: { mode: "time", timeformat: "%d-%b-%y", labelWidth: 10 },
				y2axis: { minTickSize: 1, autoscaleMargin: 2,
					tickFormatter: (function formatter(val, axis) { return val.toFixed(1) + "&deg;C"}) }
		};
	}
	
	getTime();
 
	autoRefresh();
}

function hour()
{
	// Set display options for graphs
	options = { selection: { mode: "x" },
			grid: { hoverable: true, clickable: true, autoHighlight: true, backgroundColor: "#313030" , tickColor: "#545454" },
			legend: { show: document.getElementById('ShowLegend').checked, position: "ne", backgroundColor: "#FFFFFF" },
			yaxis: { min: 0, 
					tickFormatter: (function formatter(val, axis) { return val + "Wh"}) },
			xaxis: { tickSize: 1, 
					tickFormatter: (function formatter(val, axis) { return val + "h"})}
			};
			
	getHour();

	autoRefresh();
}

// Get time data via http request
function getTime()
{
	httpObject = getHTTPObject();
	
	var arguments = "graph=" + document.getElementById('graphType').value +
					"&parameter=" + document.getElementById('timeScale').value +
					"&displayRange=" + document.getElementById('displayRange').value;

	if(document.getElementById('CurrentEnergy').checked)
	{
		arguments += "&energy=true";
	}
	
	if(document.getElementById('CurrentInverterEnergyCC').checked)
	{
		arguments += "&inverterenergycc=true";
	}
	
	if(document.getElementById('CurrentInverterEnergy').checked)
	{
		arguments += "&inverterenergy=true";
	}
	
	if(document.getElementById('CurrentTemperature').checked)
	{
		arguments += "&temperature=true";
	}
	
	if(document.getElementById('EnergyOverlay').checked)
	{
		arguments += "&overlayenergy=true";
	}
	
	if(document.getElementById('InverterEnergyCCOverlay').checked)
	{
		arguments += "&overlayinverterenergycc=true";
	}
	
	if(document.getElementById('InverterEnergyOverlay').checked)
	{
		arguments += "&overlayinverterenergy=true";
	}
	
	if(document.getElementById('TemperatureOverlay').checked)
	{
		arguments += "&overlaytemperature=true";
	}
	
	if (httpObject != null)
	{
		if(arguments.length > 0)
		{
			httpObject.open("GET", server + "?" + arguments, true);
		}
		else
		{
			httpObject.open("GET", server, true);
		}
		httpObject.send(null);
		httpObject.onreadystatechange = setTimeGraph;
	}
}

// Get time data via http request
function getHour()
{
	httpObject = getHTTPObject();
	
	var arguments = "graph=" + document.getElementById('graphType').value +
					"&parameter=" + document.getElementById('timeScale').value;
	
	if (httpObject != null)
	{
		if(arguments.length > 0)
		{
			httpObject.open("GET", server + "?" + arguments, true);
		}
		else
		{
			httpObject.open("GET", server, true);
		}
		httpObject.send(null);
		httpObject.onreadystatechange = setTimeGraph;
	}
}

// Get the HTTP Object for AJAX request
function getHTTPObject()
{
	if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP");
	else if (window.XMLHttpRequest) return new XMLHttpRequest();
	else
	{
		alert("Your browser does not support the technology used on this page (AJAX).");
		return null;
	}
}
		   
// Build time graph once data request response is returned
function setTimeGraph()
{
	if(httpObject.readyState == 4)
	{
		// Uncomment for debug
		//document.getElementById('debug').value = httpObject.responseText;
		var results = eval("([" + httpObject.responseText + "])");
		graphData = results;

		plot = $.plot($("#placeholder"),
				results
			   , options);

		lastUpdated();
	}
}

function getSubtrackOverlay(range, timeframe)
{
	var time = 0;
	
	if(range == "")
	{
		range = 1;
	}
	
	if (timeframe == "Hour")
	{
		time = 3600000 * range;
	}
	else if (timeframe == "Day")
	{
		time = 86400000 * range;
	}
	else if (timeframe == "Week")
	{
		time = 604800000 * range;
	}
	else if (timeframe == "Month")
	{
		time = 2629743830 * range;
	}
	else if (timeframe == "Year")
	{
		time = 31556926000 * range;
	}
	
	return time;
}

function resetZoom()
{
	init();
	document.getElementById('AutoRefresh').checked = false;
	autoRefresh();
}

// Set http object to null
var httpObject = null;

function graphClick(event, pos, item)
{
	if (item) {
		// Check what type of graph is showing. For future use
		if (document.getElementById('graphType').value == "Time")
		{
			//$("#clickdata").text("You clicked point " + item.dataIndex + " in " + item.series.label + ".");
			if(item.series.label == "Energy Used")
			{
				$("#clickdata").text("Current: " + parseInt(item.datapoint[1].toFixed(2)) + " watts was used on " +
						new Date(parseInt(item.datapoint[0].toFixed(2))).toGMTString() + ".");
			}
			else if(item.series.label == "CC Energy Generated")
			{
				$("#clickdata").text("Current: " + parseInt(item.datapoint[1].toFixed(2)) + " watts was generated on " +
						new Date(parseInt(item.datapoint[0].toFixed(2))).toGMTString() + ".");
			}
			else if(item.series.label == "Energy Generated")
			{
				$("#clickdata").text("Current: " + parseInt(item.datapoint[1].toFixed(2)) + " watts was generated on " +
						new Date(parseInt(item.datapoint[0].toFixed(2))).toGMTString() + ".");
			}
			else if(item.series.label == "Temperature")
			{
				$("#clickdata").text("Current: It was " + item.datapoint[1].toFixed(1) + " degrees celsius at " +
						new Date(parseInt(item.datapoint[0].toFixed(2))).toGMTString() + ".");
			}
			else if(item.series.label == "Energy Overlay")
			{
				// Get offset time
				var subtrackTime = getSubtrackOverlay(document.getElementById('timeScale').value);
				
				$("#clickoverlay").text("Overlay: " + parseInt(item.datapoint[1].toFixed(2)) + " watts was used on " +
						new Date(parseInt(item.datapoint[0].toFixed(2)) - subtrackTime).toGMTString() + ".");
			}
			else if(item.series.label == "Inverter Energy Overlay")
			{
				$("#clickoverlay").text("Overlay: " + parseInt(item.datapoint[1].toFixed(2)) + " watts was generated on " +
						new Date(parseInt(item.datapoint[0].toFixed(2)) - subtrackTime).toGMTString() + ".");
			}
			else if(item.series.label == "Inverter CC Energy Overlay")
			{
				$("#clickoverlay").text("Overlay: " + parseInt(item.datapoint[1].toFixed(2)) + " watts was generated on " +
						new Date(parseInt(item.datapoint[0].toFixed(2)) - subtrackTime).toGMTString() + ".");
			}
			else if(item.series.label == "Temperature Overlay")
			{
				// Get offset time
				var subtrackTime = getSubtrackOverlay(document.getElementById('timeScale').value);
				
				$("#clickoverlay").text("Overlay: It was " + item.datapoint[1].toFixed(1) + " degrees celsius at " +
						new Date(parseInt(item.datapoint[0].toFixed(2)) - subtrackTime).toGMTString() + ".");
			}
		}
	}
}

function graphHover(event, pos, item) {

	
	if (item)
	{
		if (previousPoint != item.datapoint)
		{
			previousPoint = item.datapoint;
			
			$("#tooltip").remove();
			var x = 0, y = new Date();
			// Check what type of graph is showing. For future use
			if (document.getElementById('graphType').value == "Time")
			{
				if(item.series.label == "Energy Used")
				{
					x = parseInt(item.datapoint[1].toFixed(2)),
					y = new Date(parseInt(item.datapoint[0].toFixed(2)));
					
					showTooltip(item.pageX, item.pageY,
							x + " watt(s) used at " + y.toGMTString());

				}
				else if(item.series.label == "CC Energy Generated")
				{
					x = parseInt(item.datapoint[1].toFixed(2)),
					y = new Date(parseInt(item.datapoint[0].toFixed(2)));
					
					showTooltip(item.pageX, item.pageY,
							x + " watt(s) generated at " + y.toGMTString());
				}
				else if(item.series.label == "Energy Generated")
				{
					x = parseInt(item.datapoint[1].toFixed(2)),
					y = new Date(parseInt(item.datapoint[0].toFixed(2)));
					
					showTooltip(item.pageX, item.pageY,
							x + " watt(s) generated at " + y.toGMTString());
				}
				else if(item.series.label == "Temperature")
				{
					x = item.datapoint[1].toFixed(1),
					y = new Date(parseInt(item.datapoint[0].toFixed(2)));
					
					showTooltip(item.pageX, item.pageY,
							x + " degrees celsius on " + y.toGMTString());
				}
				else if(item.series.label == "Energy Overlay")
				{
					// Get offset time
					var subtrackTime = getSubtrackOverlay(document.getElementById('displayRange').value, document.getElementById('timeScale').value);
					
					x = parseInt(item.datapoint[1].toFixed(2)),
					y = new Date(parseInt(item.datapoint[0].toFixed(2)) - subtrackTime);
					
					showTooltip(item.pageX, item.pageY,
							x + " Watt(s) used at " + y.toGMTString());
				}
				else if(item.series.label == "Temperature Overlay")
				{
					// Get offset time
					var subtrackTime = getSubtrackOverlay(document.getElementById('displayRange').value, document.getElementById('timeScale').value);
					
					x = item.datapoint[1].toFixed(1),
					y = new Date(parseInt(item.datapoint[0].toFixed(2)) - subtrackTime);
					
					showTooltip(item.pageX, item.pageY,
							x + " degrees celsius on " + y.toGMTString());
				}
			}
			else if (document.getElementById('graphType').value == "Hour")
			{
				x = item.datapoint[1].toFixed(0);
				var y1 = item.datapoint[0];
				var y2 = item.datapoint[0] + 1;
				// Pad time with leading 0
				if(y1 < 10)
				{
					y1 = "0" + y1;
				}
				if(y2 < 10)
				{
					y2 = "0" + y2;
				}
				
				showTooltip(item.pageX, item.pageY,
							x + "W was consumed between " + y1 + ":00 - " + y2 + ":00");
			}
		}
	}
	else
	{
		$("#tooltip").remove();
		previousPoint = null;            
	}
}

// Tooltip look
function showTooltip(x, y, contents)
{
	$('<div id="tooltip">' + contents + '</div>').css( {
		position: 'absolute',
		display: 'none',
		top: y + 20,
		left: x + 5,
		border: '1px solid #fdd',
		padding: '2px',
		'background-color': '#fee',
		opacity: 0.80
	}).appendTo("body").fadeIn(200);
}

