/* global variables */
// tab id(s) from the permalink
var cur_tabs = [0];
// qmap tab id (can be set from data point capturing in tims)
var qmap_tab = 0;
// indicator of whether it is loading from permalink
var from_permalink = false;
// json saving info parsed from permalink
var iddb_saved = {};
var idmonTabView;

function create_permalink(){
  var mode = $("#menu .menu_items_highlight").attr("id");
  var activetab1, activetab2, activetab3;
  var pars = $("form:visible").serialize();
  var permalink;
  
  if(mode == "qsum"){
    activetab1 = eval("show_" + mode + "_reload.tabViews")[0].get("activeIndex");
    activetab2 = eval("show_" + mode + "_reload.tabViews")[1].get("activeIndex");
    activetab3 = eval("show_" + mode + "_reload.tabViews")[2].get("activeIndex");
    cur_tabs = [activetab1, activetab2, activetab3];
    permalink = "?tab1=" + activetab1 + "&tab2=" + activetab2
      + "&tab3=" + activetab3 + "&" + pars + "#" + mode;       
  }
  else{
    activetab1 = eval("show_" + mode + "_reload.tabView").get("activeIndex");
    cur_tabs = [activetab1];
    
    // in iddb mode, append idmonitor information in the permalink if shown
    if(mode == "iddb" && $("#idmonitorwin_c").css("visibility") == "visible"){
      iddb_id = $("#idmonitorwin").attr("data-id");
      iddb_type = $("#idmonitorwin").attr("data-type");
      iddb_tab = idmonTabView.get("activeIndex");
      pars = pars + "&iddb_id=" + iddb_id + "&iddb_type=" + iddb_type 
        + "&iddb_tab=" + iddb_tab;
    }
    permalink = "?tab=" + activetab1 + "&" + pars + "#" + mode;
  }
  console.log(permalink);
  history.replaceState(permalink, "", permalink); 
}

function parse_permalink(location){
  var search = location.search;
  var hash = location.hash;
  //console.log("search:", search);
  //console.log("hashtag:", hash);

  if(hash){
    var mode = hash.substring(1); //Puts hash in variable, and removes the # character
    console.log("mode:", mode);
    
    // set from_permalink
    from_permalink = true;   

    // parse url search string (following ? sign)
    if(search){
      var ctrl = search.substring(1).split("&");
      var key, value;
      var qc = [];
      cur_tabs = [];
      
      $.each(ctrl, function(){
        key = this.split("=")[0];
        value = this.split("=")[1];
        //console.log(key, value);   
        
        if(key.substring(0, 3) == "tab"){
          //eval("show_" + mode + "_reload.tabView").selectTab(value);
          cur_tabs.push(parseInt(value));
        }
        else if(value == "on"){  
          // if this is a checkbox
          $("input[name=" + key + "]").prop("checked", true);
        }
        else if(key.substring(0, 9) == "dateinput"){
          // if this is dateinput
          $("select[name=" + key + "]").val(value);
          if(key == "dateinput_year") fill_month();
          else if(key == "dateinput_month") fill_dayofmon();               
        }
        else if(key.substring(0, 4) == "iddb"){
          // if this is a iddb keyword, save to iddb_saved
          iddb_saved[key] = value;
        }
        else{
          $("input[name=" + key + "][value=" + value + "]:enabled").prop("checked", true);
        }
        
      });
    }   

    // correct dateinput
    month_day_change();
    
    // resume menu selection
    onMNClick(null, $(hash)[0], $("#menu")[0]);  
    
    // reset from_permalink
    //from_permalink = false;  
  }
  else{
    //from_permalink = false;
    cur_tabs = [0];
    onMNClick(null, $("#qmap")[0], $("#menu")[0]);      
  }  
}

function fileExists(url) {
//    if(url){
//        var req = new XMLHttpRequest();
//        req.open('HEAD', url, false);
//        req.send();
//        return req.status==200;
//    } else {
//        return false;
//    }
  var response = $.ajax({
    url: url, 
    type: "HEAD", 
    async: false
  }).status;
  
  return (response != "200") ? false : true;
}

function getParkey_date()
{
  var aggtime = $("#dayofmoninput input:checked").val();
  with(document.dateinput)
  {
  	var year = parseInt(dateinput_year.value,10);
  	var month = parseInt(dateinput_month.value,10);
  	
    if(aggtime == "monthly"){
      return year+"-"+(month>9?month:("0"+month));
    }else if(aggtime == "daily"){
      var day = parseInt(dateinput_day.value, 10);
      return year+"-"+(month>9?month:("0"+month))+"-"+(day>9?day:("0"+day));
	}
  }
}
function getParkey_dayofmon()
{
  var aggtime = $("#dayofmoninput input:checked").val();
  var day;
  
  with(document.dayofmoninput)
  {
		if(aggtime == "monthly"){
		  day = "";
		}
		else if(aggtime == "daily"){
			day = parseInt(dateinput_day.value, 10);
			day = (day>9?day:("0"+day))+".";
	  }
	  
	  return day ;
  }
}

function getParkey_qmref()
{
  var qmref = $("#qmrefinput input:checked").val();
  return '_'+qmref;
//    with(document.qmrefinput)
//	{
//		if( qmref[1].checked ) return '_qmcmc';
//		else return '_qmrey';
//	}
}

function getParkey(dispKey, iddb)
{
	//synthesize parameter hased key for indexing data file
	var parkey = [];
	var selected_parpanels = eval(dispKey+"_selps");
	for(var j=0; j<selected_parpanels.length; j++)
	{
		try //in case getParkey is not supported or it is tipPanels
		{
			if(selected_parpanels[j] == "dayofmon") // date have two functions, 
			{
				if(dispKey == "tims")
				{
				        with(document.dayofmoninput)
				        {
				          parkey[j] = $("#dayofmoninput input:checked").attr("data-value");
				        }
				}
				else
				{
			       		parkey[j] = eval("getParkey_"+selected_parpanels[j]+"()");
				}
			}
			else if(selected_parpanels[j] == "date") // date have two functions, 
			{
                with(document.dateinput)
                {
                    //apply date subdir
                    var year = parseInt(dateinput_year.value,10);
                    var month = parseInt(dateinput_month.value,10);
                    if (dispKey == "itim")
                    {
                        parkey[j] = year+"-"+(month>9?month:("0"+month));
                    }
                    else
                    {
		                parkey[j] = eval("getParkey_date()");
                    }
                }
			}
			else if(selected_parpanels[j] == "qmref") // date have two functions, 
			{
			       	parkey[j] = eval("getParkey_qmref()");
			}
		}
		catch(e)
		{
			continue;
		}
	}
	return parkey;
}


