/**
 * @@@ START COPYRIGHT @@@  
 *
 * (C) Copyright 2015 Hewlett-Packard Development Company, L.P.                 
 *                                                                             
 * Licensed under the Apache License, Version 2.0 (the "License");            
 * you may not use this file except in compliance with the License.            
 * You may obtain a copy of the License at                                     
 *                                                                             
 *      http://www.apache.org/licenses/LICENSE-2.0                              
 *                                                                                
 * Unless required by applicable law or agreed to in writing, software           
 * distributed under the License is distributed on an "AS IS" BASIS,              
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
 * See the License for the specific language governing permissions and         
 * limitations under the License.                                                
 *                                                                                 
 * @@@ END COPYRIGHT @@@     
 */
var setRootNode = false;
var LOADING_SELECTOR = ".hpdsm-spinner";			
var st = null;
var resizeTimer = null;			
var ROUTE_FILTER="/queryplan/filter";
var formDialogContents;
var formStateView;			
var HPDSMDATATABLE = "#query-result-container";
var GRIDCONTAINER = "#hpdsm-1";
var ohpdsmTable = null;
var controlStatements = null;
var previousScrollTop = 0;
var controlDialog = null;
var controlStmts = "";

var deselectedButtonStyle = 
	{
		"color": "#007dba",
		"border": "2px solid #BFE5F5",
		"border-top-right-radius": "5px",
		"border-bottom-left-radius": "5px",
		"background-color": "#BFE5F5"
	};
var selectedButtonStyle = 
	{
		"background-color": "#0096d6",
		"border-color": "#0096d6",
		"color": "#fff"
	};
			
//Implement a node rendering function called 'nodeline' that plots a straight line
//when contracting or expanding a subtree.
$jit.ST.Plot.NodeTypes.implement({
	'nodeline': {
	  'render': function(node, canvas, animating) {
			if(animating === 'expand' || animating === 'contract') {
			  var pos = node.pos.getc(true), nconfig = this.node, data = node.data;
			  var width  = nconfig.width, height = nconfig.height;
			  var algnPos = this.getAlignedPos(pos, width, height);
			  var ctx = canvas.getCtx(), ort = this.config.orientation;
			  ctx.beginPath();
			  if(ort == 'left' || ort == 'right') {
				  ctx.moveTo(algnPos.x, algnPos.y + height / 2);
				  ctx.lineTo(algnPos.x + width, algnPos.y + height / 2);
			  } else {
				  ctx.moveTo(algnPos.x + width / 2, algnPos.y);
				  ctx.lineTo(algnPos.x + width / 2, algnPos.y + height);
			  }
			  ctx.stroke();
		  } 
	  }
	}
});

$( document ).ready(function() {
	init();
});

function showLoading(){
	$('#loadingImg').show();
};

function hideLoading() {
	$('#loadingImg').hide();
};
				
