function JTable(name)
{
	this.listener = new Array();
	this.table = document.getElementById(name);
	
	if(this.table == null)
	{
		throw "Table with name "+name+" not found";
		return;
	}
	this.initCell();
}

/**
 * 
 */
JTable.prototype = new EventDispatcher();

/**
 * ������������� ������ �� ������� ��� ������ ��������������
 */
JTable.prototype.setTableById = function(id)
{
	this.table = document.getElementById(id);
}
	
/**
 * �������� ������ �� ��������� �������
 * @return HTMLObject
 */
JTable.prototype.getTable = function()
{
	return this.table;
}


JTable.addClass= function(element, className)
{
	JTable.removeClass(element, className);
	element.className = element.className  + ' ' + className;
}

JTable.addMinorClass= function(element, className)
{
	element.className = className  + ' ' + element.className;
}

JTable.removeClass = function(element, className)
{
	myregexp = new RegExp(className, 'i');
	newClass = element.className;
	newClass = newClass.replace(myregexp, "");
	element.className = newClass;
}

JTable.changeClass= function(element, oldClassName, newClassName)
{
	JTable.removeClass(element, oldClassName);
	JTable.addClass(element, newClassName);
}


/**
 * @private
 */
JTable.prototype.initCell = function()
{
	var cols =  document.getElementsByTagName('COL');
	
	if (this.getTable().getAttribute('type') == 'sortable')
	{
		var tds = this.getTable().getElementsByTagName('TD');
		ln = tds.length; 
	
		instance = this;
		for (var j=0; j <ln; j++) 
		{
			
			tds[j].onclick = function() 
			{ 
				JTable.editCell(this, instance);
			}
		}// end for j
			
		var tbodies = this.getTable().getElementsByTagName('TBODY');

			rs = this.getTable().getElementsByTagName('TR');
			ln = rs.length; 
			for (var j=0; j <ln; j++)
			{
				if (j % 2 == 0) 
					JTable.changeClass(rs[j],"even","odd");
				else 
					JTable.changeClass(rs[j],"odd","even");
				
				JTable.setRowColor(rs[j].getElementsByTagName('td'), "#FFFFFF");
					
				rs[j].onmousemove = function(evt) 
				{
				    evt = (evt) ? evt : ((window.event) ? event : null);
					if (evt) 
					{
						if (evt.ctrlKey) 
							this.style.cursor = 'pointer'; 
						else 
							this.style.cursor = 'default';
					}
				}// end function rs[j].onmousemove

				rs[j].onmouseover = function(evt) 
				{
				    evt = (evt) ? evt : ((window.event) ? event : null);
				    if (evt) 
					{
						JTable.setPointer(this, this.getAttribute("index"), 'over', '#FFFFFF', '#33FFFF', '#FFCC99');
						if (evt.ctrlKey) 
							this.style.cursor = 'pointer';
					}
				}// end function rs[j].onmouseover
				
				rs[j].onmouseout = function() 
				{
					JTable.setPointer(this, this.getAttribute("index"), 'out', '#FFFFFF', '#33FFFF', '#FFCC99');
					this.style.cursor = 'default';
				}
				
				rs[j].onmousedown = function() 
				{
					JTable.setPointer(this, this.getAttribute("index"), 'click', '#FFFFFF', '#33FFFF', '#FFCC99');
				}
				
				rs[j].onclick = function(evt) 
				{
					evt = (evt) ? evt : ((window.event) ? event : null);
					if (evt) 
					{
						if (evt.ctrlKey)
							if (this.getAttribute('selected')) 
							{
								JTable.removeClass(this, 'selected');
								this.setAttribute('selected', false);
							}
							else
							{
								JTable.addClass(this, 'selected');
								this.setAttribute('selected', true);
							}
						}
						return false;
					}

				}

			ln = tbodies.length;
			for (var tb=0; tb < ln; tb++)
			 if (tbodies[tb].getAttribute('collapse')){

					if (tbodies[tb].getAttribute('collapsed')){
						if (tbodies[tb].getAttribute('collapsed') != 'false'){
							document.getElementById(tbodies[tb].getAttribute('collapse')).style.display = "none";
							tbodies[tb].setAttribute('collapsed','true');
							tbodies[tb].className = 'collapsed';
						}else{
							document.getElementById(tbodies[tb].getAttribute('collapse')).style.display = "";
							tbodies[tb].setAttribute('collapsed','false');
							tbodies[tb].className = 'expand';
						}
					}else{
							tbodies[tb].setAttribute('collapsed','false');
							tbodies[tb].className = 'expand';
					
					}
				
				tbodies[tb].ondragstart = function() {
					alert('dr');
				}

				tbodies[tb].onclick = function() {
					if (this.getAttribute('collapsed')){
						if (this.getAttribute('collapsed') == 'false'){
							document.getElementById(this.getAttribute('collapse')).style.display = "none";
							this.setAttribute('collapsed','true');
							this.className = 'collapsed';
						}else{
							document.getElementById(this.getAttribute('collapse')).style.display = "";
							this.setAttribute('collapsed','false');
							this.className = 'expand';
						}
					}else{
							document.getElementById(this.getAttribute('collapse')).style.display = "none";
							this.setAttribute('collapsed','true');
							this.className = 'collapsed';
					
					}
				}
			 }


			ths =  this.getTable().getElementsByTagName('TH');
			for (var t=0; t< ths.length; t++){
				ths[t].onmouseover = function() {
					JTable.addClass(this, 'hover');
				}
				ths[t].onmouseout = function() {
					JTable.removeClass(this, 'hover');
				}

				ths[t].onclick = function() {
					var ths = this.parentNode.getElementsByTagName('TH');
					for (var th=0; th < ths.length; th++){
						if (ths[th] != this){
							ths[th].setAttribute('order', 'none');
							ths[th].className ='';
						}
					}
					if (this.getAttribute('order') == 'ascending') {
						this.setAttribute('order', 'descending');
						JTable.removeClass(this, 'ascending');
						JTable.addClass(this, 'descending');
						sortTable(this.parentNode.parentNode.parentNode, this.cellIndex, this.getAttribute('compare'), false, i);
					}else{	
						this.setAttribute('order', 'ascending');
						JTable.removeClass(this, 'descending');
						JTable.addClass(this, 'ascending');
						sortTable(this.parentNode.parentNode.parentNode, this.cellIndex, this.getAttribute('compare'), true, i);
					}
				}
			}
		}
		
}