/*
plot xml into a highchart Chart
input:  xmlPath -- path to xml file
	chartContainer -- element to hold the chart flash
	tabContainer -- element to hold the toggle form, also can be a YUI tab to which toggle will be appended
output: the chart object genereated
*/
xml2highChart = function(xml, chartContainer, key, parkey, needUpdatePlatformVisibility){
  var chart = null;
  var disp=chartContainer.substring(0, 4);
  var highchart_id = chartContainer;
  var hcOptions = getHcOptions(disp, key, parkey, highchart_id);

  var tims_type = needUpdatePlatformVisibility? "platform" : "qc"

  // add tims type as an attribute to the DOM container
  $("#" + chartContainer).attr("data-type", tims_type);

  if(xml.content.length == 0)
  {
	  Dom.get(chartContainer).innerHTML = "No records found.";
	  return null;
  }

  hcOptions.series = xml.content;
  //hcOptions.data = xml.content;

  if(!hcOptions.yAxis.title)  hcOptions.yAxis.title = {text:null};
  hcOptions.yAxis.title.text = xml.ytitle;;

  if(!hcOptions.xAxis.title)  hcOptions.xAxis.title = {text:null};
  hcOptions.xAxis.title.text = xml.xtitle;;

  if (xml.type == 'tims')  //tims
  { 
    hcOptions.xAxis.title.type = 'datetime';

  }

  //console.log(xml.color);
  hcOptions.colors = xml.color;

  if(disp != "itim"){
    if(needUpdatePlatformVisibility)
    {
      $.extend(hcOptions.plotOptions.series, {
        events: {		  
	        legendItemClick: function () {
            var name = this.name.trim();
            HighchartPlatformVisibility[name] = !this.visible;
            updateHighchartPlatformVisibility(name);
            return false;	//suppress automatic toggle functionality
          }
        }
      });
    }
    else 
    {
	    $.extend(hcOptions.plotOptions.series, {
		    events: {
          legendItemClick: function () {
            var name = this.name.trim();        
            HighchartQCCheckVisibility[name] = !this.visible;
            updateHighchartQCCheckVisibility(name);
            return false;	//suppress automatic toggle functionality
          }
        }
      });
    }
  }
  
  // if x-axis bounds are specified
  if(xml.xbounds){
    hcOptions.xAxis.min = xml.xbounds[0];
    hcOptions.xAxis.max = xml.xbounds[1];
  }
  
  // if chart container is tsirErr_disp
//  if(chartContainer == "tsirErr_disp"){
//    hcOptions.tooltip.valueSuffix = '%';
//    hcOptions.yAxis.max = 100;
//    hcOptions.yAxis.min = 0;  
//  }

  //avoid undefined canvas size
  if( $('#'+chartContainer).width() == 0 )
  {
    if( $('#'+chartContainer).parent().width() == 0 )
    {
      $('#'+chartContainer).parent().width( $('#'+chartContainer).parent().parent().width() );
      }
    $('#'+chartContainer).width( $('#'+chartContainer).parent().width() );
  }

  $(function () { 
    // destroy existing chart and draw a new one
    //var old_chart = $('#'+chartContainer).highcharts();
    //console.log("old chart", $('#'+chartContainer).data("highchartsChart"), old_chart);
    //if(old_chart) old_chart.destroy();  
    $('#'+chartContainer).highcharts(hcOptions); 
    //console.log("new chart", $('#'+chartContainer).highcharts());   
  });
  
	chart = $('#'+chartContainer).highcharts();

  // added by xzhou and modified by kh, remember selected zoom 
//	if (typeof extreme_x_remember !== 'undefined' ){
//	   if (typeof extreme_x_remember[highchart_id] !== 'undefined' ){
    if(extreme_x_remember[highchart_id] && extreme_y_remember[highchart_id]){
	      chart.xAxis[0].setExtremes(extreme_x_remember[highchart_id].min, extreme_x_remember[highchart_id].max);
	      chart.yAxis[0].setExtremes(extreme_y_remember[highchart_id].min, extreme_y_remember[highchart_id].max);
	      if( !chart.resetZoomButton ) {
		          chart.showResetZoom();
	      }
	   }
//	}

	//add context text to buttons
	var hButtons = $('#'+chartContainer).find('.highcharts-button');
	$(hButtons[0]).find('title')[0].innerHTML  = "Print/Save";
	$(hButtons[1]).find('title')[0].innerHTML  = "All On/Off";

  if(disp != "itim"){
    var series_name, series_vis;  
    var visList = needUpdatePlatformVisibility? HighchartPlatformVisibility : HighchartQCCheckVisibility;
    //console.log(visList);
	  for(var i=0; i<chart.series.length; i++){
	    series_name = chart.series[i].name.trim();
	    series_vis = visList[series_name];
	    console.log(i, series_name, series_vis);
		  chart.series[i].setVisible(series_vis, true);
	  }  
	}
  return chart;
};


updateHighchartPlatformVisibility = function(name){	
  var ser_name;
	//update all platform-wise charts
	for(var i=0; i < Index_of_first_qc_tims; i++){
	  if(tims[i])
		  if(tims[i].chart){
		    for(var j=0; j < tims[i].chart.series.length; j++){
		      ser_name = tims[i].chart.series[j].name.trim();
		      if(ser_name == name)
		        tims[i].chart.series[j].setVisible(HighchartPlatformVisibility[name], true);
		    }
		  }
	}
	// update daily charts
	for(var i=0; i < HC_num_tims_daily; i++){	
		if(tims_daily[i])
		  if(tims_daily[i].chart){
		    for(var j=0; j < tims_daily[i].chart.series.length; j++){	
		      ser_name = tims_daily[i].chart.series[j].name.trim();		    	  
		      if(ser_name == name)
		        tims_daily[i].chart.series[j].setVisible(HighchartPlatformVisibility[name], true);
		    }	  
		  }	
	}
	// update 4 charts in qsum
	for(var i=3; i <= 3 + HC_num_qsum; i++){
	  if(qsum[i])
      if(qsum[i].chart){
		    for(var j=0; j < qsum[i].chart.series.length; j++){
		      ser_name = qsum[i].chart.series[j].name.trim();		    
		      if(ser_name == name)		          
            qsum[i].chart.series[j].setVisible(HighchartPlatformVisibility[name], true);
        }
      }
	}
};