function drawExplain(jsonData) {
	hideLoading();
	$("#infovis").empty();

	//init Spacetree
	//Create a new ST instance
	st = new $jit.ST({
		'injectInto': 'infovis',
		orientation: "top",
		constrained: false,
		//set duration for the animation
		duration: 800,
		//set animation transition type
		transition: $jit.Trans.Quart.easeInOut,
		//set distance between node and its children
		levelDistance: 40,
		siblingOffset: 100,
		width: ($(GRIDCONTAINER).width()),
		height:($(GRIDCONTAINER).height()),
		//set max levels to show. Useful when used with
		//the request method for requesting trees of specific depth
		levelsToShow: 20,
		offsetX: -100,
		offsetY: 350,
		//set node and edge styles
		//set overridable=true for styling individual
		//nodes or edges
		Node: {
			height: 20,
			width: 40,
			//use a custom
			//node rendering function
			type: 'nodeline',
			color:'#23A4FF',
			lineWidth: 2,
			align:"center",
			overridable: true
		},
		Navigation: {  
			enable: true,  
			//panning: 'avoid nodes',
			panning: true,
			zooming: 20
		},
		Edge: {
			type: 'bezier',
			lineWidth: 2,
			color:'#23A4FF',
			overridable: true
		},
		Tips: {  
			enable: true,  
			type: 'auto',  
			offsetX: 20,  
			offsetY: 20,  
			onShow: function(tip, node) {  
			  tip.innerHTML = node.data.formattedCostDesc;  
			  tip.style.width = 450 + 'px';
			  tip.className = 'mytooltip';
			}  
		  },
		//Add a request method for requesting on-demand json trees. 
		//This method gets called when a node
		//is clicked and its subtree has a smaller depth
		//than the one specified by the levelsToShow parameter.
		//In that case a subtree is requested and is added to the dataset.
		//This method is asynchronous, so you can make an Ajax request for that
		//subtree and then handle it to the onComplete callback.
		//Here we just use a client-side tree generator (the getTree function).
		request: function(nodeId, level, onComplete) {
		  //var ans = getTree(nodeId, level);
		  //onComplete.onComplete(nodeId, ans);  
		},
		
		onBeforeCompute: function(node){
			//Log.write("loading " + node.name);
		},
		
		onAfterCompute: function(){
			//Log.write("done");
		},
		onComplete: function(){   

			if(!setRootNode){
			 var m = { 
						offsetX: st.canvas.translateOffsetX, 
						offsetY: st.canvas.translateOffsetY 
				};
			 st.onClick(st.root, { Move: m});
			 setRootNode = true;
			}	
		},
		
		//This method is called on DOM label creation.
		//Use this method to add event handlers and styles to
		//your node.
		onCreateLabel: function(label, node){
			var nodeName = node.name;
			nodeName = nodeName.replace("_", " ");
			nodeName = nodeName.replace("SEABASE","TRAFODION");
			nodeName = toProperCase(nodeName);
			
			var html = nodeName;
			switch(node.name)
			{
				case 'FILE_SCAN':
				case 'INDEX_SCAN':
				case 'FILE_SCAN_UNIQUE':
				case 'INDEX_SCAN_UNIQUE':
					html = "<img src='img/file_scan.gif' />" + nodeName;
					break;
				case 'PARTITION_ACCESS':
					html =  "<img src='img/partition_scan.gif' />" + nodeName;
					break;
				case 'HASH_GROUPBY':
					html =  "<img src='img/hash_groupby.png' />" + nodeName;
					break;
				case 'HASH_PARTIAL_GROUPBY_LEAF':
					nodeName = "Hash Groupby Leaf";
					html =  "<img src='img/hash_groupby.png' />" + nodeName;
					break;
				case 'HASH_PARTIAL_GROUPBY_ROOT':
					nodeName = "Hash Groupby Root";
					html =  "<img src='img/hash_groupby.png' />" + nodeName;
					break;
				case 'SHORTCUT_SCALAR_AGRR':
				case 'SORT_SCALAR_AGGR':
					nodeName = "Scalar Aggr";
					html =  "<img src='img/scalar_aggr.png' />" + nodeName;
					break;
				case 'SORT':
				case 'SORT_GROUPBY':
					html =  "<img src='img/sort_group_by.png' />" + nodeName;
					break;
				case 'SORT_PARTIAL_AGGR_LEAF':
					nodeName = "Sort Aggr Leaf";
					html =  "<img src='img/sort_group_by.png' />" + nodeName;
					break;
				case 'SORT_PARTIAL_AGGR_ROOT':
					nodeName = "Sort Aggr Root";
					html =  "<img src='img/sort_group_by.png' />" + nodeName;
					break;
				case 'SORT_PARTIAL_GROUPBY_LEAF':
					nodeName = "Sort Groupby Leaf";
					html =  "<img src='img/sort_group_by.png' />" + nodeName;
					break;
				case 'SORT_PARTIAL_GROUPBY_ROOT':
					nodeName = "Sort Groupby Root";
					html =  "<img src='img/sort_group_by.png' />" + nodeName;
					break;
				case 'INSERT':
				case 'INSERT_VSBB':
					html =  "<img src='img/insert.gif' />" + nodeName;
					break;
				case 'PROBE_CACHE':
					html =  "<img src='img/probe_cache.png' />" + nodeName;
					break;
				case 'HYBRID_HASH_ANTI_SEMI_JOIN':
				case 'HYBRID_HASH_JOIN':
				case 'HYBRID_HASH_SEMI_JOIN':
					nodeName = "Hash Join";
					html =  "<img src='img/hash_join.png' />"  + nodeName;
					break;
				case 'LEFT_HYBRID_HASH_JOIN':
				case 'LEFT_ORDERED_HASH_JOIN':
					nodeName = "Left Hash Join";
					html =  "<img src='img/hash_join.png' />"  + nodeName;
					break;
				case 'ORDERED_HASH_ANTI_SEMI_JOIN':
				case 'ORDERED_HASH_JOIN':
				case 'ORDERED_HASH_SEMI_JOIN':
					nodeName = "Hash Join";
					html =  "<img src='img/hash_join.png' />"  + nodeName;
					break;
				case 'TUPLE_FLOW':
					html =  "<img src='img/tuple_flow.png' />"  + nodeName;
					break;
				case 'LEFT_MERGE_JOIN':
				case 'MERGE_ANTI_SEMI_JOIN':
				case 'MERGE_JOIN':
				case 'MERGE_SEMI_JOIN':
					html =  "<img src='img/merge_join.gif' />"  + nodeName;
					break;									
				case 'NESTED_ANTI_SEMI_JOIN':
				case 'LEFT_NESTED_JOIN':
				case 'NESTED_JOIN':
				case 'NESTED_SEMI_JOIN':
					html =  "<img src='img/nested_join.png' />"  + nodeName;
					break;
				case 'MERGE_UNION':
					html =  "<img src='img/merge_union.gif' />" + nodeName;
					break;
				case 'ESP_EXCHANGE':
					html =  "<img src='img/esp_exchange.png' />" + nodeName;
					break;
				case 'SPLIT_TOP':
					html =  "<img src='img/split_top.gif' />" + nodeName;
					break;
				case 'HIVE_INSERT':
				case 'TRAFODION_':
				case 'TRAFODION_DELETE':
				case 'TRAFODION_INSERT':
					html =  "<img src='img/trafodion_insert.png' />" + nodeName;
					break;
				case 'HIVE_SCAN':
				case 'TRAFODION_SCAN':
				case 'SEABASE_SCAN':
					html =  "<img src='img/seabase_scan.gif' />" + nodeName;
					break;
				case 'ROOT':
					html =  "<img src='img/root.png'/> " + nodeName;
					break;
				default:
					html =  "<img src='img/undefined.gif' />" + nodeName;
				break;
			}
			label.id = node.id;            
			label.innerHTML = html;
			label.onclick = function(){
				 var m = { 
							offsetX: st.canvas.translateOffsetX, 
							offsetY: st.canvas.translateOffsetY 
					}; 
				 st.onClick(node.id, { Move: m }); 
			};
			//set label styles
			var style = label.style;
			style.width = 175 + 'px';
			style.height = 17 + 'px';            
			style.cursor = 'pointer';
			style.color = '#000';
			style.display = 'inline-table';
			//style.backgroundColor = '#1a1a1a';
			style.fontSize = '15px';
			style.fontWeight = 'bold';
			//style.textAlign= 'center';
			//style.textDecoration = 'underline';
			//style.paddingTop = '3px';
			style.paddingLeft = '3px';
		},
		
		//This method is called right before plotting
		//a node. It's useful for changing an individual node
		//style properties before plotting it.
		//The data properties prefixed with a dollar
		//sign will override the global node style properties.
		onBeforePlotNode: function(node){
			//add some color to the nodes in the path between the
			//root node and the selected node.
			if (node.selected) {
				node.data.$color = "#ff7";
			}
			else {
				delete node.data.$color;
			}
		},
		
		//This method is called right before plotting
		//an edge. It's useful for changing an individual edge
		//style properties before plotting it.
		//Edge data proprties prefixed with a dollar sign will
		//override the Edge global style properties.
		onBeforePlotLine: function(adj){
			if (adj.nodeFrom.selected && adj.nodeTo.selected) {
				adj.data.$color = "#eed";
				adj.data.$lineWidth = 3;
			}
			else {
				delete adj.data.$color;
				delete adj.data.$lineWidth;
			}
		}
	});
	//load json data
	st.loadJSON(jsonData);
	//compute node positions and layout
	st.compute();
	$("#infovis").show();
	//emulate a click on the root node.
	st.onClick(st.root);
	doResize();
	//end
};

