{extends file=$smarty.const.SMARTY_LAYOUT_DASHBOARD_WIDGET_DEFAULT}

{block name="localJS"}
	<script type="text/javascript">
		formatWidgetData_{$widget.id} = function(historicalData, options) {
			// prepare the data 
			var widgetDataList = [];
			var colors = {
				main: 		'#91b4da',
				min: 		'#a6a6a6',
				max: 		'#a6a6a6',
				runningAvg: '#181f50',
				trend: 		'#f88989',
			};
			
			if (historicalData) {
				if (options['interval']=='1day') {
					var widgetData = { };
					widgetData.key = "{$widgetLang['name']}";
					widgetData.area = true;
					widgetData.classed = 'main';
					widgetData.color = colors.main;
					widgetData.values = historicalData
						.map(function(d) {
							return {
								x: new Date((+d.timestamp)*1000),
								y: +d.value	
							};
						});
					widgetDataList.push(widgetData);
					
					var runningAvg = (widgetData.values.length?widgetData.values[0].y:0);
					var avgWidgetData = { };
					avgWidgetData.key = "{$widgetLang['avg']}";
					avgWidgetData.area = false;
					avgWidgetData.classed = 'runningAvg';
					avgWidgetData.color = colors.runningAvg;
					avgWidgetData.disableTooltip = true;
					avgWidgetData.values = historicalData
						.filter(function(d, i) {
							// eliminate every 4'th data point, to speed up the calulations & rendering
							return i%4==0;
						})
						.map(function(d) {
							// format data points
							var ret = {
								x: new Date(+(d.timestamp)*1000),
								y: +(d.value)
							};
							
							runningAvg = (runningAvg*4 + ret.y)/5;	// average of 5 minutes
							
							ret.y = runningAvg;
							
							return ret;
						});
					widgetDataList.push(avgWidgetData);
				}
				
				if (options['interval']=='1month') {
					// average
					var avgWidgetData = { };
					avgWidgetData.key = "{$widgetLang['avg']}";
					avgWidgetData.area = true;
					avgWidgetData.classed = 'main';
					avgWidgetData.color = colors.main;
					avgWidgetData.values = historicalData				
						.map(function(d) {
							// format data points
							var ret = {
								x: new Date(d.dayDate),
								y: +d.avg
							};
							
							return ret;
						});
					widgetDataList.push(avgWidgetData);
					
					// min value
					var minWidgetData = { };
					minWidgetData.key = "{$widgetLang['min']}";
					minWidgetData.classed = 'min';
					minWidgetData.color = colors.min;
					minWidgetData.values = historicalData
						.map(function(d) {
							return {
								x: new Date(d.dayDate),
								y: +d.min,
								shape: 'triangle-down'
							};
						});
					widgetDataList.push(minWidgetData);
					
					// max value
					var maxWidgetData= { };
					maxWidgetData.key = "{$widgetLang['max']}";
					maxWidgetData.classed = 'max';
					maxWidgetData.color = colors.max;
					maxWidgetData.values = historicalData
						.map(function(d) {
							return {
								x: new Date(d.dayDate),
								y: +d.max,
								shape: 'triangle-up'
							};
						});
					widgetDataList.push(maxWidgetData);
					
					
					// Calculates the `variation` graph based on the range of [minValue, maxValue] taken on that day
					var runningAvg = (minWidgetData.values.length?minWidgetData.values[0].y:0);
					var minValue = (minWidgetData.values.length?d3.min(minWidgetData.values, function(d) { return d.y;}): 0);
					var maxValue = (minWidgetData.values.length?d3.max(minWidgetData.values, function(d) { return d.y;}): 0);
					avgMinWidgetDataScale = d3.scale.linear()
		    			.domain([minValue, maxValue])
		    			.range([minValue, maxValue]);
		    
					var avgMinWidgetData = { };
					avgMinWidgetData.key = "{$widgetLang['runningAvg']}";
					avgMinWidgetData.area = false;
					avgMinWidgetData.classed = 'runningAvg';
					avgMinWidgetData.color = colors.runningAvg;
					avgMinWidgetData.disableTooltip = true;
					avgMinWidgetData.values = historicalData
						.map(function(d) {
							// format data points
							var ret = {
								x: new Date(d.dayDate),
								y: avgMinWidgetDataScale(+(d.min))
							};
							
							runningAvg = (runningAvg*4 + ret.y)/5;	// average over the last 5 sample points 
							ret.y = runningAvg;
							
							return ret;
						});
					widgetDataList.push(avgMinWidgetData);
				}
				
				
				if (options['interval']=='1year') {
					// average
					var avgWidgetData = { };
					avgWidgetData.key = "{$widgetLang['avg']}";
					avgWidgetData.area = true;
					avgWidgetData.classed = 'main';
					avgWidgetData.color = colors.main;
					avgWidgetData.values = historicalData				
						.map(function(d) {
							// format data points
							var ret = {
								x: new Date(d.dayDate),
								y: +d.avg
							};
							
							return ret;
						});
					widgetDataList.push(avgWidgetData);
					
					// min value
					var minWidgetData = { };
					minWidgetData.key = "{$widgetLang['min']}";
					minWidgetData.classed = 'min';
					minWidgetData.color = colors.min;
					minWidgetData.values = historicalData
						.map(function(d) {
							return {
								x: new Date(d.dayDate),
								y: +d.min,
								shape: 'triangle-down'
							};
						});
					widgetDataList.push(minWidgetData);
					
					// max value
					var maxWidgetData= { };
					maxWidgetData.key = "{$widgetLang['max']}";
					maxWidgetData.classed = 'max';
					maxWidgetData.color = colors.max;
					maxWidgetData.values = historicalData
						.map(function(d) {
							return {
								x: new Date(d.dayDate),
								y: +d.max,
								shape: 'triangle-up'
							};
						});
					widgetDataList.push(maxWidgetData);
					
					
					// Calculates the `variation` graph based on the range of [minValue, maxValue] taken on that day
					var runningAvg = (minWidgetData.values.length?minWidgetData.values[0].y:0);
					var minValue = (minWidgetData.values.length?d3.min(minWidgetData.values, function(d) { return d.y;}): 0);
					var maxValue = (minWidgetData.values.length?d3.max(minWidgetData.values, function(d) { return d.y;}): 0);
					avgMinWidgetDataScale = d3.scale.linear()
		    			.domain([minValue, maxValue])
		    			.range([minValue, maxValue]);
		    
					var avgMinWidgetData = { };
					avgMinWidgetData.key = "{$widgetLang['runningAvg']}";
					avgMinWidgetData.area = false;
					avgMinWidgetData.classed = 'runningAvg';
					avgMinWidgetData.color = colors.runningAvg;
					avgMinWidgetData.disableTooltip = true;
					avgMinWidgetData.values = historicalData
						.map(function(d) {
							// format data points
							var ret = {
								x: new Date(d.dayDate),
								y: avgMinWidgetDataScale(+(d.min))
							};
							
							var ratio = ret.y/runningAvg;
							 
							if (ratio>0.9) {
								runningAvg =  (runningAvg*3 + ret.y)/4;
							}
							else {
								runningAvg =  (runningAvg*0.1 + ret.y)/1.1;
							}
							
							runningAvg = (runningAvg*2 + ret.y)/3;	// average over the last 5 sample points
							
							/* var ratio = ret.y/runningAvg;
							if      (ratio>2.5) {
								runningAvg =  (runningAvg*1 + ret.y)/2;	// average over the last 3 sample points
							}
							else if (ratio>2.0) {
								runningAvg =  (runningAvg*6 + ret.y)/7;	// average over the last 7 sample points
							}
							else if (ratio>0.9) {
								runningAvg =  (runningAvg*29 + ret.y)/30;	// average over the last 7 sample points
							}
							else if (ratio>0.75) {
								runningAvg =  (runningAvg*6 + ret.y)/7;	// average over the last 7 sample points
							}
							else if (ratio>0.25) {
								runningAvg =  (runningAvg*2 + ret.y)/3;	// average over the last 7 sample points
							}
							else {
								runningAvg =  (runningAvg*0 + ret.y)/1;	// average over the last 7 sample points
							} */
							
							ret.y = runningAvg;
							
							return ret;
						});
					widgetDataList.push(avgMinWidgetData);
				}
			}
		
			return widgetDataList;
		}
	
	
	
		// first render, on page load
		MVC.scheduleOnLoad(function() {
			var options = {$widget['options']|json_encode};
			var widgetDataList = formatWidgetData_{$widget.id}({$widget['data']['values']|json_encode}, {$widget['options']|json_encode});
			// add the actual graph	
		 	nv.addGraph({
		 		generate: function() {
		 			var svgelm = d3.select('#{$widget.id} svg');
		 			var width = svgelm.node().getBoundingClientRect().width,
							height = svgelm.node().getBoundingClientRect().height;
					// force Y axis to display 0 so that we can see the graphs displaying small values		
					var chart = nv.models.lineChart()															
								.width(width)
								.forceY(0)
								.height(height)
								.legendPosition('top')								
								.useInteractiveGuideline(true);
					
					// overwrite the `no data` message for this chart, if an errorMessage exists 
					{if $widget['data']['errorMessage']}
						chart.noData("{$widget['data']['errorMessage']}");
					{/if}
								
					// use the "furious" legend type
					chart.legend.vers('furious');	
					
					// exponential scale
					// chart.yScale(d3.scale.pow().exponent(2));

					// Check for options, show hours for '1day' and date for others 
					var tickFormat = d3.time.format('%H:%M');
					if (options.interval == "1year" || options.interval == "1month") {
						tickFormat = d3.time.format('%d-%m-%Y');
					}
					
					chart.xAxis.tickFormat(function(d) {
						return tickFormat(new Date(d));
					});

					var roundBy2 = d3.format(',.2f');
					chart.yAxis.tickFormat(function(d) {
						return roundBy2(d);
					});
					
					chart.yAxis.axisLabel('{$widgetLang['yAxis']['description']}');
					
					var svg = svgelm.datum(widgetDataList);
					svg	
						.transition().duration(0)
						.call(chart);

					window.chart_{$widget.id} = chart;
					return chart;	 		
		 		},
		 		callback: function(chart) {
					dashboardController.dashboardElement.observe('widget:drop', function(evt) {
						dashboardController.dashboard.fireWindowResize();
					});

					// redraw on window resize
					nv.utils.windowResize(function() {
						var svgelm = d3.select('#{$widget.id} svg');
						var width = svgelm.node().getBoundingClientRect().width

						chart
							.width(width);
						
						svgelm
							.attr('width', width)
							.transition().duration(0)
							.call(chart);
						});
					return chart;
				}
		   	});
		   	
			// observe the `changed` fire event on the date input 
			// (whenever a valid date is input and is also changed by the formatter)	   	
		   	$('{$widget.id}_title').observe('validator:changed', function() { 
		  	 	var newLogDate = document.getElementById('{$widget.id}').value;
				
				var url=MVC.appUrl(MVC.CURRENT_MODULE, 'editDashboardElement', { 'idEntity' : '{$widget.id}', 'operation': 'methodCall', 'date': newLogDate, 'method': 'getServerStatsData_AJAX', 'src': '{$widget.id}' } );
				// do the ajax request
				new Ajax.Request(url, {
					onSuccess: function(transport, JSON) {
						var svgelm = d3.select('#{$widget.id} svg');
						var svg = svgelm.datum(formatWidgetData_{$widget.id}(JSON.response.values, {$widget['options']|json_encode}));
						svg	
							.transition().duration(0)
							.call(window.chart_{$widget.id});
					}
				});
						
		   	});
		});
	</script>
{/block}