function Sorter() {

  this.sortDir_ = 1;
  this.elementPrefix_ = "listRow_";

  this.sortType_ = null;

  this.elementContainer_ = null;
  this.elements_ = [];

}

Sorter.DATE_CHECKER = /^\s*(\d{2})\.(\d{2})\.(\d{4})\s*$/;
Sorter.DATE_SORT = 1;
Sorter.TITLE_SORT = 2;

Sorter.prototype._compare = function (v1, v2) {
  if (v1 > v2) {
    return this.sortDir_;
  }
  else if (v1 < v2) {
    return - this.sortDir_;
  }
  return 0;
}

Sorter.prototype._getTypedChildNode = function (theNode, theType, theNumber) {
  var ctr = 0;
  var nodes = theNode.childNodes;
  for (var i = 0; i < nodes.length; i ++) {
    var curr = nodes[i];
    if (curr.nodeName != theType) {
      continue;
    }
    if (ctr == theNumber) {
      return curr;
    }
    ctr ++;
  }
}

Sorter.prototype._getDataFromNode = function (theRowNode) {
  if (this.sortType_ == Sorter.DATE_SORT) {
    return this._getTypedChildNode(theRowNode, "TD", 3).childNodes[0].data;
  }
  else if (this.sortType_ == Sorter.TITLE_SORT) {
    return this._getTypedChildNode(theRowNode, "TD", 2).childNodes[0].childNodes[0].data;
  }

  return this._getTypedChildNode(theRowNode, "TD", 2).childNodes[0].childNodes[0].data;
}

Sorter.prototype._realSort = function (a, b) {
  var value1 = this._getDataFromNode(a).toLowerCase();
  var value2 = this._getDataFromNode(b).toLowerCase();
  
  var date_sort = this.sortType_ == Sorter.DATE_SORT;
  
  if (value1.match(Sorter.DATE_CHECKER)) {
    var y1 = RegExp.$3;
    var m1 = RegExp.$2;
    var d1 = RegExp.$1;
  }
  else {
    date_sort = false;
  }
  
  if (value2.match(Sorter.DATE_CHECKER)) {
    var y2 = RegExp.$3;
    var m2 = RegExp.$2;
    var d2 = RegExp.$1;
  }
  else {
    date_sort = false;
  }
  
  if (date_sort) {
    return this._compare(y1, y2) || this._compare(m1, m2) || this._compare(d1, d2);
  }
  else {
    return this._compare(value1, value2);
  }
}

Sorter.prototype.sort = function (theSortType, theSortDir) {
  this.sortType_ = theSortType;
  this.sortDir_ = theSortDir || (- this.sortDir_);

  for (var i = 0; true; i ++) {
    var el = document.getElementById(this.elementPrefix_ + i);
    if (el == null) {
      break;
    }

    if (this.elementContainer_ == null) {
      this.elementContainer_ = el.parentNode;
    }

    this.elements_[this.elements_.length] = el;

    this.elementContainer_.removeChild(el);
  }

  this_ = this;
  this.elements_.sort(function (a, b) {
    return this_._realSort(a, b);
  });

  for (var i = 0; i < this.elements_.length; i ++) {
    this.elementContainer_.appendChild(this.elements_[i]);
  }

}
