// SortableTable Class v1.0
// Author:  Золотухин Сергей ( serge@design.ru, http://serge.design.ru/ )
// Updated:  2003-12-24

/*
  CSS селекторы:

    st_Sortable
    st_Sorted

    st_Asc
    st_Desc

    st_TypeNumber
    st_TypeMoney

  Events:

    OnSortBegin
    OnSortEnd
*/

function SortableTable( htmlTableID, sortedColumnIndex )
{
  var i;
  var thisCopy = this;

  //  CSS селекторы
  this.SORTED = 'st_Sorted';
  this.SORTABLE = 'st_Sortable';
  this.SORTED_ASC = 'st_Asc';
  this.SORTED_DESC = 'st_Desc';

  this.TYPE_NUMBER = 'st_TypeNumber';
  this.TYPE_MONEY = 'st_TypeMoney';

  this.SortedColumnIndex = ( sortedColumnIndex == null ) ? -1 : sortedColumnIndex;

  this.table = document.getElementById( htmlTableID );
  this.head = this.table.getElementsByTagName('thead')[0];
  this.headCells = this.head.getElementsByTagName('td');

  // Посмотрим есть ли колонки, по которым будем сортировать
  if( this.head )
  {
    var st_i = 0;
    for( i=0; i<this.headCells.length; i++ )
    {
      if( this.getSelector( this.headCells[i], this.SORTABLE ) )
      {
        this.headCells[i].st_Index = st_i;
        st_i++;

        if( this.getSelector( this.headCells[i], this.TYPE_NUMBER ) )
        {
          this.headCells[i].st_SortkeyType = this.TYPE_NUMBER
        }

        if( this.headCells[i].attachEvent )
        {
          this.headCells[i].attachEvent( 'onclick', function(){thisCopy.sort()} )
          this.headCells[i].unselectable = true
        }
        if( this.headCells[i].addEventListener )
        {
          this.headCells[i].addEventListener( 'click', function(e){thisCopy.sort(e)}, false )
          this.headCells[i].onmousedown = function() {return false}
        }
      }
    }
  }

  this.body = this.table.getElementsByTagName('tbody')[0];
  this.rows = this.body.getElementsByTagName('tr');
  this.rowsCount = this.rows.length;
  this.cache = new Array();

  // наверное не дурно было бы сделать индексы
  var cells = this.body.getElementsByTagName('td');
  var cellsCount = cells.length;

  var abbr;

  for( i=0; i<cellsCount; i++ )
  {
    abbr = cells[i].getAttribute('abbr')
    this.setCellSortkey(cells[i], ( abbr != null && abbr != '' ) ? abbr : cells[i].firstChild.nodeValue)
  }

  for( i=0; i<this.rowsCount; i++ )
  {
    this.cache[i] = this.rows[i].cloneNode(true)
  }

  return this
}


