/**
 * @fileoverview Plugin for southprojects Grid to input grid data from HTML source.
 *
 * <pre>
 * Copyright (c) 2006 by SouthProjects
 * http://www.southprojects.com
 * Santiago, Chile,
 * Version 1.2 Dec 2006.
 * All rights reserved.
 * </pre>
 */

/* $Id: spgrid-html.js 4761 2006-10-13 18:27:46Z alex $ */

/**
 * Loads data from HTML table source. Utilizes custom "style" attributes.
 *
 * @private
 * @param {object} oSource Input HTMLElement object
 */
southprojects.Grid.prototype.loadDataHtml = function(oSource) {
  var oTable = null;
  if (oSource) {
    oTable = oSource;
  } else if (this.container) {
    oTable = southprojects.Utils.getFirstChild(this.container, 'table');
  }
  if (!oTable) {
    alert("southprojects.Grid invalid configuration: Can't find source table");
    return;
  }
  // If there is thead element, header will be taken from it
  var oThead = southprojects.Utils.getFirstChild(oTable, 'thead');
  // Get tbody elements
  var oTbodies = oTable.getElementsByTagName('tbody');
  if (!oTbodies || !oTbodies.length) {
    oTbodies = [oTable];
  }
  var oHeaderTr = southprojects.Utils.getFirstChild(oThead || oTbodies[0], 'tr');
  if (!oHeaderTr) {
    alert("southprojects.Grid invalid configuration: Can't find header for table");
    return;
  }
  // Remove old data
  this.data = this.newDataHtml(oTable, oHeaderTr);
  this.fields = this.data.fields;
  this.rows = this.data.rows;
  this.rowsIndex = [];
  // Go to first page
  this.currentPage = 0;
  // Create fields
  var oTableCell = southprojects.Utils.getFirstChild(oHeaderTr, 'th', 'td');
  while (oTableCell) {
    // Add field
    this.fields.push(this.newFieldHtml(oTableCell));
    // Next field
    oTableCell = southprojects.Utils.getNextSibling(oTableCell, 'th', 'td');
  }
  // Create rows
  for (var iTbody = 0; iTbody < oTbodies.length; iTbody++) {
    // Get tr elements
    var oTrs = oTbodies[iTbody].getElementsByTagName('tr');
    var iTr = 0;
    // Skip header
    if (iTbody == 0 && !oThead) {
      iTr++;
    }
    for (; iTr < oTrs.length; iTr++) {
      // Create row
      var oRow = this.newRowHtml(oTrs[iTr]);
      // Add row
      this.rows.push(oRow);
      this.rowsIndex.push(oRow);
    }
  }
  // Show grid
  this.show();
};

/**
 * Creates new data object from HTML source.
 *
 * @private
 * @param {object} oTable Table element
 * @param {object} oHeaderTr First table row element in the table
 * @return Data object
 * @type object
 */
southprojects.Grid.prototype.newDataHtml = function(oTable, oHeaderTr) {
  // Create data object
  var oData = {
    fields: [],
    rows: []
  };
  // Set style
  var sStyle = southprojects.Widget.getStyle(oTable);
  if (sStyle) {
    oData.style = sStyle;
  }
  var sHeaderStyle = southprojects.Widget.getStyle(oHeaderTr);
  if (sHeaderStyle) {
    oData.headerStyle = sHeaderStyle;
  }
  return oData;
};

/**
 * Creates new field object from HTML table cell element.
 *
 * @private
 * @param {object} oTableCell Table cell element
 * @return Field object
 * @type object
 */
southprojects.Grid.prototype.newFieldHtml = function(oTableCell) {
  // Create field object
  var oField = {
    i: this.fields.length,
    title: oTableCell.innerHTML
  };
  // Set data type
  if (this.getTypeByClass) {
    oField.dataType = this.getTypeByClass(oTableCell.className);
  }
  // Set width
  var sWidth = oTableCell.getAttribute('width');
  if (sWidth) {
    sWidth += ''; // Convert to string
    if (sWidth.length) {
      oField.columnWidth = sWidth;
    }
  }
  // Set style
  var sStyle = southprojects.Widget.getStyle(oTableCell);
  if (sStyle) {
    oField.style = sStyle;
  }
  // Set span
  var sSpan = oTableCell.getAttribute('span');
  if (sSpan) {
    oField.span = sSpan * 1;
  }
  var sSpanTitle = oTableCell.getAttribute('spanTitle');
  if (sSpanTitle) {
    oField.spanTitle = sSpanTitle;
  }
  var sSpanStyle = oTableCell.getAttribute('spanStyle');
  if (sSpanStyle) {
    oField.spanStyle = sSpanStyle;
  }
  // Set hidden
  var bHidden = (oTableCell.className.indexOf('spgridTypeHidden') >= 0);
  if (bHidden) {
    oField.hidden = bHidden;
  }
  // Set nosort
  var bNosort = (oTableCell.className.indexOf('spgridTypeNosort') >= 0);
  if (bNosort) {
    oField.nosort = bNosort;
  }
  // Set notags
  var bNotags = (oTableCell.className.indexOf('spgridTypeNotags') >= 0);
  if (bNotags) {
    oField.notags = bNotags;
  }
  // Set sortByColumn
  var aMatch = oTableCell.className.match(/spgridTypeSortBy(\d+)/);
  if (aMatch) {
    oField.sortByColumn = aMatch[1];
  }
  return oField;
};

/**
 * Creates new row object from HTML table row element.
 *
 * @private
 * @param {object} oTableRow Table row element
 * @return Row object
 * @type object
 */
southprojects.Grid.prototype.newRowHtml = function(oTableRow) {
  // Create new row object
  var oRow = {
    i: this.rowsIndex.length,
    cells: []
  };
  // Set style
  var sStyle = southprojects.Widget.getStyle(oTableRow);
  if (sStyle) {
    oRow.style = sStyle;
  }
  // Get cells
  var oTableCell = southprojects.Utils.getFirstChild(oTableRow, 'td', 'th');
  for (var iCol = 0; iCol < this.fields.length; iCol++) {
    // Add cell
    oRow.cells.push(this.newCellHtml(oTableCell, oRow.i, iCol));
    // Next cell
    if (oTableCell) {
      oTableCell = southprojects.Utils.getNextSibling(oTableCell, 'td', 'th');
    }
  }
  return oRow;
};

/**
 * Creates new cell object from HTML table cell element.
 *
 * @private
 * @param {object} oTableCell Table cell element
 * @param {number} iRow Row id
 * @param {number} iCol Column id
 * @return Cell object
 * @type object
 */
southprojects.Grid.prototype.newCellHtml = function(oTableCell, iRow, iCol) {
  // Create cell object
  var oCell = {
    i: iCol,
    r: iRow,
    v: ''
  };
  if (oTableCell) {
    // Set value
    oCell.v = oTableCell.innerHTML;
    // Facilitate migrating from an existing <table> to the grid
    if (this.fields[iCol].notags) {
      // Remove tags
      oCell.v = oCell.v.replace(/<[^>]*>/g, '');
    }
    // Set style
    var sCellStyle = southprojects.Widget.getStyle(oTableCell);
    if (sCellStyle) {
      oCell.style = sCellStyle;
    }
  }
  // Convert cell value
  oCell = this.convertCell(oCell);
  return oCell;
};
