<html>
<head>
	<title>Benchtracker viewer</title>
	<link rel="stylesheet" type="text/css" href="/static/viewer.css" />
	<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
    <script type="text/javascript" src="http://gabelerner.github.io/canvg/rgbcolor.js"></script> 
    <script type="text/javascript" src="http://gabelerner.github.io/canvg/StackBlur.js"></script>
    <script type="text/javascript" src="http://gabelerner.github.io/canvg/canvg.js"></script> 
    <script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/jszip/2.5.0/jszip.min.js'></script>
    <script type='text/javascript' src='/static/FileSaver.js'></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.css" rel="stylesheet" type="text/css"></link>
    <script>
    	var database = '{{database}}';
    </script>
    <script src="/static/plotter.js"></script>
	<script src="/static/viewer.js"></script>
</head>


<body>

<div id="selection_bar">
	<div class="box_wrapper"><div class="selection_box" id="task_select">
		<h5 class="box_header">Select tasks</h5>
		{% for task_name in tasks %}
	    <a class="task" title="{{ task_name }}">{{task_name}}</a>
	    {% endfor %}
    </div></div>
    <div class="box_wrapper"><div class="selection_box" id="x_box"> 
    	<h5 class="box_header">x parameter</h5>
    	<form id="x_param"></form>
    </div></div>
    <div class="box_wrapper"><div class="selection_box" id="y_box">
    	<h5 class="box_header">y parameter</h5>
    	<form id="y_param"></form>
    </div> </div>
    <div class="box_wrapper page_divider" id="add_filter"><br><br><br><br><h1>+</h1><br>filter</div>
</div>

<div id="display_canvas">
	<div class="options_container">
    <a class='page_divider divider_options' id="generate_plot">Generate plot</a>
    <a class='page_divider divider_options' id="generate_csv">Download as CSV</a>
    <a class='page_divider divider_options' id="get_query">Get query string</a>
    </div>
    <div id="plotter_container">
	    <a class='page_divider plotter_options' id='customizePlot'>Customize plot</a>
        <a class='page_divider plotter_options' id='savePlot'>Save plots (png, svg)</a>
        <a class='page_divider plotter_options' id='savePlotData'>Save plotter data</a>

	    <div id='custom_panel'>
	        <div class="custom_plot_selection_box" id="gmean_select">
	        	<form class="custom_plot_form" id="gmean_options" action="">
	        	<fieldset>
	        		<legend><strong>average (geometric) over:</strong></legend>
	        	</fieldset>
	        	</form>
	        </div>
	        <div class="custom_plot_selection_box" id="overlay_select">
	        	<form class="custom_plot_form" id="overlay_options" action="">
	        	<fieldset>
	        		<legend><strong>combined series over:</strong></legend>
	        	</fieldset>	        	
	        	</form>
	        </div>
	        <button class='custom_plot_selection_box' id='get_custom_plot'>Get plot
	        </button>
	    </div>
    </div>
    <div id="chart">
    </div>
    <!--canvas id='canvas' width='1000px' height='600px'></canvas-->
</div>
<!--temp div for storing image-->
<div id='temp' style='display: none'>
</div>
</body>

<script>

var exec_delay = 100;
var t = "";

$(document).ready(function() {


report_debug(x_param);
{% if queried_x %}
	x_sel = '{{queried_x}}';
{% endif %}
{% if queried_y %}
	y_sel = '{{queried_y}}';
{% endif %}

{% for task in queried_tasks %}
	var t = task_select.querySelector("a[title='{{task}}']");
	if (t) toggle_task(t);
{% endfor %}

{% if filters %}
	if (t) {
		report_debug("preloading filters");
		preload_filters();
	}
{% endif %}
});


window.onload = function() {
}


function preload_filters() {
	if (params.length !== 0) {
		{% for filter in filters %}
			var f_args = [];
			{% for arg in filter.args %}
				f_args.push('{{arg}}');
			{% endfor %}
			// convert each filter object to a filter window
			preload_one_filter('{{filter.param}}', '{{filter.method}}', f_args);

		{% endfor %}
	}
	else {report_debug("waiting for params"); setTimeout(preload_filters, exec_delay);}
}

function preload_one_filter(param, method, args) {
	if (!active_querying_filter) {
		var f = create_filter_window(param);
		// make sure the selection box matches the filter method
		preload_filter_sel(f, method, args);
	}
	else {report_debug("waiting for construction"); setTimeout(preload_one_filter, exec_delay, param, method, args);}
}

function preload_filter_sel(filter, method, args) {
	var filter_sel = filter.getElementsByClassName("filter_sel");
	if (filter_sel.length !== 0) {	
		filter_sel = filter_sel[0];
		// all the incompatible selections
		if ((method.toUpperCase() === "IN" && filter_sel.value === "range") || 
			(method.toUpperCase() === "BETWEEN" && filter_sel.value === "categorical")) {
			if (filter_sel.value === "categorical") filter_sel.value = "range";
			else filter_sel.value = "categorical";
			fire_event(filter_sel, 'change');
			// keep calling itself until a compatible selection results and preload_filter_val is called
			setTimeout(preload_filter_sel, exec_delay, filter, method, args);
		}
		else {
			// can safely proceed to populate values
			preload_filter_val(filter, method, args);
		}
	}
	else {report_debug("waiting for filter sel"); setTimeout(preload_filter_sel, exec_delay, filter, method, args);}
}

function preload_filter_val(filter, method, args) {
	var filter_val = filter.getElementsByClassName("filter_val");
	if (filter_val.length !== 0) {
		filter_val = filter_val[0];
		if (method.toUpperCase() === "IN") {
			report_debug("selecting in");
			var sel_in = filter_val.getElementsByClassName("in")[0];
			set_selected(sel_in, new Set(args));
		}
		else {
			var min = filter_val.getElementsByClassName("min")[0];
			var max = filter_val.getElementsByClassName("max")[0];
			if (args.length !== 2) {report_debug("incorrect number of filter arguments:" + args.length + "for range"); return;}
			min.value = Number(args[0]);
			max.value = Number(args[1]);
		}
	}
	else {report_debug("waiting for filter val"); setTimeout(preload_filter_val, exec_delay, filter, method, args);}
}

</script>

</html>