// Сортировка
SortableTable.prototype.sort = function(e)
{
  var thisCopy = this
  var headCell =  window.event ? window.event.srcElement : e.currentTarget

  if (headCell.tagName != 'TD' && headCell.tagName != 'td')
  {
    var c = 0
    while (headCell.tagName != 'TD' && headCell.tagName != 'td' && c < 10)
    {
      headCell = headCell.parentNode
      c++
    }
  }

  if( this.OnSortBegin )
  {
    // Вызов пользовательского обработчика события с передачей события
    this.OnSortBegin( window.event ? window.event : e )
  }

  // Нужно поставить правильный селектор
  this.applySelectors(headCell)


  if( headCell.st_Index == this.SortedColumnIndex )
  {
    this.cache.reverse(headCell)
  }
  else
  {
    this.SortedColumnIndex = headCell.st_Index;

    switch( headCell.st_SortkeyType )
    {
      // Сравнение чисел
      case this.TYPE_NUMBER :
      this.cache.sort(
        function( a, b )
        {
          var aVal = parseInt( thisCopy.getCellSortkey( a.getElementsByTagName('td')[thisCopy.SortedColumnIndex] ).replace (',', '.') )
          var bVal = parseInt( thisCopy.getCellSortkey( b.getElementsByTagName('td')[thisCopy.SortedColumnIndex] ).replace (',', '.') )

          var aValSort = a.getElementsByTagName('td')[thisCopy.SortedColumnIndex].getAttribute ("sort_order");
          var bValSort = b.getElementsByTagName('td')[thisCopy.SortedColumnIndex].getAttribute ("sort_order");

          if (aValSort && bValSort) return aValSort - bValSort

          return  ( aVal - bVal )
        }
      )
      break

      // Сравнение денежных величин (откусывается первый знак, типа $1 и $10)
      case this.TYPE_MONEY :
      this.cache.sort(
        function( a, b )
        {
          var aVal = parseFloat( thisCopy.getCellSortkey( a.getElementsByTagName('td')[thisCopy.SortedColumnIndex].firstChild.nodeValue).substr(1) )
          var bVal = parseFloat( thisCopy.getCellSortkey( b.getElementsByTagName('td')[thisCopy.SortedColumnIndex].firstChild.nodeValue).substr(1) )
          return ( aVal - bVal )
        }
      )
      break

      // Сравнение всего остального
      default:
      this.cache.sort(
        function( a, b )
        {
          var aVal = thisCopy.getCellSortkey( a.getElementsByTagName('td')[thisCopy.SortedColumnIndex] )
          var bVal = thisCopy.getCellSortkey( b.getElementsByTagName('td')[thisCopy.SortedColumnIndex] )
          return ( aVal == bVal ? 0 : ( aVal > bVal ? 1 : -1 ) )
        }
      )
    }
  }

  var body = document.createElement('tbody')
  for( var i=0; i<this.rowsCount; i++ )
  {
    body.appendChild( this.cache[i] )
  }
  this.table.replaceChild(body, this.body)
  this.body = body

  if( this.OnSortEnd )
  {
    // Вызов пользовательского обработчика события с передачей "нажатого" header'а
    this.OnSortEnd( window.event ? window.event : e )
  }
}


// Получение ключа сортировки ячейки
SortableTable.prototype.getCellSortkey = function( cell )
{
  return cell.getAttribute('Sortkey')
}

// Установка ключа сортировки ячейки
SortableTable.prototype.setCellSortkey = function( cell, val )
{
  cell.setAttribute('Sortkey', val)
}

// Проверка селектора у элемента
SortableTable.prototype.getSelector = function( elem, selector )
{
  return ( elem && elem.className.indexOf(selector) != -1 )
}

// Установка селектора у элемента
SortableTable.prototype.setSelector = function( elem, selector )
{
  for( var i=1; i<arguments.length; i++ )
  {
    elem.className += ' ' + arguments[i]
  }
}

// Удаление селектора у элемента
SortableTable.prototype.deleteSelector = function( elem, selector )
{
  for( var i=1; i<arguments.length; i++ )
  {
    elem.className = elem.className.replace( new RegExp(arguments[i], 'g'), '' )
  }

}


// Установка правильных селекторов у заголовков
SortableTable.prototype.applySelectors = function( headCell )
{
  for( var i=0; i<this.headCells.length; i++ )
  {
    if( headCell.st_Index == this.headCells[i].st_Index)
    {
      var childs = this.headCells[i].childNodes;
      for(var j = 0; j < childs.length; j++){
        if(childs[j].nodeName == 'DIV'){
          var div = childs[j];
        }
      }

      if( !this.getSelector(this.headCells[i], this.SORTED) )
      {
    this.setSelector(this.headCells[i], this.SORTED)
      }

      if( this.getSelector(this.headCells[i], this.SORTED_ASC) )
      {
        this.deleteSelector(this.headCells[i], this.SORTED_ASC)
        this.setSelector(this.headCells[i], this.SORTED_DESC)
        div.innerHTML = "↓"; //
      }
      else
      {
        this.deleteSelector(this.headCells[i], this.SORTED_DESC)
        this.setSelector(this.headCells[i], this.SORTED_ASC)
        div.innerHTML = "↑"; //
      }
    }
    else
    {
      this.deleteSelector(this.headCells[i], this.SORTED, this.SORTED_ASC, this.SORTED_DESC);
      var childs = this.headCells[i].childNodes;
      for(var j = 0; j < childs.length; j++){
        if(childs[j].nodeName == 'DIV'){
          var div = childs[j];
        }
      }
      if (this.getSelector (this.headCells[i], this.SORTABLE)) {
        div.innerHTML = " ";
      }
    }
  }
}