updateHighchartQCCheckVisibility = function(name)
{
	//update all QCCheck-wise charts
	for(var i=Index_of_first_qc_tims; i<tims.length; i++){
	  if(tims[i])
		  if(tims[i].chart){
		    for(var j=0; j < tims[i].chart.series.length; j++){
		      ser_name = tims[i].chart.series[j].name.trim();		    
		      if(ser_name == name)
		        tims[i].chart.series[j].setVisible(HighchartQCCheckVisibility[name], true);
		    }
		  }
  }
};

/*
plot xml into a dataTable
input:  xmlPath -- path to xml file
	dataTableContainer -- element to hold the dataTable
output: the dataTable object genereated
*/
xml2dataTable = function(xmlPath, dataTableContainer)
{
	var xml = xmlread(xmlPath)
	var dataSource = new YAHOO.util.DataSource(xml.xmlDoc);
	dataSource.responseType = YAHOO.util.DataSource.TYPE_XML;
	dataSource.useXPath = true;
	
	var myFields = new Array(xml.tags.length);
	for(var i=0; i<xml.tags.length; i++)
	{
		myFields[i] = {key:xml.tags[i].key, parser:xml.tags[i].type.toLowerCase()};
	}
	dataSource.responseSchema = {
		resultNode: "ENTRY",
		fields: myFields
		};
	
	var myColumnDefs = new Array(xml.tags.length);
	for(var i=0; i<xml.tags.length; i++)
	{
		if(xml.tags[i].sort)
		{
			var defaultDir = (xml.tags[i].sort.toLowerCase() == 'desc')?YAHOO.widget.DataTable.CLASS_DESC:YAHOO.widget.DataTable.CLASS_ASC;
			myColumnDefs[i] = {key:xml.tags[i].key, formatter:xml.tags[i].type.toLowerCase(), sortable:true, sortOptions:{defaultDir:defaultDir}, label:xml.tags[i].label};
		}
		else
		{
			myColumnDefs[i] = {key:xml.tags[i].key, formatter:xml.tags[i].type.toLowerCase(), sortable:false, label:xml.tags[i].label};
		}
	}
	console.log(dataSource)
	var dt = new YAHOO.widget.DataTable(dataTableContainer, myColumnDefs, dataSource, {scrollable:true});
//	dt.subscribe("columnSortEvent",function(){loadbar.hide();});
//	dt.doBeforeSortColumn = function(){loadbar.show();alert('1');return true;};
	dt.set("renderLoopSize", 100);
	dt.set("MSG_LOADING","Processing...");
	return dt;
};

// global variable to record the ordering of IDDB table, DATA table, and LOG table
var ORDER_IDDB;
var ORDER_DATA = [[0, "desc"]];
var ORDER_LOG = [[0, "desc"]];