function toProperCase(s) {
	return s.toLowerCase().replace(/^(.)|\s(.)/g, function($1) {
		return $1.toUpperCase();
	});
};
function init() {

	controlDialog = $("#dialog-form").dialog({
      autoOpen: false,
      height: 300,
      width: 500,
      modal: true,
      buttons: {
        "OK": function (){
			controlStmts = $("#controlStmts").val();
			if(controlStmts == null) {
				controlStmts = "";
			} else {
				controlStmts = controlStmts.replace(/(\r\n|\n|\r)/gm,"");
			}
			controlDialog.dialog( "close" );
		},
        Cancel: function() {
          controlDialog.dialog( "close" );
        }
      },
      close: function() {
        //form[ 0 ].reset();
        //allFields.removeClass( "ui-state-error" );
      }
    });
	
	hideLoading();
	//initFilterDialog();
	$("#explainQuery").on('click', explainQuery);
	$("#executeQuery").on('click', executeQuery);
	$("#setControlStmts").on('click', openFilterDialog);
	$("#infovis").show();
	$("#errorText").hide();
	
	
};
function onRelayout() {
	onResize();
};
function onResize() {
	clearTimeout(resizeTimer);
	resizeTimer = setTimeout(doResize, 200);
};
function doResize  () {
	if(st != null) {
		st.canvas.resize($('#infovis').width(), ($(GRIDCONTAINER).height() + $(GRIDCONTAINER).scrollTop() + 800));
	}
};