searchableHandler = {
	table_index : [],
	table_index_length : 0,
	search_input : null,
	table_rows : [],
	table_id : '',
	init : function (table_id, search_input_id) {
		searchableHandler.table_id = table_id;
		var table = document.getElementById(table_id);
		// фиксируем ширину таблицы, ширину контейнерной таблицы и колонок после загрузки
		document.getElementsByTagName('table')[0].style.width = document.getElementsByTagName('table')[0].offsetWidth + 'px';
		table.style.width = table.offsetWidth + 'px';

		var head_cells = table.getElementsByTagName('tr')[0].getElementsByTagName('td');
		
		for (var i = 0; i < head_cells.length; i++) {
			head_cells[i].style.width = head_cells[i].offsetWidth + 'px';
		}
		
		// индексируем таблицу
		searchableHandler.setIndex(table_id);
		
		// событие нажатия на клавишу для IE
		searchableHandler.search_input = document.getElementById(search_input_id);
		if( searchableHandler.search_input.attachEvent ) {
			searchableHandler.search_input.attachEvent( 'onkeydown', function(){
				clearTimeout(searchableHandler.search_timer);
				
				var e = window.event;
				
				var code;
				if (e.keyCode) code = e.keyCode;
				else if (e.which) code = e.which;
				
				
				if (code == 13) {
					searchableHandler.search();
				} else if (code != 37 && code != 38 && code != 39 && code != 40) {
					searchableHandler.search_timer = window.setTimeout(searchableHandler.search, 1000);
				}
			});
        }
		// событие нажатия на клавишу для остальных
        if( searchableHandler.search_input.addEventListener ) {
			searchableHandler.search_input.addEventListener( 'keypress', function(e){
				clearTimeout(searchableHandler.search_timer);
				
				var code;
				if (e.keyCode) code = e.keyCode;
				else if (e.which) code = e.which;
				
				if (code == 13) {
					searchableHandler.search();
				} else if (code != 37 && code != 38 && code != 39 && code != 40) {
					searchableHandler.search_timer = window.setTimeout(searchableHandler.search, 1000);
				}
			});
        }
		
	},
	setIndex : function (table_id) {
		searchableHandler.table_index = [];
		
		var table = document.getElementById(table_id);
		var table_rows = table.getElementsByTagName('tbody')[0].getElementsByTagName('tr');
		searchableHandler.table_rows = table_rows;
		
		for (var i = 0, table_rows_length = table_rows.length; i < table_rows_length; i++) {
			var row = table_rows[i];
			var cells = table_rows[i].getElementsByTagName('td');
			var searchable_string = '';
			for (var j = 0, cells_length = cells.length; j < cells_length; j++) {
				if (j < 3) {
					var cell = cells[j];
					searchable_string += cell.getAttribute('abbr') ? cell.getAttribute('abbr') + ' ' : '';
					var cell_paragraphs = cell.childNodes;
					for (var k = 0; k < cell_paragraphs.length; k++) {
						var innerText = cell_paragraphs[k].innerText ? cell_paragraphs[k].innerText : cell_paragraphs[k].textContent
						searchable_string += innerText;
					}
				}
			}
			searchable_string = searchable_string.toLowerCase();
			searchable_string = searchable_string.replace(String.fromCharCode(160), ' ');
			searchableHandler.table_index.push(searchable_string);
		}
		searchableHandler.table_index_length = searchableHandler.table_index.length;
	},
	search : function () {
		var table = document.getElementById(searchableHandler.table_id);
		var searchable_string = searchableHandler.search_input.value.toLowerCase();
		var nothing_found = true;
		for (var i = 0; i < searchableHandler.table_index_length; i++) {
			if (searchableHandler.table_index[i].indexOf(searchable_string) >= 0) {
				// есть совпадение - убираем hidden со строки
				searchableHandler.table_rows[i].className = searchableHandler.table_rows[i].className.replace( new RegExp(' hidden', 'g'), '' );
				nothing_found = false;
			} else {
				// нет совпадений - ставим hidden на строку
				searchableHandler.table_rows[i].className += ' hidden';
			}
		}
		
		// ничего не нашли - скрываем таблицу и текст поля ввода делаем красным
		if (nothing_found) {
			table.className += ' hidden';
			searchableHandler.search_input.style.color = 'red';
		} else {
			table.className = table.className.replace( new RegExp(' hidden', 'g'), '' );
			searchableHandler.search_input.style.color = 'black';
		}
	}
};