/**
 * Массив для хранения строк, для их подсвечивания и выделения
 * @type Object
 */
JTable.marked_row = new Object();

JTable.selected_row = null;

/**
 * Установка оброботчика выделений для строки
 * @param   object    the table row
 * @param   interger  the row number
 * @param   string    the action calling this script (over, out or click)
 * @param   string    the default background color
 * @param   string    the color to use for mouseover
 * @param   string    the color to use for marking a row
 */
 JTable.setPointer = function(theRow, theRowNum, theAction, theDefaultColor, thePointerColor, theMarkColor)
 {
	
	//if(JTable.marked_row[theRowNum]==null)
			JTable.marked_row[theRowNum] = theRow.getElementsByTagName('td');
	
	JTable.updateRows(theDefaultColor);
	if(theAction == "over")
	{
		if(JTable.selected_row != JTable.marked_row[theRowNum])
			JTable.setRowColor(JTable.marked_row[theRowNum], thePointerColor);	
	}
	else if(theAction == "out")
	{
		
	}
	else if(theAction=="click")
	{
		JTable.selected_row = JTable.marked_row[theRowNum];
		JTable.setRowColor(JTable.marked_row[theRowNum], theMarkColor);	
		JTable.updateRows(theDefaultColor);
	}// end if
}// end  setPointer
 
JTable.setRowColor = function(row, color)
{
	for (c = 0; c < row.length; c++) 
	{
		row[c].setAttribute('bgcolor', color, 0);
    }
}

JTable.updateRows = function(color)
{
	for(key in JTable.marked_row)
	{
		if(JTable.selected_row==JTable.marked_row[key])
			continue;
		JTable.setRowColor(JTable.marked_row[key], color);
	}// end for
}// end  JTable.updateRows
	


JTable.editCell = function(td, tableInstance)
{
	if (td.getAttribute('editable'))
	{
		if (td.getAttribute('editable') == 'true')
		{
			td.innerHTML = '<INPUT TYPE="text" style="width: '+(td.offsetWidth-4)+'px;" VALUE="'+td.innerHTML+'" >';
			JTable.addClass(td, 'edit');
			inputs = td.getElementsByTagName('INPUT');
			
			inputs[0].onblur = function(evt) 
			{
				var actions = td.getAttribute("actions");
				var layer = td.getAttribute("responseTo");
				
				var event = new Event();
				event['actions'] = actions;
				event['responseTo'] = layer;
				event['target'] = this.parentNode;
				
				tableInstance.dispatchEvent(Event.CHANGE, event);
				
				this.parentNode.onclick = function() 
				{
					JTable.editCell(this, tableInstance);
				}
				 
				JTable.removeClass(this.parentNode,'edit'); 
				var tbody = JTable.findParent(this,'TBODY'); 
				this.parentNode.innerHTML = (this.value != '') ? this.value : '&nbsp;'; 
				
			}
			
			inputs[0].onkeypress = function(evt) 
			{
				evt = (evt) ? evt : ((window.event) ? event : null);
				if (evt.keyCode == 13) 
					this.blur();
			}
			
			inputs[0].select();
			td.onclick = '';
		}
	}
}

JTable.findParent = function(el, parentTagName){
	var parent = el.parentNode;
	while (parent.tagName != parentTagName){
		parent = parent.parentNode;
		if (parent.tagName == 'BODY') return null;
	}
	return parent;
}