if(!(new Array()).indexOf) {
  Array.prototype.indexOf = function(search) {
    for(var i = 0; i < this.length; i++)
      if(this[i] == search)
        return i;
        
    return -1;
  }
}

function srtGetClass(elm) {
  if(!elm.className)
    return elm.getAttribute("class");
  else
    return elm.className;
}

function srtSetClass(elm, className) {
  if(!elm.className && elm.className != "")
    elm.setAttribute("class", className);
  else
    elm.className = className;
}

function srtAddClass(elm, className) {
  var cls = srtGetClass(elm).split(' ');
  var c = 0;
  
  c = cls.indexOf(className);
  if(c < 0) {
    cls[cls.length] = className;
    srtSetClass(elm, cls.join(' '));
  }
}

function srtDelClass(elm, className) {
  var cls = srtGetClass(elm).split(' ');
  var c = 0;
  
  c = cls.indexOf(className);
  if(c >= 0) {
    for(; c < cls.length - 1; c++)
      cls[c] = cls[c+1];
    cls.length--;
    srtSetClass(elm, cls.join(' '));
  }    
}

function srtRepClass(elm, class1, class2) {
  srtDelClass(elm, class1);
  srtAddClass(elm, class2);
}

function srtGetText(elm) {
  var r = null;
  if(elm.innerText)
    return elm.innerText;
  else {
    r = elm.ownerDocument.createRange();
    r.selectNodeContents(elm);
    return r.toString();
  }
}

function srtQuickSort(data, min, max, fetchFunc, cmpFunc, swapFunc) {
  var first = min;
  var last = max;
  var mid = Math.floor((min + max) / 2);
  var cmp = fetchFunc(data, mid);
  
  for(;first <= last;) {
    for(;(first < max) && cmpFunc(fetchFunc(data, first), cmp); first++);
    for(;(last > min) && cmpFunc(cmp, fetchFunc(data, last)); last--);
    
    if(first <= last) {
      swapFunc(data, first, last);
      first++;
      last--;
    }
  }

  if(min < last)
    srtQuickSort(data, min, last, fetchFunc, cmpFunc, swapFunc);
    
  if(first < max)
    srtQuickSort(data, first, max, fetchFunc, cmpFunc, swapFunc);
}

function tableSortOnclick(e) {
  var cls = srtGetClass(this).split(' ');
  var pos = 0;
  
  if((pos = cls.indexOf('sortasc')) > -1) {
    cls[pos] = 'sortdesc';
    srtSetClass(this, cls.join(' '));
    this._sortFunc = this._sortDescFunc;
    this._sortTable.sort(this);
  } else if((pos = cls.indexOf('sortdesc')) > -1) {
    for(;pos < cls.length-1; pos++)
      cls[pos] = cls[pos+1];
    cls.length--;
    srtSetClass(this, cls.join(' '));
    this._sortFunc = null;
    this._sortTable.sort(null, this);
  } else {
    cls[cls.length] = 'sortasc';
    srtSetClass(this,cls.join(' '));
    this._sortFunc = this._sortAscFunc;
    this._sortTable.sort(this);
  }
}

function tableSortStringAsc(a,b) {
  return -srtGetText(a).localeCompare(srtGetText(b));
}

function tableSortStringDesc(a,b) {
  return srtGetText(a).localeCompare(srtGetText(b));
}

function tableSortCurrencyAsc(a,b) {
  var ta = parseFloat(srtGetText(a).replace(/[\$,]/g, ''));
  var tb = parseFloat(srtGetText(b).replace(/[\$,]/g, ''));

  return (ta == tb ? 0 : (ta < tb ? -1 : 1));
}

function tableSortCurrencyDesc(a,b) {
  var ta = parseFloat(srtGetText(a).replace(/[\$,]/g, ''));
  var tb = parseFloat(srtGetText(b).replace(/[\$,]/g, ''));

  return (ta == tb ? 0 : (ta > tb ? -1 : 1));
}

function tableSortPercentAsc(a,b) {
  var ta = parseFloat(srtGetText(a).replace(/[%,]/g, ''));
  var tb = parseFloat(srtGetText(b).replace(/[%,]/g, ''));
  
  return (ta == tb ? 0 : (ta < tb ? -1 : 1));
}

function tableSortPercentDesc(a,b) {
  var ta = parseFloat(srtGetText(a).replace(/[%,]/g, ''));
  var tb = parseFloat(srtGetText(b).replace(/[%,]/g, ''));
  
  return (ta == tb ? 0 : (ta > tb ? -1 : 1));
}

