ns('Carib.Order.Widgets');

/**
 * Table
 * 
 * @version $Id: table.js 405 2009-07-06 07:00:00Z  $
 */
Carib.Order.Widgets.Table = function(config) {
  // configurable {
  this.selector = '';
  this.recordset = null; // required
  this.auto_init = false;
  this.column_model = [];
  this.id = false;
  this.selected = false;
  this.hide_empty = false;
  // }
  
  this.addEvents({
    select: true
  });
  
  Carib.Order.Widgets.Table.superclass.constructor.call(this, config);
  
  if(this.auto_init)
    this.init();
}

utils.extend(Carib.Order.Widgets.Table, utils.Observable, {
  init: function() {
    this.recordset.on('update', this.onUpdateRecord, this);
    this.recordset.on('remove', this.onRemoveRecord, this);
    this.recordset.on('add', this.onAddRecord, this);
    
    this.hideTableIf();
  },
  
  hideTableIf: function() {
    if(!this.hide_empty)
      return;
      
    if(this.recordset.getCount() > 0)
      this.getEl().show();
    else
      this.getEl().hide();
  },
  
  /**
   * Render cell.
   * Returns object:
   * {
   *   class: 'cell class',
   *   content: 'cell content'
   * }
   * 
   * @param {String} name
   * @param {Object} record
   * @return {Object}
   */
  _renderCell: function(name, record) {
    var method_name = '_' + name + 'Renderer';
    var result = {};
    if(this[method_name]) {
      result = this[method_name].call(this, record);
    } else {
      result.content = record.get(name);
    }
      
    return result;
  },
  
  _addRow: function(record, num) {
    var $tr = $('<tr></tr>').appendTo(this.getBody()).attr('id', this._generateRowId(record));
    this._initRowEvents($tr, record, num);
    var row_class = this._getRowClass(record, num);
    if(row_class)
      $tr.addClass(row_class);
      
    var _this = this;
    $.each(this.column_model, function(i, name) {
      var result = _this._renderCell(name, record);
      var $td = $('<td></td>').appendTo($tr).addClass(_this._generateCellClass(name)).empty();
      if(result.content)
        $td.html(result['content']);
      else if(result.$content)
        $td.append(result.$content);
      if(result['class'])
        td.addClass(result['class']);
    });

    this.hideTableIf();
  },
  
  _initRowEvents: function($row, record, num) {
    $row.mouseover(this.onMouseOver.createDelegate(this, [record]));
    $row.mouseout(this.onMouseOut.createDelegate(this, [record]));
    $row.click(this.onClick.createDelegate(this, [num]));
  },
  
  _updateRow: function(record, num) {
    var $tr = this.getTableRow(record);

    var _this = this;
    $.each(this.column_model, function(i, name) {
      var result = _this._renderCell(name, record);
      var $td = $('.' + _this._generateCellClass(name), $tr);
      $td.removeClass();
      $td.addClass(_this._generateCellClass(name)).empty();
      if(result.content)
        $td.html(result['content']);
      else if(result.$content)
        $td.append(result.$content);
      if(result['class'])
        td.addClass(result['class']);
    });
  },
  
  _removeRow: function(record, num) {
    this.getTableRow(record).remove();

    this.hideTableIf();
  },
  
  _getRowClass: function(record, num)
  {
    return false;
  },
  
  getTableRow: function(record) {
    return $(this.getTableRowSelector(record), this.getEl());
  },
  
  getTableRowSelector: function(record) {
    return 'tr#' + this._generateRowId(record);
  },
  
  getSelected: function() {
    return this.recordset.getCount() > 0 ? this.recordset.getAt(this.selected) : null;
  },
  
  _higlightRow: function(record) {
    this.getTableRow(record).addClass('highlight');   
  },
  
  _unhighlightRow: function(record) {
    this.getTableRow(record).removeClass('highlight');   
  },
  
  select: function(num) {
    if(num === this.selected)
      return;
      
    this.unselect();
    
    var record = this.recordset.getAt(num);
    if(!record)
      return;
      
    this.selected = num;
    this.getTableRow(record).addClass('selected');    
    this.onSelect();
  },
  
  unselect: function() {
    if(this.selected === false)
      return;
      
    var record = this.recordset.getAt(this.selected);
    this.selected = false;
    if(!record)
      return;
      
    this.getTableRow(record).removeClass('selected');
  },
  
  getRecordset: function() {
    return this.recordset;
  },
  
  onRemoveRecord: function(store, record, num) {
    this._removeRow(record, num);
  },
  
  onUpdateRecord: function(store, record, num) {
    this._updateRow(record, num);
  },
  
  onAddRecord: function(store, record, num) {
    this._addRow(record, num);
  },
  
  onMouseOver: function(record) {
    this._higlightRow(record);
  },
  
  onMouseOut: function(record) {
    this._unhighlightRow(record);
  },
  
  onClick: function(num) {
    this.select(num);
  },
  
  onSelect: function() {
    this.fireEvent('select', [this, this.getSelected()]);
  }, 
  
  _generateRowId: function(record) {
    return this.getId() + '_row_' + record.getId();
  },
  
  _generateCellClass: function(name) {
    return 'cell_' + name;
  },
  
  getEl: function() {
    return $(this.selector);
  },
  
  getId: function() {
    if(!this.id) {
      this.id = this.getEl().generateId().attr('id');
    }
    return this.id;
  },
  
  getBody: function() {
    return $('tbody', this.getEl());
  }
 
});