/*
plot xml into a jQuery dataTable
input:  xmlPath -- path to xml file
	dataTableContainer -- element to hold the dataTable
output: the dataTable object genereated
*/
xml2jqDataTable = function(xml, dataTableContainer,table_type)
{
  //console.log(xml)	
	if(!xml.data || xml.data.length < 1)
	{
		Dom.get(dataTableContainer).innerHTML = "No records found.";
		return null;
  }

  var dt;

  if(table_type == 'nobs')
  {
  isIDDB = false;
  isLOG = false;  
  columns_all = [ 
          {"title":xml.columns[0], "width": "11.%" },
		  {"title":xml.columns[1], "width": " 9.%" ,render: $.fn.dataTable.render.number( ',' ) },
		  {"title":xml.columns[2], "width": "11.5%" ,render: $.fn.dataTable.render.number( ',' ) },
		  {"title":xml.columns[3], "width": "11.5%" ,render: $.fn.dataTable.render.number( ',' ) },
		  {"title":xml.columns[4], "width": "11.5%" ,render: $.fn.dataTable.render.number( ',' ) },
		  {"title":xml.columns[5], "width": "11.5%" ,render: $.fn.dataTable.render.number( ',' ) },
		  {"title":xml.columns[6], "width": "11.5%" ,render: $.fn.dataTable.render.number( ',' ) },
		  {"title":xml.columns[7], "width": "11.5%" ,render: $.fn.dataTable.render.number( ',' ) }
		]
  }
  else if(table_type == 'nobs_norm')
  {
  isIDDB = false;
  isLOG = false;  
  columns_all = [ 
          {"title":xml.columns[0], "width": "11.%" },
		  {"title":xml.columns[1], "width": " 9.%" ,render: $.fn.dataTable.render.number( ',' ) },
		  {"title":xml.columns[2], "width": "11.5%" ,render: $.fn.dataTable.render.number( ',' ) },
		  {"title":xml.columns[3], "width": "11.5%" ,render: $.fn.dataTable.render.number( ',','.',2) },
		  {"title":xml.columns[4], "width": "11.5%" ,render: $.fn.dataTable.render.number( ',','.',2) },
		  {"title":xml.columns[5], "width": "11.5%" ,render: $.fn.dataTable.render.number( ',','.',2) },
		  {"title":xml.columns[6], "width": "11.5%" ,render: $.fn.dataTable.render.number( ',','.',2) },
		  {"title":xml.columns[7], "width": "11.5%" ,render: $.fn.dataTable.render.number( ',','.',2) }
		]
  }
  else if(table_type == 'stat')
  {
  isIDDB = false;  
  isLOG = false;  
  columns_all = [ {"title":xml.columns[0], "width": "10%"  },
		  {"title":xml.columns[1], "width": "10%" ,render: $.fn.dataTable.render.number(',') },      //( thousands, decimal, precision, prefix )
		  {"title":xml.columns[2], "width": "7%"  ,render: $.fn.dataTable.render.number(',','.',2) },
		  {"title":xml.columns[3], "width": "7%"  ,render: $.fn.dataTable.render.number(',','.',2) },
		  {"title":xml.columns[4], "width": "7%"  ,render: $.fn.dataTable.render.number(',','.',2) },
		  {"title":xml.columns[5], "width": "7%"  ,render: $.fn.dataTable.render.number(',','.',2) },
		  {"title":xml.columns[6], "width": "7%"  ,render: $.fn.dataTable.render.number(',','.',2) },
		  {"title":xml.columns[7], "width": "7%"  ,render: $.fn.dataTable.render.number(',','.',2) },
		  {"title":xml.columns[8], "width": "7%"  ,render: $.fn.dataTable.render.number(',','.',2) },
		  {"title":xml.columns[9], "width": "7%"  ,render: $.fn.dataTable.render.number(',','.',2) }
                ]
  }
  else if(table_type == 'iddb')
  {
  isIDDB = true; 
  isLOG = true;  
  //console.log(xml)
  columns_all = [ 
                  {"title":xml.columns[0], "width": "12.5%"  },  //time
                  {"title":xml.columns[1], "width": "9.5%", render: $.fn.dataTable.render.number(',','.',3) },  //lat
                  {"title":xml.columns[2], "width": "9.5%", render: $.fn.dataTable.render.number(',','.',3) },  //lon
                  {"title":xml.columns[3], "width": "11.0%", },  // agency
                  {"title":xml.columns[4], "width": "11.0%", },  // receiver
                  {"title":xml.columns[5], "width": "9.0%", },  // gnss
                  {"title":xml.columns[6], "width": "12.%", render: $.fn.dataTable.render.number(',') },  // n_levels
                  {"title":xml.columns[7], "width": "12.%", render: $.fn.dataTable.render.number(',','.',3) },  //alt_min
                  {"title":xml.columns[8], "width": "12.%", render: $.fn.dataTable.render.number(',','.',3) }   //alt_max
		]
  }
  else if(table_type == 'data')
  {
  isIDDB = false;
  isLOG = true;
  var ftp_path = "ftp://ftp.star.nesdis.noaa.gov/pub/sod/sst/iquam/v2.10/";  
  columns_all = [ {"title":xml.columns[0], 
                   "width": "70%" ,
                   "sClass": "datatablecenter granule-name",
                   "render": function(data, type, row, meta){
                               return "<a href='" + ftp_path + data + "'>"
                               + data + "</a>";
                             }
                  },                   
                  {"title":xml.columns[1], "width": "30%" ,"sClass": "datatablecenter"},
//                  {"title":xml.columns[2], "width": "34%" ,"sClass": "datatablecenter"  }
              ]
  }
  else if(table_type == 'log')
  {
  isIDDB = false;
  isLOG = true;
  columns_all = [ {"title":xml.columns[0], "width": "50%" ,"sClass": "datatablecenter"  },
                  {"title":xml.columns[1], "width": "15%" ,"sClass": "datatablecenter"  },
                  {"title":xml.columns[2], "width": "5%"  ,"sClass": "datatablecenter"  },
                  {"title":xml.columns[3], "width": "30%" ,"sClass": "datatablecenter"  }
              ]
  }
	
  $(document).ready(function() {
    $('#'+dataTableContainer).html( '<table cellpadding="0" cellspacing="0" border="0" class="display compact cell-border hover" id="'+dataTableContainer+'_holder"></table>' );
    
    var tableHeight = undefined; 
    var order = undefined;
    var dom = 'lfrtip'; //default
    
    if(isIDDB){
      tableHeight = $("#row2leftcol").height() - 100;
      order = ORDER_IDDB;
      dom = 'iftp'; // reposition DOM object as - info, filter, table, pagination (hiden)
    }
    else if(isLOG){
      tableHeight = 660;
      order = (table_type == "data") ? ORDER_DATA : ORDER_LOG;
    }
    
    // initialize dataTable [KH]
    dt = $('#'+dataTableContainer+'_holder').dataTable( {
      data: xml.data,
      columns:columns_all,
      "searching": isIDDB,
      "bInfo": isLOG,
      "bLengthChange": false,
      "ordering": isLOG,
      "order":  order,
      "paging": isLOG,
      //lengthMenu: [[100, 200, -1], [100, 200, "All"]],
      //"scrollX": isIDDB,
      scrollY: tableHeight, // matched with left panel at 628 
      scroller: isLOG,
      deferRender: isLOG,
      "dom": dom,
//      initComplete: function(){
//        $("#iddb_disp table a").click(function(){
//          if($("#idmonitorwin_c").css("visibility") == "visible" &&
//             $("#idmonitorwin").attr("data-id") == $(this).attr("data-id") &&
//             $("#idmonitorwin").attr("data-type") == $(this).attr("data-type")
//            ){
//            // do nothing
//          }
//          else{
//            //idMonitor($(this).attr("data-id"), $(this).attr("data-type"));          
//            console.log("Added class");
//          }
//        });      
//      }
    });

    // bind "order/sort" event listeners to table objects; pass the current order to a global variable ORDER_X [KH]
    if(isIDDB){
      dt.on("order.dt", function(e){
        ORDER_IDDB = $(e.target).DataTable().order();
        //console.log(ORDER_IDDB);
      });   
    }
    else if(isLOG){ 
      if(table_type == "data"){ // data table
        dt.on("order.dt", function(e){
          ORDER_DATA = $(e.target).DataTable().order();
          //console.log(ORDER_IDDB);
        })
      }
      else{ // log table
        dt.on("order.dt", function(e){
          ORDER_LOG = $(e.target).DataTable().order();
          //console.log(ORDER_IDDB);
        })                  
      }
    }
  });

  return dt;
};