function makeHeaderSortable(table, elm, col) {
  var cls = srtGetClass(elm).split(' ');
  
  elm._sortTable = table;
  elm._sorted = 0;
  elm.onclick = tableSortOnclick;

  if(cls.indexOf('sortascur') > -1) {
    elm._sortAscFunc = tableSortCurrencyAsc;
    elm._sortDescFunc = tableSortCurrencyDesc;
  } else if(cls.indexOf('sortaspct') > -1) {
    elm._sortAscFunc = tableSortPercentAsc;
    elm._sortDescFunc = tableSortPercentDesc;
  } else {  
    elm._sortAscFunc = tableSortStringAsc;
    elm._sortDescFunc = tableSortStringDesc;
  }
  elm._sortCol = col;

  if(cls.indexOf('sortable') < 0)
    cls[cls.length] = 'sortable';
  srtSetClass(elm, cls.join(' '));  
}

function tableSortRowGet(tbody, idx) {
  var tr = tbody.rows.item(idx);
  if(!tr._table)
    tr._table = tbody._table;
  return tr;
}

function tableSortRowSwap(tbody, idx1, idx2) {
  var tr1 = tbody.rows.item(idx1);
  var tr2 = tbody.rows.item(idx2);
  var sr1 = tr1.nextSibling;
  var sr2 = tr2.nextSibling;
  var cls1 = srtGetClass(tr1);
  var cls2 = srtGetClass(tr2);

  if(tr1 == tr2)
    return;
    
  if(sr1 != tr2) {
    tbody.removeChild(tr1);
    tbody.insertBefore(tr1, sr2);
  } else
    sr1 = tr1;

  tbody.removeChild(tr2);
  tbody.insertBefore(tr2, sr1);
  
  srtSetClass(tr1, cls2);
  srtSetClass(tr2, cls1);
}

function tableSortRowTest(a, b) {
  var tbl = a._table;
  var i = 0, r = 0;
  var th = null;
  
  for(i = 0; i < tbl._sortCol.length && r == 0; i++) {
    th = tbl._sortCol[i];
    if(th._sortFunc)
      r = th._sortFunc(a.cells.item(th._sortCol), b.cells.item(th._sortCol));
  }

  if(r == 0)
    return (a._index < b._index);
  else if(r == 1)
    return true;
  else
    return false;
}

function tableSortDoSort(idTable) {
  var elm = document.getElementById(idTable);
  var tbody = null;
  var sr, srn;
  
  if(!elm || !elm._sorting)
    return;
  
  if(elm._sortBody >= elm.tBodies.length)
    return;

  tbody = elm.tBodies.item(elm._sortBody);
  tbody._table = elm;

  srtQuickSort(tbody, 0, tbody.rows.length-1, tableSortRowGet, tableSortRowTest, tableSortRowSwap);

  elm._sortBody++;
  window.setTimeout("tableSortDoSort('" + this.id + "');", 100);
}

function tableSortStart(colAdd, colDel) {
  var i = 0;
  this._sorting = 1;
  if(!this._sortCol)
    this._sortCol = new Array();
    
  this._sortBody = 0;

  if(colAdd) {
    i = this._sortCol.indexOf(colAdd);
    if(i < 0)
      i = this._sortCol.length;
      
    for(; i > 0; i--)
      this._sortCol[i] = this._sortCol[i-1];
      
    this._sortCol[0] = colAdd;
  }
  if(colDel && (i = this._sortCol.indexOf(colDel)) > -1) {
    for(; i < this._sortCol.length; i++)
      this._sortCol[i] = this._sortCol[i+1];
    this._sortCol.length--;
  }
  
  window.setTimeout("tableSortDoSort('" + this.id + "');", 10);
}

function tableSortStop() {
  this._sorting = 0;
}

function initTableSort(idTable) {
  var elm = document.getElementById(idTable);
  var i = 0, j = 0;
  var tr = null;
  
  if(!elm)
    return false;
    
  if(!elm.tHead)
    return false;

  elm.sort = tableSortStart;
  elm.stopSort = tableSortStop;
  for(i = 0; i < elm.tHead.rows.length; i++) {
    tr = elm.tHead.rows.item(i);
    for(j = 0; j < tr.cells.length; j++) {
      makeHeaderSortable(elm, tr.cells.item(j), j);
    }
  }
  for(i = 0; i < elm.tBodies.length; i++)
    for(j = 0; j < elm.tBodies.item(i).rows.length; j++)
      elm.tBodies.item(i).rows.item(j)._index = j;
  
}