function openFilterDialog () {
	controlDialog.dialog( "open" );
};

function explainQuery() {
	showLoading();
	$("#infovis").hide();
	$("#errorText").hide();
	$("#query-result-container").hide();
	var queryText = $("#query-text").val();
	var param = {sQuery : queryText, sControlStmts: controlStmts};

	$.ajax({
	    url:'queryPlan.jsp',
	    type:'POST',
	    data: JSON.stringify(param),
	    dataType:"json",
	    contentType: "application/json;",
	    success:drawExplain,
	    error:function(jqXHR, res, error){
	    	hideLoading();
	    	showErrorMessage(jqXHR);
	    }
	});
    
};

function executeQuery() {
	showLoading();
	$("#infovis").hide();
	$("#errorText").hide();
	$("#query-result-container").show();
	var queryText = $("#query-text").val();
	var param = {sQuery : queryText, sControlStmts: controlStmts};
	
	$.ajax({
	    url:'executeQuery.jsp',
	    type:'POST',
	    data: JSON.stringify(param),
	    dataType:"json",
	    contentType: "application/json;",
	    success:displayResults,
	    error:function(jqXHR, res, error){
	    	hideLoading();
	    	showErrorMessage(jqXHR);
	    }
	});
};

function displayResults(result){
	hideLoading();
	var keys;
    $.each(result, function(i, data){
      keys = Object.keys(data);
	});
    
	if(keys != null && keys.length > 0) {
		var sb = '<table class="display1" id="query-results" style="font-size:small"><thead><tr>';
		for (var r=0,len=keys.length; r<len; r++) {
		  sb += '<th><b></b>' + keys[r] + '</th>';
		}
		sb += '</tr></thead><tbody> </tbody></table>';
		$('#query-result-container').html( sb );
		
		var aoColumns = [];
		var aaData = [];
		
		$.each(result, function(i, data){
		var rowData = [];
		  $.each(keys, function(k, v) {
			rowData.push(data[v]);
		  });
		  aaData.push(rowData);
		});

		// add needed columns
		$.each(keys, function(k, v) {
			obj = new Object();
			obj.sTitle = v;
			aoColumns.push(obj);
		});
		
		var bPaging = aaData.length > 25;
		
		 $('#query-results').dataTable({
			"bProcessing": true,
			"bJQueryUI": true,
			"bPaginate" : bPaging, 
			"iDisplayLength" : 25, 
			"sPaginationType": "full_numbers",
			"aaData": aaData, 
			"aoColumns" : aoColumns 
		 });
	 }

};

function showErrorMessage (jqXHR) {
	hideLoading();
	$("#infovis").hide();
	$("#query-result-container").hide();
	$("#errorText").show();
	if (jqXHR.responseText) {
		$("#errorText").text(jqXHR.responseText);
	}
};
//@ sourceURL=ExplainPlanView.js