show_tims = function()
{
	//synthesize parkey form parpanel input
	var newParkey = getParkey("tims");
	console.log(newParkey)

	if(show_tims.parkey && (show_tims.parkey.toString() == newParkey.toString() || (show_tims.parkey.length == 0 && newParkey.length == 0))){
		create_permalink();
  
    // reset from_permalink
    from_permalink = false; 		
		return;
	}
	show_tims.parkey = newParkey;

	loadbar.show();
	show_tims_reload();
}


function show_tims_reload()
{
	//var activeIndex = 0;
	var tabView;
	var activeIndex = from_permalink ? cur_tabs[0] : 0;	
  var aggtime = $("#dayofmoninput input:checked").val();
  
  function make_tims_plot(tabview, tims){
    var tabid = tabview.get("activeIndex");
    var key = tims[tabid].key;
    var filename;
    var pars = $("form:visible").serialize();
    var last_pars = tabview.pars[tabid];
    var isPlatform = tabid < Index_of_first_qc_tims ? true : false;
        
    // for mean/med, sd/rsd, min/max
    if(key == "mean" || key == "medn" || key == "minv" || key == "maxv" || key == "stdv" || key == "rstd"){
      filename = "data/tims/tims_" + key +show_tims.parkey[1] + show_tims.parkey[0] + ".json";
    }
    else{ // for all others
      filename = "data/tims/tims_" + key +show_tims.parkey[1] + show_tims.parkey[0] + ".json";
    }
    console.log(tabid, key, filename, last_pars);

    // only if the pars [parameters] has changed should we re-download and re-render
    if(pars != last_pars){    
    loadbar.show();
    $.getJSON(filename, function(data) {
		  tims[tabid].chart = xml2highChart(data[0], "tims_" + key + "_tv", key, show_tims.parkey, isPlatform); 		  
		})
	  .fail(function(){ 
      Dom.get("tims_"+key+"_tv").innerHTML = "No records found."; 
    })
    .always(function(){
	    tabview.pars[tabid] = pars;    
		  show_tims_reload.tabView = tabview;
		  loadbar.hide();
    	create_permalink();	
    	  
      // reset from_permalink
      from_permalink = false; 		
		});
		} 
		else{
		  // update permalink even though plot need not be reloaded
		  create_permalink(); 		
		}// end of if 
  }  
	//monthly
	if(aggtime == "monthly"){

	if(show_tims_reload.tabView)
	{
		//clear existing elements and remember active tab index
		if(show_tims_reload.aggregation == 'monthly')
		{
     	activeIndex = show_tims_reload.tabView.get("activeIndex");
		}
		else if(show_tims_reload.aggregation == 'daily')
		{
   	  last_activeIndex = show_tims_reload.tabView.get("activeIndex");
			activeIndex = last_activeIndex * 2;
		}

		//remove flash object before remove tab to avoid error
		for(var j=0; j< tims.length; j++)
		{
			var el=Dom.get("tims_"+tims[j].key+"_tv")
			while(el && el.hasChildNodes())	el.removeChild(el.lastChild);
		}
		var el = Dom.get("tims_disp");
		while(el.hasChildNodes())	el.removeChild(el.lastChild);
		//to do: probably need to collect discarded objects
	}

  tabView = new YAHOO.widget.TabView();
  tabView.pars = new Array(tims.length);
	for(var j=0; j<tims.length; j++)
	{
		tabView.addTab( new YAHOO.widget.Tab({
				label: tims[j].label,
				content: '<div class="chart" id="tims_'+tims[j].key+'_tv" ></div><table id="tims_'+tims[j].key+'_tf"></table>',
				active: j == activeIndex }));
	}
	tabView.appendTo('tims_disp');
  $("#tims_disp ul.yui-nav li:eq(10)").css("visibility","hidden")
  tabView.addListener("activeTabChange", function(){
    make_tims_plot(this, tims);
  });
  
  // initiate plot if it is a fresh load
	make_tims_plot(tabView, tims);

	}  // monthly end
	else if(aggtime == "daily") //daily
	{ 
	if(show_tims_reload.tabView)
	{
		//clear existing elements and remember active tab index
		if(show_tims_reload.aggregation == 'daily')
		{
		       	activeIndex = show_tims_reload.tabView.get("activeIndex");
		}
		else if(show_tims_reload.aggregation == 'monthly')
		{
		       	last_activeIndex = show_tims_reload.tabView.get("activeIndex");
			if(last_activeIndex == 0) 
			{activeIndex = 0;}
			else if (last_activeIndex == 2)
			{activeIndex = 1;}
			else if (last_activeIndex == 4)
			{activeIndex = 2;}
			else if (last_activeIndex == 6)
			{activeIndex = 3;}
		}

		//remove flash object before remove tab to avoid error
		for(var j=0; j< tims_daily.length; j++)
		{
			var el=Dom.get("tims_"+tims_daily[j].key+"_tv")
			while(el && el.hasChildNodes())	el.removeChild(el.lastChild);
		}
		var el = Dom.get("tims_disp");
		while(el.hasChildNodes())	el.removeChild(el.lastChild);
		//to do: probably need to collect discarded objects
	}

	tabView = new YAHOO.widget.TabView();
  tabView.pars = new Array(tims_daily.length);	
	for(var j=0; j<tims_daily.length; j++)
	{
		//console.log('33333333333');
		tabView.addTab( new YAHOO.widget.Tab({
				label: tims_daily[j].label,
				content: '<div class="chart" id="tims_'+tims_daily[j].key+'_tv"></div><table id="tims_'+tims_daily[j].key+'_tf"></table>',
				active: j == activeIndex }));
	}
	tabView.appendTo('tims_disp');
	make_tims_plot(tabView, tims_daily);

  tabView.addListener("activeTabChange", function(){
    make_tims_plot(this, tims_daily);
  });	

	} // daily
	
	// store aggtime
  show_tims_reload.aggregation = aggtime;  
}

show_qmap = function()
{
  //synthesize parkey form parpanel input
  var newParkey = getParkey("qmap");

  //if no changes when back from other selps (qsum, itim, iddb), then do not reload
	if(show_qmap.parkey && (show_qmap.parkey.toString() == newParkey.toString() || (show_qmap.parkey.length == 0 && newParkey.length == 0))){
  	create_permalink();
    	  
    // reset from_permalink
    from_permalink = false; 
    return;
  }

  loadbar.show();
	
  show_qmap.parkey = newParkey;
  show_qmap_reload();
}

