/**
 *  object to control one or more WATTableView objects as e.g. fill tables with data from an XML
 *  structure that has been received for an AJAX request
 *
 *  @author   Tobias Hettinger
 *  @version  $Id: tablecontrol.js,v 1.9 2008/01/14 10:59:07 tobias Exp $
 */
 
 
/**
 *  constructor
 */
var WATTableControl = function(name)
{
  //  set the member variables
  this.name = name;
  this.tableViews = new Array();
}


//=====================================================================================================================
//  user interface
//=====================================================================================================================

/**
 *  function to add the passed WATTableView object to the internal list of table views
 */
WATTableControl.prototype.AddTableView = function(name, watTableView, ajaxHandler, modulePrefix)
{
  //  create the table view entry
  var tableView = new Array();
  tableView['tableView'] = watTableView;
  tableView['ajaxHandler'] = ajaxHandler;
  tableView['modulePrefix'] = modulePrefix;

  //  add the passed table view to the table view array of the table control
  this.tableViews[name] = tableView;
}

/**
 *  function to get the ajax handler for the table with the passed name
 *
 *  @param string name  name of the table
 *
 *  @return string  the function returns the ajax handler for the selected table or null
 *                  if the ajax handler is not available
 */
WATTableControl.prototype.GetAjaxHandler = function(name)
{
  if (this.tableViews[name]) return this.tableViews[name]['ajaxHandler'];
    else return null;
}

/**
 *  function to get the module prefix for the table with the passed name
 *
 *  @param string name  name of the table
 *
 *  @return string  the function returns the module prefix for the selected table or null
 *                  if no module prefix is available
 */
WATTableControl.prototype.GetModulePrefix = function(name)
{
  if (this.tableViews[name]) return this.tableViews[name]['modulePrefix'];
    else return null;
}

/**
 *  structure of the expected XML
 *
 *  <t   :=> select a new table
 *    n="[name of the table in the TableControl class (the one that has been passed in the AttTableView function]">
 *
 *    <cl />   :=> clear the selected table (including the data structure)
 *    <st />   :=> (re)show the table
 *    <sr />   :=> (re)show the rows (without refreshing the columns)
 *    <sort c="[name of the column to sort or NULL if the current sort column should be used]"
 *          d="[1 for 'desc' or 0 for 'asc'] />
 *
 *    <cs>   :=> block of column definitions
 *      <c   :=> definition of a single column
 *         n="[name of the column, required]"   :=> name of the column
 *         s="[1/0, 0 if not defined]"          :=> 1 if the column is sortable
 *         fi="[1/0, 0 if not defined]">        :=> 1 if a filter input should be shown
 *
 *      [caption of the column]
 *
 *      </c>
 *    </cs>
 *
 *    <r k="[key of the row (e.g. the row id in the database)]">   :=> a single row definition
 *      <f n="[name of the field which corresponds to the name of its column]">
 *        <v t="[s/n  :=> data type of the value whereas the data type of the sortable value overwrites this data type]">
 *          [value to show]</v>   :=> if the value tag is not sent, the value is set to 'null'
 *        <s t="[s/n  :=> data type of the value]">
 *          [sortable value]</s>  :=> if the value contains e.g. HTML or a date string, the sortable value
 *                                    can be sent to provide the possibility to sort the value even if the
 *                                    value itself can not be easily sorted. If this value is not sent, the
 *                                    value itself is sorted
 *      </f>
 *    </r>
 *
 *  </t>
 */
