// reports.js
// Javascript to display report web pages.
// Called from reports.html
// usage...
// reports.html?FN=datatype&BA=showbasins&YE=year&ME=month&DE=day&HE=hour-minute-second
// or
// reports.html?FN=datatype&BA=showbasins&TE=year-month-day-hour-minute-second
// where:
// datatype is the type of data to display on the report (e.g. rain)
//  If the data type is not provided, the default data type is read from
//  reports.xml as //defaults/report/type
// showbasins is "yes" to display site data by basin.
//            is "no" to display site data without basins.
//  If showbasins is not provided, the default is read from
//  reports.xml as //defaults/showbasins
// YE,ME,DE,HE and TE define a historic date and time for data display
//  If they are not provided, the current data is displayed.

// Set page location and XSL file name
var strPathname = strRoot + "reports.html";
var strXSLname = strRoot + strXSLfolder + "reports.xsl";
var strPageTitle = "Data Reports";

// Define search command arguments
var strShowBasins;
var strDataType;
var strTimeArg,strTimeDisplay,strYear,strMonth,strDay,strHour,strMinute,strSecond;

// Set default select and sort parameters
var strSortSelect;
var strSortDataType;
var strSortOrder;
var strSortSelectDefault = "@nosort";
var strSortDataTypeDefault = "number";
var strSortOrderDefault = "ascending";

// Parameters set by report selection
var strTitle;
var bTitleDisplayed = false;
var timeout_id;
var nReloadMilliseconds = 0;

// XML data sets
var objXMLdata = null;
var objXMLsitedata = null;
var objXMLsites = null;
var objXMLreports = null;
var objXMLintervals = null;
var objXSLreports = null;

// Set report data type selected from list
function changeReportDataType()
{
  // Get report data type index to display, return if index is 0
  var objSelect = document.all['selectReportType'];
  nIndex = objSelect.selectedIndex;

  // Set report data type to display from list value
  strDataType = objSelect.options[nIndex].value;

  // Save the data type in a cookie
  set_cookie("DataType", strDataType);

  // Redisplay the title and data without reloading XML data
  displayReport(true,false);
  return;
}

// Set basin sort select sites in basins
function sortBasins()
{
  // Get basin display selection, return if index is 0
  var objSelect = document.all['selectBasins'];
  nIndex = objSelect.selectedIndex;

  // Set basin display from list value
  strShowBasins = objSelect.options[nIndex].value;

  // Save the data type in a cookie
  set_cookie("ShowBasins", strShowBasins);

  // Redisplay the data only without reloading 
  displayReport(false,false);
  return;
}

// Reverse sort order from ascending to descending
function reverseSortOrder()
{
  if(strSortOrder == "ascending")
    strSortOrder = "descending";
  else
    strSortOrder = "ascending";
}

// Set sort selection, reverse sort order if same sort,
// set sort data type, then transform report
function sortReport(sortSelect, sortDataType)
{
  // Clear timer
  clearTimeout(timeout_id);

  // If already using sorting selection then reverse sort order
  if(strSortSelect == sortSelect)
    reverseSortOrder();
  // Otherwise set sort selection
  else
    strSortSelect = sortSelect;

  // Set sort data type
  strSortDataType = sortDataType;

  // Save the sort parameters in cookies
  set_cookie("SortSelect", escape(strSortSelect));
  set_cookie("SortDataType", escape(strSortDataType));
  set_cookie("SortOrder", escape(strSortOrder));
  
  // Redisplay the data only without reloading 
  displayReport(false,false);
}

// Load the XSL document for the report display
function loadXSLreports()
{
  objXSLreports = loadDOMDocument(strXSLname,true);
}