function show_qmap_reload()
{
  //var activeIndex = 0;
  var active_found = 0;
  var activeIndex = from_permalink ? cur_tabs[0] : qmap_tab;
  if(show_qmap_reload.tabView)
  {
  	//clear existing elements and remember active tab index
  	activeIndex = show_qmap_reload.tabView.get("activeIndex");
  	var el = Dom.get("qmap_disp");
  	while(el.hasChildNodes())	el.removeChild(el.lastChild);
  }
	
  var tabView = new YAHOO.widget.TabView();
  var min_tab;
  for(var j=0; j<qmap.length; j++)
  {
    exist_id=fileExists("data/"+show_qmap.parkey[0]+"/qmap/"+show_qmap.parkey[0]+"_"+qmap[j].key+".gif")
    //exist_id = true;
    if(exist_id == false) {
      if(active_found == 0){
        if(from_permalink == false){
          activeIndex++;
        }
      }
      continue;
    }
    else {

    active_found = 1
  	var imgText = '<img src="data/'+show_qmap.parkey[0]+"/qmap/"+show_qmap.parkey[0]+'_'+qmap[j].key+'.gif" onerror="this.src=';
  	imgText += "'../framework/images/noresult.gif'";
  	imgText += '"/>';
    console.log('qmap[j].key: ', qmap[j].key);

  	tabView.addTab( new YAHOO.widget.Tab({
  			label: qmap[j].label,
  			content: '<div class="yui-content" id="qmap_'+qmap[j].key+'_tv" style="overflow:auto">'+imgText+'</div>',
  			active: j == activeIndex }));
    }
  }
  tabView.appendTo('qmap_disp');
  tabView.addListener("activeTabChange", create_permalink);
  //tabView.selectTab(cur_tabs[0]);
	
  loadbar.hide();
  show_qmap_reload.tabView = tabView;
  create_permalink();	  
	
  // reset from_permalink
  from_permalink = false; 
}


show_qsum = function()
{
  //synthesize parkey form parpanel input
  var newParkey = getParkey("qsum");
	
  if(show_qsum.parkey && (show_qsum.parkey.toString() == newParkey.toString() || (show_qsum.parkey.length == 0 && newParkey.length == 0))){
    create_permalink();
  
    // reset from_permalink
    from_permalink = false; 	  
  	return;
  }

  loadbar.show();

  //setTimeout("show_qsum_reload()", 0);
  show_qsum.parkey = newParkey;
  show_qsum_reload();
}


function show_qsum_reload()
{
  var noTab = 3;
  var activeIndex = from_permalink ? cur_tabs : [0, 0, 0];
  function make_qsum_plot(tabview, qsum){
    var tabid = tabview.get("activeIndex"); // id as within the tabView
    var tabid2 = tabid + tabview.offset;    // id as across all tabViews
    var key = qsum[tabid2].key;
    var filename;
    var pars = $("form:visible").serialize();
    var last_pars = tabview.pars[tabid];
    var table_keyword = ["nobs", "nobs_norm", "stat"]; // key word needed for xml2jqDataTable
    
    //console.log(tabid, tabview.tvid, tabview.offset, tabid2);
    // only if the pars [parameters] has changed should we re-download and re-render    
    if(pars != last_pars){
    if(tabview.tvid <= 1){
      if(tabview.tvid == 0)
        filename = "data/"+show_qsum.parkey[0]+"/qsum/"+show_qsum.parkey[0]+"_"+key+".json"; 
      else
        filename = "data/"+show_qsum.parkey[0]+"/qsum/"+show_qsum.parkey[0]+"_"+key+show_qsum.parkey[2]+".json";
      //console.log(tabid2, filename);
      
	    $.getJSON(filename, function(data){
		    qsum[tabid2].dataTable = xml2jqDataTable(data[0], "qsum_"+key+"_tv", table_keyword[tabid2]); 
	    })
		  .fail(function(){ 
		    Dom.get("qsum_"+key+"_tv").innerHTML = "No records found.";
		  })
		  .always(function(){
        // share height between the table in the first tabView (pass height of qsum[0/1] to the other one)		  
        if(tabview.tvid == 0){
          var act_qsum = qsum[activeIndex[0]].key;
          var inact_qsum = qsum[1 - activeIndex[0]].key;
          var qsum_height = $("#qsum_" + act_qsum + "_tv").height();
          
          console.log(act_qsum, inact_qsum, qsum_height);
          $("#qsum_" + inact_qsum + "_tv").height(qsum_height);
        }		  
		    tabview.pars[tabid] = pars;
        show_qsum_reload.tabViews[tabview.tvid] = tabview;
      	create_permalink();	  
        // reset from_permalink
        from_permalink = false; 
	    });
    }
    else{
      if(tabid >= 2)
        filename = "data/"+show_qsum.parkey[0]+"/qsum/"+show_qsum.parkey[0]+"_"+key+show_qsum.parkey[2]+".json";
      else
        filename = "data/"+show_qsum.parkey[0]+"/qsum/"+show_qsum.parkey[0]+"_"+key+".json"; // hourly timeseries

      //console.log(tabid2, filename);
            
      $.getJSON(filename, function(data) {
		    qsum[tabid2].chart= xml2highChart(data[0], "qsum_" + key + "_tv", key, getParkey_date(), true); 		    
		  })
	    .fail(function(){ 
        Dom.get("qsum_"+key+"_tv").innerHTML = "No records found."; 
      })
		  .always(function(){
        loadbar.hide();
		    tabview.pars[tabid] = pars;        
        show_qsum_reload.tabViews[tabview.tvid] = tabview;
      	create_permalink();	  
        // reset from_permalink
        from_permalink = false; 
	    });
	  } 
	  }// end of if
		else{
		  // update permalink even though plot need not be reloaded
		  create_permalink(); 		
		}// end of if 	  
  }  

	if(show_qsum_reload.tabViews)
	{
		//clear existing elements and remember active tab index
		for(var j=0; j<noTab; j++)	activeIndex[j] = show_qsum_reload.tabViews[j].get("activeIndex");
		//remove flash object before remove tab to avoid error
		for(var j=0; j<qsum.length; j++)
		{
			var el=Dom.get("qsum_"+qsum[j].key+"_tv")
			while(el && el.hasChildNodes())	el.removeChild(el.lastChild);
		}
		var el = Dom.get("qsum_disp");
		while(el.hasChildNodes())	el.removeChild(el.lastChild);
		//to do: probably need to collect discarded objects
	}
	
    console.log('xxxxxxxxxxxxxxxxx')
  var tabViews = [];
  var offsets = [0, 2, 3];  // tabid offset for each tabView
  var tabNums = [2, 1, HC_num_qsum];  // tab1 has 2 tabs, tab2 has 1, tab3 has 4
	for(var jj=0; jj<noTab; jj++)
	{
		tabViews[jj] = new YAHOO.widget.TabView();
		tabViews[jj].pars = new Array(tabNums[jj]);
		for(var j=0; j<tabNums[jj]; j++)
		{
			var j2 = offsets[jj]+j;
			//if(j2 == 3) continue;
			tabViews[jj].addTab( new YAHOO.widget.Tab({
					label: qsum[j2].label,
					content: '<div class="'+(jj==2?'chart':'yui-content')+'" id="qsum_'+qsum[j2].key+'_tv" '+(jj==2?'style="height:300px;"':'')+'></div>',
					active: j == activeIndex[jj] }));
		}
		tabViews[jj].tvid = jj;
		tabViews[jj].offset = offsets[jj];
		tabViews[jj].appendTo('qsum_disp');
		tabViews[jj].addListener("activeTabChange", function(){
		  make_qsum_plot(this, qsum);
		});
		
		// initial plots
  	make_qsum_plot(tabViews[jj], qsum);			
	}
	show_qsum_reload.tabViews = tabViews;
	
  // width adjustment (fill the width for qsum0 and qsum1, others at a certain ratio)
  console.log($("#dispanel").width());
  $("#qsum_"+qsum[0].key+"_tv").width($("#dispanel").width() * 0.72); 
  $("#qsum_"+qsum[1].key+"_tv").width($("#dispanel").width() * 0.72); 
  $("#qsum_"+qsum[2].key+"_tv").width($("#dispanel").width() - 3); 
  $("#qsum_"+qsum[3].key+"_tv").width($("#dispanel").width()); 

}

