/* ----------------------------------------------- *\
   RowsControl

   (c) 2008 www.seo4experts.com
   author:  anvi@fromru.com
\* ------------------------------------------------ */

/*
	Настройка скрипта:
	Подключите к HTML документу библиотеку:

		<script language="JavaScript" src="/site/jslibs/rowsControl.js"></script>


	В управляемой таблице должен быть установлен id атрибут
	и обработчик события onselectstart="return false;"

	Например:
		<table id="keyword" onselectstart="return false;" >

	В CSS стилях для таблицы прописать
		"-moz-user-select: none;-khtml-user-select: none;user-select: none;"

	Например:
		#keyword {
			-moz-user-select: none;
			-khtml-user-select: none;
			user-select: none;
		}

	У каждой строки попадающей под управление должен быть установлен id атрибут,
	состоящий из id таблицы, знака подчёркивания и идентификатора записи.

	Например:
		<tr id="keyword_14">

	Создайте для строк таблицы 2 стиля:
		- сфокусированная строка
		- выбранная строка

	Например:
		tr.select { background-color: #CCCCFF; }
		tr.focus  { background-color: #FFFFCC; }

	У checkbox-а строки должен быть установлен id атрибут, состоящий
	из id таблицы, знака подчёркивания, идентификатора записи и суфикса 'cb'.

	Например:
		<input type="checkbox" id="keyword_14_cb">


	Создайте элемент управления:

		var rows = new RowsControl('keywords', {focus_class:'focus', select_class:'select'});
		или
		new RowsControl('table_id', {focus_class:'focus', select_class:'select'});

	Доступ к элементу управления:

		rows.SelectAll(true);
		или
		RowsControl.controls.keywords.SelecteAll(true);

	Доступные методы:

		SelecteAll(true|false) 			- выбор/сброс всех строк.
		Select(trObject, true|false) 	- выбор/сброс указанной строки.
		Selected() 						- массив выбранных значений.
		Disable(true|false) 			- запрещает/разрешает работу с checkbox-ами.

	ToDo:
	-)	нужно убрать активирование чекбокса при нажатии на ссылку, находящейся в строке таблицы
*/

function RowsControl(tableId, params)
{
	this.params  = {focus_class:'focus', select_class:'select'};
	this.rows    = [];
	this.pullRows= [];
	this.lastRow = -1;

	this.table 	 = document.getElementById(tableId);
	if (this.table.tagName!='TABLE') return;

	for(var i in params) this.params[i] = params[i];

	var rows = this.table.getElementsByTagName('TBODY')[0].getElementsByTagName('TR');
	for (var i=0; i<rows.length; i++) if (rows[i].id) {
		rows[i].rowsControl = this;
		rows[i].checkbox 	= document.getElementById(rows[i].id+'_cb');
		addEvent(rows[i].checkbox,'click', function(){if(!this.disabled){this.checked=!this.checked}});
		addEvent(rows[i], 'mouseout',  this.on_RowMouseOut);
		addEvent(rows[i], 'mouseover', this.on_RowMouseOver);
		addEvent(rows[i], 'mousedown', this.on_RowMouseDown);
		this.rows.push(rows[i]);
	}
	if (!RowsControl.controls.length) {
		if (document.captureEvents) {
			document.captureEvents(Event.MOUSEUP);
		}
		addEvent(document, 'mouseup',  this.on_DocumentMouseUp);
		RowsControl.onmouseup = true;
	}
	RowsControl.controls[tableId] = this;
	return this;
}

RowsControl.controls  = {};

//------------------------------------------------------------------------------
//	SelectAll(true|false) - select/deselect all rows
//
RowsControl.prototype.SelectAll  = function(state)
{
	for(var i=0; i<this.rows.length; i++) {
		if (this.rows[i].checkbox.checked!=state) this.Select(this.rows[i], state);
	}
}
//------------------------------------------------------------------------------
//	Select(trObject, true|false) - select/deselect specified row
//
RowsControl.prototype.Select = function(row, status)
{
	if (!row.checkbox.disabled) {
		row.checkbox.checked = status;
		this.StyleClass(row, 'select', status);
	}
}