// Load the XML documents for the report display
function loadXMLreports()
{
  var strQuery;
  var objNode;

  // Load XML sites document
  if(objXMLsites) delete objXMLsites;
  objXMLsites = loadDOMDocument(getXMLPathName(strXMLsitesName),true);

  // Load XML reports document
  if(objXMLreports) delete objXMLreports;
  objXMLreports = loadDOMDocument(getXMLPathName(strXMLreportsName),true);

  // Load XML intervals document
  if(objXMLintervals) delete objXMLintervals;
  objXMLintervals = loadDOMDocument(getXMLPathName(strXMLintervalsName),true);

  // Get the report default data type if not defined
  if ( strDataType == "" )
  {
    strQuery = "/reports/defaults/datatype";
    objNode = objXMLreports.selectSingleNode(strQuery);
    if ( objNode ) strDataType = objNode.text;
  }

  // Get the report default show basins if not defined
  if ( strShowBasins == "" )
  {
    strQuery = "/reports/defaults/showbasins";
    objNode = objXMLreports.selectSingleNode(strQuery);
    if ( objNode ) strShowBasins = objNode.text;
  }

  // Get the reports tooltip and status
  strQuery = "//defaults/tooltip";
  load_tooltip(objXMLreports,strQuery);

  // Get the report reload interval if defined
  strQuery = "/reports/@reload";
  objNode = objXMLreports.selectSingleNode(strQuery);
  if ( objNode != null )
    nReloadMilliseconds = objNode.text * 1000;
}

// Merge XML documents for data type
function makeXMLreportnodes()
{
  var objNode;
  var strQuery;

  // Create a new working document
  if(objXMLdata != null)
    delete objXMLdata;
  objXMLdata = newDOMDocument();

  // Copy the sites XML document to the working document
  objXMLsites.save(objXMLdata);

  // Create a report node in the XML document
  var objReportNode = objXMLdata.documentElement.appendChild(objXMLdata.createNode("element","report",""));

  // Get the report default data type if not defined
  if ( strDataType == "" )
  {
    strQuery = "/reports/defaults/datatype";
    objNode = objXMLreports.selectSingleNode(strQuery);
    if ( objNode ) strDataType = objNode.text;
  }

  // Get the report default show basins if not defined
  if ( strShowBasins == "" )
  {
    strQuery = "/reports/defaults/showbasins";
    objNode = objXMLreports.selectSingleNode(strQuery);
    if ( objNode ) strShowBasins = objNode.text;
  }

  // Make the report data type query
  var strQueryDataType = "/reports/datatypes/datatype[@type = '" + strDataType + "']";

  // Get the report title for the report data type selected
  strQuery = strQueryDataType + "/title/name";
  objNode = objXMLreports.selectSingleNode(strQuery);
  if ( objNode != null ) strTitle = objNode.text;

  // Append the report data type intervals to report node
  strQuery = strQueryDataType + "/interval";
  objNode = objXMLreports.selectSingleNode(strQuery);
  if ( objNode )
  {
    strIntervalType = objNode.text;
    strQuery = "/datatypeintervals/intervals[@type = '" + strIntervalType + "']";
    objNodeList = objXMLintervals.selectNodes(strQuery);
    appendDocumentNodeList(objReportNode,objNodeList);
  }

  // Set data type attribute in report node
  objReportNode.setAttribute("type",strDataType);

  // Set showbasins attribute in report node
  objReportNode.setAttribute("showbasins",strShowBasins);

  // Append site data date and time to report node
  var strDateTime = "";
  strQuery = "/sitedata/@datetime";
  objNode = objXMLsitedata.selectSingleNode(strQuery);
  if ( objNode != null ) strDateTime = objNode.text;
  objReportNode.setAttribute("datetime",strDateTime);

  // Set time arguments in report node
  objReportNode.setAttribute("historictime",strTimeArg);

  // Append the reports document to the working document
  // This allows the report specific document defaults to be found first
  objNodeList = objXMLreports.selectNodes("/reports");
  appendDocumentNodeList(objXMLdata.documentElement,objNodeList);

  // Merge site data into sites XML document
  mergeSiteData(objXMLdata,objXMLsitedata);

  // Return XML object on success
  return objXMLdata;
}