WATTableControl.prototype.ParseXML = function(xml, suppressErrors)
{
  //  get the response or error elements
  var node = xml.firstChild;
  while(node)
  {
    switch(node.nodeName)
    {
      //  data has been sent
      case 't' :
        //  get the name of the table and load the selected TableView object
        var tableName = node.getAttribute('n');
        if (tableName && this.tableViews[tableName]['tableView'])
        {
          //  get the selected table view
          var tableView = this.tableViews[tableName]['tableView'];
      
          //  parse the table data
          var table = node.firstChild;
          while(table)
          {
            switch(table.nodeName)
            {
              //  a clear table signal has been sent
              case 'cl' :
                //  clear the table and the underlying data structure
                tableView.ClearTable();
                break;
                
              //  (re)show the table
              case 'st' :
                //  show the table
                tableView.ShowTable();
                break;
                
              //  sort the table
              case 'sort' :
                //  get the parameters
                var columnName = table.getAttribute('c') ? table.getAttribute('c') : tableView.sortColumnName;
                var desc = table.getAttribute('d') ? (table.getAttribute('d') == 1 ? true : false) : tableView.sortDesc;
                tableView.Sort(columnName, desc);
                break;
          
              //  a set of columns was sent
              case 'cs' :
                //  parse the columns
                var column = table.firstChild;
                while(column)
                {
                  switch(column.nodeName)
                  {
                    //  a column definition was sent 
                    case 'c' :
                      //  get the column attributes
                      var columnName = column.getAttribute('n');
                      //  the column name is required
                      if (columnName)
                      {
                        //  get the optional attributes
                        var sortable = column.getAttribute('s');
                        var filterInput = column.getAttribute('fi');   
                        
                        //  create the caption
                        var caption = (column.firstChild) ? column.firstChild.data : columnName;
                        caption = caption.replace(/§!!§/g, '\"');
                        caption = caption.replace(/§!§/g, '\'');  
                        caption = caption.replace(/§!-/g, '<');
                        caption = caption.replace(/-!§/g, '>');   
                        caption = caption.replace(/§!and!§/g, '&');
                      
                        //  create a new column object
                        var tableColumn = new WATTableColumn(caption,
                                                            (sortable && sortable == '1') ? true : false,
                                                            (filterInput && filterInput == '1') ? true : false);
                        //  add the column to the table
                        tableView.AddColumn(columnName, tableColumn);
                      }
                      break;
                  }
              
                  //  try to parse the next column
                  column = column.nextSibling;
                }
                break;
              
              //  a row was sent
              case 'r' :
                //  initialize the row
                var cells = new Array();
                var row = table.firstChild;
                
                //  get the row attributes
                var key = table.getAttribute('key');
                var replace = table.getAttribute('r') ? true : false;
                var autoSelect = table.getAttribute('as') ? true : false;
                var href = table.getAttribute('href');
                if (href)
                {
                  href = href.replace(/§!!§/g, '\"');
                  href = href.replace(/§!§/g, '\'');  
                  href = href.replace(/§!-/g, '<');
                  href = href.replace(/-!§/g, '>');   
                  href = href.replace(/§!and!§/g, '&');
                }
                
                //  parse the row
                while(row)
                {
                  switch(row.nodeName)
                  {
                    //  a field definition has been sent
                    case 'f' :
                      //  get the name of the field (required attribute)
                      var fieldName = row.getAttribute('n');
                      if (fieldName)
                      {
                        //  get the field data
                        var fieldValue = null;
                        var valueDataType = 's';
                        var sortableValue = null;
                        var sortableDataType = 's';
                        var field = row.firstChild;
                        while(field)
                        {                        
                          switch(field.nodeName)
                          {
                            //  the value of the field has been sent
                            case 'v' :
                              //  get the attributes
                              valueDataType = field.getAttribute('t');
                              //  get the data
                              if (field.firstChild) fieldValue = field.firstChild.data;
                              break;
                              
                            //  a sortable value has been sent
                            case 's' :
                              //  get the attributes
                              sortableDataType = field.getAttribute('t');
                              //  get the data
                              if (field.firstChild) sortableValue = field.firstChild.data;
                              break;
                          }
                    
                          //  get the next part of the field definition
                          field = field.nextSibling;
                        }

                        //  add the cell to the current row
                        var cell = new WATTableCell(fieldValue);
                        
                        //  set additional data
                        if (sortableValue)
                        {
                          //  set the sortable value
                          cell.sortableValue = sortableValue;
                          cell.sortDataType = sortableDataType;
                        }
                        else
                        {
                          //  there is no sortable value, modify the data type if it has been sent
                          cell.sortDataType = valueDataType;
                        }
                        
                        //  add the cell to the row
                        cells[fieldName] = cell;
                      }
                      break;
                  }
                
                  //  get the next field
                  row = row.nextSibling;
                }
              
                //  the row has been completely parsed, check if the row should be replaced
                if (key && replace)
                {
                  //  search the existing row
                  for (var i in tableView.rows)
                    if (tableView.rows[i].key == key)
                    {
                      var tableRow = tableView.rows[i];
                      tableRow.href = href;
                      tableRow.cells = cells;
                      tableView.__UpdateCells(tableRow);
                    }
                }
                
                //  insert the item if it can not be replaced
                if (!replace)
                {
                  //  add the data to the table view
                  var tableRow = new WATTableRow(cells);
                  tableRow.key = key;
                  tableRow.href = href;
                  tableView.AddRow(tableRow);
                }
                
                //  select the row if the auto select flag is set
                if (autoSelect && tableRow) tableView.SelectRow(tableRow);
                break;
            }
          
            //  get the next part of the table
            table = table.nextSibling;
          }
        }
        break;
        
      //  an error was sent
      case 'error' :
        //  show an error message if errors should not be suppressed
        if (!suppressErrors)
        {
          //  show the error message
          var message = node.getElementsByTagName('message');
          if (message && message.item(0)) alert(message.item(0).firstChild.data);
        }
        break;
    }
    
    //  get the next node
    node = node.nextSibling;
  }
}