//------------------------------------------------------------------------------
//	Selected() - returns array of selected values
//
RowsControl.prototype.Selected = function()
{
	for(var sel=[], i=0; i<this.rows.length; i++) {
		if (this.rows[i].checkbox.checked) sel.push(this.rows[i].checkbox.value);
	}
	return sel;
}
//------------------------------------------------------------------------------
//	Disable(true|false)
//
RowsControl.prototype.Disable  = function(state)
{
	for(var i=0; i<this.rows.length; i++) {
		this.rows[i].checkbox.disabled = state;
	}
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
RowsControl.prototype.on_DocumentMouseUp = function(event)
{
	for(var i in RowsControl.controls) {
		RowsControl.controls[i].pullRows = [];
	}
}
//------------------------------------------------------------------------------
RowsControl.prototype.on_RowMouseOut = function(event)
{
	this.rowsControl.StyleClass(this, 'focus', 0);
}
//------------------------------------------------------------------------------
RowsControl.prototype.on_RowMouseOver= function(event)
{
	this.rowsControl.StyleClass(this, 'focus', 1);
	if (this.rowsControl.pullRows.length) {
		var rc = this.rowsControl;
		var r  = rc.IndexOf(this);
		for(var i=0; i<rc.pullRows.length; i++) {
			if (rc.pullRows[i]==r) return;
		}
		rc.pullRows.push(r);
		rc.Select(this, rc.rows[rc.pullRows[0]].checkbox.checked);
	}
}
//------------------------------------------------------------------------------
RowsControl.prototype.on_RowMouseDown= function(event)
{
	if ((event.srcElement ?event.srcElement :event.target).tagName == 'A') {
		if (event.bubbles) event.bubbles = false; else event.cancelBubble = true;
		return;
	}
	this.rowsControl.selectRow(this, event);
	this.rowsControl.pullRows = [this.rowsControl.lastRow];
}
//------------------------------------------------------------------------------
RowsControl.prototype.selectRow = function(row, event)
{
	var stat		= !row.checkbox.checked;
	var currRow 	= this.lastRow;
	this.lastRow	= this.IndexOf(row);
	if (currRow>=0 && event.shiftKey) {
		var from= Math.min(currRow, this.lastRow);
		var to  = Math.max(currRow, this.lastRow);
		stat    = this.rows[currRow].checkbox.checked;
		if (stat!=this.rows[this.lastRow].checkbox.checked) {
			for(var i=from+1; i<to; i++) {
				this.Select(this.rows[i], stat);
			}
		}
	}
	this.Select(row, stat);
}
//------------------------------------------------------------------------------
RowsControl.prototype.StyleClass = function(row, name, set)
{
	var cls= row.className.split(' ');
	var classSet= [];
	var classMy = {};
	for (var i=0; i<cls.length; i++) {
		if (cls[i]==this.params.focus_class) {
			if (name!='focus') classMy['focus'] = this.params.focus_class;
		} else
		if (cls[i]==this.params.select_class) {
			if (name!='select') classMy['select'] = this.params.select_class;
		} else {
			classSet.push(cls[i]);
		}
	}
	if (set) classMy[name] = this.params[name+'_class'];
	if (classMy.select) classSet.push(classMy.select);
	if (classMy.focus) classSet.push(classMy.focus);
	row.className = classSet.join(' ');
}
//------------------------------------------------------------------------------
RowsControl.prototype.IndexOf = function(row)
{
	for(var i=0; i<this.rows.length; i++) if (row==this.rows[i]) return i;
	return -1;
}
//------------------------------------------------------------------------------
function addEvent( obj, type, fn ) {
  if ( obj.attachEvent ) {
    obj['e'+type+fn] = fn;
    obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
    obj.attachEvent( 'on'+type, obj[type+fn] );
  } else
    obj.addEventListener( type, fn, false );
}
//------------------------------------------------------------------------------
function removeEvent( obj, type, fn ) {
  if ( obj.detachEvent ) {
    obj.detachEvent( 'on'+type, obj[type+fn] );
    obj[type+fn] = null;
  } else
    obj.removeEventListener( type, fn, false );
}
//------------------------------------------------------------------------------