// Load the XML data document and append nodes for report display selections
// strDataType: report data type (rain, level, battery, ...)
// strShowBasins: yes print basin names, no does not print)
// strSortSelect: XML node value selection for sort
// strSortDataType: (number or text)
// strSortOrder: (ascending or descending)
function loadXMLdata(strXMLPathName)
{
  // Load XML data document
  // If error, may be that data set for time period not created.
  var objXML = loadDOMDocument(strXMLPathName,true);
  if ( objXML == null )
  {
    if(strTimeDisplay)
       alert("The data set for:\n"+strTimeDisplay+"\ndoes not exist!");
    else
      alert("Unable to load data file:\n " + strXMLPathName);
    return null;
  }

  // Return XML object on success
  return objXML;
}

// Transform and display the report data using the XSL file
// Arguments: objXML - XML DOM Document for data and report
//            objDisplay - XML Node to select type of display
//             is set to "data" to display report data
function transformData(objXML,objDisplay,strDisplay,strHtmlID)
{
  // Return if the XSL document is not loaded
  if ( objXSLreports == null ) return false;

  // Get the XSL sort objects and set the sort select, data-type, and order
  if ( strDisplay == "data" )
  {
    var objSort = objXSLreports.selectNodes("//xsl:sort");
    objNode = objSort.nextNode;
    while ( objNode )
    {
      objNode.setAttribute("select",strSortSelect);
      objNode.setAttribute("data-type",strSortDataType);
      objNode.setAttribute("order",strSortOrder);
      objNode = objSort.nextNode;
    }
  }

  // Set the display attribute
  objDisplay.setAttribute("display",strDisplay);

  // Replace the DisplayData object with the XML transformation
  var objHtml = document.all[strHtmlID];
  objHtml.innerHTML = objXML.transformNode(objXSLreports);

  // Return display success
  return true;
}

// Transform and display the report
// Argument bDisplayTitle:
//    true displays the title and data
//    false displays the data only
// Argument bReloadData:
//    true reads the XML data files
//    false uses the XML data files already loaded
function displayReport(bDisplayTitle,bReloadData)
{
  // Hide tooltip if active
  hide_tooltip();

  // Reload data if flag set
  if( bReloadData == true || objXMLsitedata == null )
  {
    // Construct the XML data document historic path name 
    // if the time argument is set
    var strXMLPathName;
    if ( strTimeDisplay != "" )
      strXMLPathName = getHistoricXMLDataFileName(strYear, strMonth, strDay, strHour, strMinute, strSecond);

    // Otherwise use the current data file path name
    else
      strXMLPathName = getCurrentXMLDataFileName();

    // Remove previous XML data object
    if ( objXMLsitedata != null )
      delete objXMLsitedata;

    // Load the XML data document
    objXMLsitedata = loadXMLdata(strXMLPathName);
  }

  // Display report if data available
  if ( objXMLsitedata != null )
  {
    // Set report node elements
    var objXML;
    objXML = makeXMLreportnodes();

    // Get the report node that defines what is displayed
    var strQuery = "/*/report";
    var objDisplay = objXML.selectSingleNode(strQuery);

    // Display the title once
    if ( bDisplayTitle == true )
    {
      // Set the window title
      document.title = strSystemTitle + " " + strTitle;

      // Display the report title
      bTitleDisplayed = transformData(objXML,objDisplay,'title','DisplayTitle');
    }

    // Always display report data
    transformData(objXML,objDisplay,'data','DisplayData');
  }

  // Check for active alarms
  checkAlarms();

  // Start data reload timer
  startReloadTimer();
  return true;
}

// Set reload timer
function startReloadTimer()
{
  // Set data reload timer if current data displayed
  if ( strTimeDisplay == "" && nReloadMilliseconds > 0 )
    timeout_id = setTimeout("reloadData()", nReloadMilliseconds);
  return true;
}

// Reload the data on the page
function reloadData()
{
  // Display title if not done yet
  if ( bTitleDisplayed == false )
    displayReport(true,true);
  else
    displayReport(false,true);
  clearStatus();
}