show_iddb = function()
{
	//synthesize parkey form parpanel input
	var newParkey = getParkey("iddb");

	if(show_iddb.parkey && (show_iddb.parkey.toString() == newParkey.toString() || (show_iddb.parkey.length == 0 && newParkey.length == 0))){
		create_permalink();  
    // reset from_permalink
    from_permalink = false; 
		return;
  }

	loadbar.show();

	show_iddb.parkey = newParkey;
	show_iddb_reload();
}


function show_iddb_reload()
{
  var activeIndex = 0;
  //var sortedKeys = new Array(iddb.length);
  function make_iddb_table(tabview, iddb){
    var tabid = tabview.get("activeIndex");
    var iddbid = tabview.exist_iddb[tabid];
    console.log(tabid, iddbid);
    //var filename = "data/" + show_iddb.parkey[0] + show_iddb.parkey[1] + "_" + iddb[iddbid].key + show_iddb.parkey[2] + ".json";
    var filename = "data/" + show_iddb.parkey[0] +"/iddb/"+show_iddb.parkey[0]+ "_" + iddb[iddbid].key + show_iddb.parkey[2] + ".json";
    var pars = $("form:visible").serialize();
    var last_pars = tabview.pars[iddbid];

    console.log(iddbid, filename);
    console.log(iddbid, last_pars);
    
    // only if the pars [parameters] has changed should we re-download and re-render
    if(pars != last_pars){
    loadbar.show();
    $.getJSON(filename, function(data) { 
      iddb[0].dataTable = xml2jqDataTable(data[0], "iddb_"+iddb[iddbid].key+"_tv", 'iddb'); 
    }) 
	  .always(function(){
	    tabview.pars[iddbid] = pars;
	    show_iddb_reload.tabView = tabview;
	    loadbar.hide();

      //console.log("iddb partial failed");
      // when switching table, reorder based on the latest ordering
      $("#iddb_disp_deletable ul.yui-nav li").click(function(){
        var idx = $(this).index(); // get the index among available platform types (the ?th tab); zero based [KH]
        
        var table_name = $("#iddb_disp .yui-content>div:eq(" + iddbid + ")>div").attr("id");
        var table_obj = $("#" + table_name + "_holder").DataTable();
        var table_prev_order = $("#" + table_name + "_holder").dataTable().fnSettings().aLastSort[0];
        
        // if ordering is set, and is different from the current settings (either col id or direction) 
        // redorder the active table and redraw [KH]
        if(ORDER_IDDB && table_prev_order){ 
          if(ORDER_IDDB[0][0] != table_prev_order.col || ORDER_IDDB[0][1] != table_prev_order.dir)      
            table_obj.order(ORDER_IDDB).draw();
        }
      });
           
      setTimeout(function(){    
        // when from_permalink is true resume the proper idmonitor
        if(from_permalink && !$.isEmptyObject(iddb_saved)){
          idMonitor(iddb_saved["iddb_id"], iddb_saved["iddb_type"]);
          idmonTabView.selectTab(parseInt(iddb_saved["iddb_tab"]));
          
          // highlight properly
          $("a[data-id=" + iddb_saved["iddb_id"] + "]").addClass("pressed")
          .closest("tr").addClass("highlight");
        }
        
        // if idmonitor is already displaying
        if($("#idmonitorwin_c").css("visibility") == "visible"){
          // highlight properly
          $("a[data-id=" + iddb_saved["iddb_id"] + "]").addClass("pressed")
          .closest("tr").addClass("highlight");
        }            

        // turn idmonitor floating window partially transparent when scrolling [KH] */
        $("div.dataTables_scrollBody").scroll(function(){      
          //console.log("scroll");
          $("#idmonitorwin:not('.active')").css("opacity", 0.2);
          clearTimeout( $.data( this, "scrollCheck" ) );
          $.data( this, "scrollCheck", setTimeout(function() {
          	$("#idmonitorwin").css("opacity", 1);
            //console.log("scroll stop");
          }, 500) );  
        }); 
      
		    create_permalink();  
        // reset from_permalink
        from_permalink = false; 	
      }, 500);  // defer by 500ms for the table to be drawn		      
	  }); 
	  } 
		else{
		  // update permalink even though plot need not be reloaded
		  create_permalink(); 		
		}// end of if 
  }  
	
  if(show_iddb_reload.tabView)
  {
		//clear existing elements and remember active tab index
		activeIndex = show_iddb_reload.tabView.get("activeIndex");
		
		//remember sorting columns
		//for(var j=0; j<iddb.length; j++)
		//{
		//	sortedKeys[j] = iddb[j].dataTable.get("sortedBy");
		//}

		//remove flash object before remove tab to avoid error
		for(var j=0; j<iddb.length; j++)
		{
			var el=Dom.get("iddb_"+iddb[j].key+"_tv")
			while(el && el.hasChildNodes())	el.removeChild(el.lastChild);
		}
		var el = Dom.get("iddb_disp_deletable");
		while(el.hasChildNodes()){
		  el.removeChild(el.lastChild);
		}
		if(document.getElementById("idmonitorwin_c").style.visibility == 'visible' ){ 		
			idMonitor(id_current, iddb_key_current);
		}
	}
	
	var valid_type = [];
	var exist_iddb = [];  // an array recording the type id of each "existing" tab
	var first_valid = true;
	//--- tabView
	var tabView = new YAHOO.widget.TabView();
	tabView.pars = new Array(iddb.length);
	for(var j=0; j<iddb.length; j++)
	//for(var j=0; j<1; j++)
	{
    //exist_id=fileExists("data/"+show_iddb.parkey[0]+show_iddb.parkey[1]+"_"+iddb[j].key+show_iddb.parkey[2]+".json")
    exist_id=fileExists("data/"+show_iddb.parkey[0]+"/iddb/"+show_iddb.parkey[0]+"_"+iddb[j].key+show_iddb.parkey[2]+".json")
    //exist_id = true;
		if(exist_id == false) 
		{
			continue;
		}
		else {
			valid_type.push(iddb[j].key);
			exist_iddb.push(j);
			if(first_valid == true) 
			{
				activeIndex = j;
				first_valid = false;
			}
			if(show_iddb_reload.valid_type && show_iddb_reload.valid_type[show_iddb_reload.tabView.get("activeIndex")] == iddb[j].key) 
			{
				activeIndex = j
			}
		}
		
		tabView.addTab( new YAHOO.widget.Tab({
				label: iddb[j].label,
				content: '<div id="iddb_'+iddb[j].key+'_tv"></div>',
				active: j == activeIndex
		}));
	}
	show_iddb_reload.valid_type = valid_type;
	tabView.exist_iddb = exist_iddb;
	tabView.appendTo('iddb_disp_deletable');
	tabView.addListener("activeTabChange", function(){
	  make_iddb_table(this, iddb);
	});	

	if(valid_type.length != 0){
	  // data exists
	  if(from_permalink){
	    tabView.selectTab(cur_tabs[0]);
	  }
	  else{
  	  // initiate the table   
	    make_iddb_table(tabView, iddb);
	  }
	}
  else{
    // no data presented, end the loading animation and show nothing
    show_iddb_reload.tabView = tabView;
    loadbar.hide();    
  }
  
  $("#iddb_disp .yui-content>div>div").width($("#dispanel").width() - 3);  
	
  // initial id monitor
  idmonTabView = new YAHOO.widget.TabView("idmonitorwin");
  idmonTabView.addListener("activeTabChange", create_permalink);	 
}