// Read parameters from cookies if not defined
function readParametersFromCookies()
{
  // Get the data type from cookie, set default if not defined
  if ( strDataType == "" ) strDataType = get_cookie("DataType");
  if ( strDataType == null ) strDataType = "";

  // Get the show basins from cookie, set default if not defined
  if ( strShowBasins == "" ) strShowBasins = get_cookie("ShowBasins");
  if ( strShowBasins == null ) strShowBasins = "";

  // Get the sort parameters from cookies
  // Set to default if not defined
  strSortSelect = get_cookie("SortSelect");
  if ( strSortSelect == null )
    strSortSelect = strSortSelectDefault;
  strSortDataType = get_cookie("SortDataType");
  if ( strSortDataType != "number" && strSortDataType != "text" )
    strSortDataType = strSortDataTypeDefault;
  strSortOrder = get_cookie("SortOrder");
  if ( strSortOrder != "ascending" && strSortOrder != "descending" )
    strSortOrder = strSortOrderDefault;
}

// Reset report parameters
function resetParameters()
{
  delete_cookie("DataType"); strDataType = "";
  delete_cookie("ShowBasins"); strShowBasins = "";
  delete_cookie("SortSelect"); strSortSelect = strSortSelectDefault;
  delete_cookie("SortDataType"); strSortDataType = strSortDataTypeDefault;
  delete_cookie("SortOrder"); strSortOrder = strSortOrderDefault;
  displayReport(true,false);
  clearStatus();
}

// This function is called when the HTML page is loaded.
// Get the search command arguments and display table.
function preparePage()
{
  // Initialize command arguments
  strDataType = "";
  strShowBasins = "";
  strTimeArg = "";
  strTimeDisplay = "";
  strYear = "";
  strMonth = "";
  strDay = "";
  strHour = "";
  strMinute = "";
  strSecond = "";

  // Set default page reload timer
  nReloadMilliseconds = ((nReloadMinutes * 60) + nReloadSeconds) * 1000;

  // Check for command arguments
  bReload = false;
  if ( location.search.length != 0)
  {
    args = location.search.substring(1);
    var args_array = args.split("&");
    for ( var cnt=0; cnt<args_array.length; cnt++)
    {
      var arg = args_array[cnt];
      var arg_array = arg.split("=");
      if(arg_array.length == 2 && arg_array[1].length > 0)
      {
        // Translate escape characters in the string argument
        strArg = arg_array[1];
        strArg = unescape(strArg);

        // Check for report data type selection
        if(arg_array[0] == "FN")
        {
          strDataType = strArg;
          set_cookie("DataType", strDataType);
          bReload = true;
        }

        // Check for basin display selection
        if(arg_array[0] == "BA")
        {
          strShowBasins = strArg;
          set_cookie("ShowBasins", strShowBasins);
          bReload = true;
        }

        // Check for time of report selection
        if(arg_array[0] == "TE")
        {
          strYear = getDateTimeYear(strArg);
          strMonth = getDateTimeMonth(strArg);
          strDay = getDateTimeDay(strArg);
          strHour = getDateTimeHour(strArg);
          strMinute = getDateTimeMinute(strArg);
          strSecond = getDateTimeSecond(strArg);
        }
        if(arg_array[0] == "YE")
          strYear = strArg;
        if(arg_array[0] == "ME")
          strMonth = strArg;
        if(arg_array[0] == "DE")
          strDay = strArg;
        if(arg_array[0] == "HE")
        {
          strHour = getTimeHour(strArg);
          strMinute = getTimeMinute(strArg);
          strSecond = getTimeSecond(strArg);
        }
      }
    }

    // Set data file path if time of report selected
    if ( strYear != "" )
    {
      endDate = new Date(strYear,eval(strMonth)-1,strDay,strHour,strMinute,strSecond);
      strTimeArg = makeDateTimeArg(endDate);
      strTimeDisplay = makeDateTimeDisplay(endDate);
    }
  }

  // Reload the page without command arguments
  // This allows return from link to use cookies
  // to set report display parameters
  if ( bReload == true )
  {
    action = strPathname;
    if ( strTimeArg != "" )
      action += "?TE=" + strTimeArg;
    location.replace(action);
  }

  // Create cross browser array
  create_object_array();

  // "Define" event for older browsers
  if (!dhtml_ok) event = null;

  // Read parameters from cookies if not defined
  readParametersFromCookies();

  // Load XML documents
  loadXMLreports();
  loadXSLreports();

  // Display the table
  displayReport(true,true);

  // Clear the status line
  clearStatus();
}