// part of show_iddb_reload(), but need to be bind on a document
// level to apply to all current and future DOM elements (<a> in iddb tables)
$(document).on("click", "#iddb_disp table a", function(){
  idMonitor($(this).attr("data-id"), $(this).attr("data-type"));
  create_permalink();

  $(this).addClass("pressed");
  var dt = $("#iddb_disp_deletable .yui-content>div:not('.yui-hidden') table").DataTable();
  var all_dt = $("#iddb_disp_deletable .yui-content table");
  var cur_tr = dt.row($(this).closest("tr")).index();
  
  //console.log(cur_tr);
  // highlight properly
  all_dt.each(function(){ 
    var t = $(this).DataTable(); 
    $(t.rows().nodes()).removeClass("highlight");
  })
  $(dt.row(cur_tr).nodes()).addClass("highlight");      
});

// turn idmonitor floating window partially transparet when mouse hovers over it [KH]
var hideMonitor;
$(document).on({
  mousedown: function(){ // mouse down
    //console.log("mouse down");
    hideMonitor = setTimeout(function(){
    $("#idmonitorwin:not('.paused')").css("opacity", 0.2);
    }, 200);  // only when holding mouse click for more than 200ms
  },
  mouseup: function(){ // mouse up
    //console.log("mouse up");
    if(hideMonitor){
      clearTimeout(hideMonitor);
    }
    $("#idmonitorwin").css("opacity", 1);
  },
  // attach a "active" class to idmonitorwin when mouse is over it.
  // so that when the unexpected "scroll" event does not accidentally turn it transparent  
  // [KH]
  mouseenter: function(){ // mouse up
    //console.log("mouse enter");
    $("#idmonitorwin").addClass("active");
  },  
  mouseleave: function(){ // mouse leaves
    //console.log("mouse leave");  
    $("#idmonitorwin").css("opacity", 1);
    $("#idmonitorwin").removeClass("active");    
  }  
}, "#idmonitorwin");

// exception to the hold-to-hide behavior when the highchart plot ("#tsir_disp") is shown in idmonitor
$(document).on({
  mouseenter: function(){ // mouse up
    //console.log("mouse enter");
    $("#idmonitorwin").addClass("paused");
  },  
  mouseleave: function(){ // mouse leaves
    //console.log("mouse leave");  
    $("#idmonitorwin").removeClass("paused");    
  }  
}, ".iddb_chart");
