
//Вызывается для события onmouseover таблицы
//делает подсветку строк таблицы при прохождении над ними мышки
//проверено в ИЕ и ФФ
function tableFlashRows(_node, _color)
{
    _node.onmouseover=function()	{}	//удаляем обработчик таблицы
    //получаем список строк и на каждую вешаем 2 обработчика
    list = _node.rows;
    for (var i = 0; i < list.length; i++) {
	list[i].onmouseover=function()	{	this.style["backgroundColor"]= _color;	}
	list[i].onmouseout=function()	{	this.style["backgroundColor"]="";	}
    }
}


//Вычисление верхнего/нижнего левого угла переданного узла. Возвращает массив [x,у]
function calcLeftCorner(_node, _calcBottom)
{
	var N=_node;
	var x=0;
	var y=_calcBottom?N.offsetHeight:0;
	while(N!=null){	
		if(isNaN(N.offsetLeft)&&isNaN(N.offsetTop))	break;
		else if(isNaN(N.offsetLeft))	y+=N.offsetTop;
		else if(isNaN(N.offsetTop))		x+=N.offsetLeft;
		else{
			x+=N.offsetLeft;
			y+=N.offsetTop;
		}
		if( N.style.position=='absolute' ) break;
		N=N.offsetParent; 
	}
	return [x,y];
}



//Объект надо создавать ПОСЛЕ создания узлов с соответствующими ID
/*
При конструировании передается префикс ID узлов, образующих окно
Главный, объемлющий, с суфиксом _wnd. Желательно за ранее ему сказать display: none;
для тех, кто не пользует javascript
2 обязательных элемента с суфиксами _header и _body образуют заголовок и телдо окна соответственно
Не обязательный тег с суфиксом _close - на него вешается событие закрытия окна

Показ окна с помощью ф-ции show

*/
function jswindow(_prefix)
{
	this.wnd=document.getElementById(_prefix+"_wnd");
	if( !this.wnd ) return;
	with (this.wnd.style) {
		display='none';
		position='absolute';
		zIndex=99;
	}
	var ctrl=document.getElementById(_prefix+"_close");
	if( ctrl ) {
		var wnd=this.wnd;
		ctrl.style.cursor='pointer';
		ctrl.onclick=function()	{	wnd.style.display='none';	}
	}	
	this.header=document.getElementById(_prefix+"_header");
	if( !this.header) return;
	this.body=document.getElementById(_prefix+"_body");
	if( !this.body) return;
	
	this.show=function(_x, _y, _header, _body)
	{
		this.header.innerHTML=_header;
		this.body.innerHTML=_body;
		with (this.wnd.style) {
			display='block';
			left=_x+"px";
			top=_y+"px";
		}
	}
	
	this.hide=function()	{		this.wnd.style.display='none';	}
	
	this.repairX=function()	
	{
		var ww=document.body.clientWidth?document.body.clientWidth:window.innerWidth;
		if(	parseInt(this.wnd.style.left)+this.wnd.offsetWidth>ww )
			this.wnd.style.left=ww-this.wnd.offsetWidth;
//		alert("ww="+ww+"; offsetWidth="+this.wnd.offsetWidth+";left="+this.wnd.style.left+"/"+l);	
	}
}
				    
// https://dev.vega.ru/twiki/bin/view/SpyLog/JavaScriptUtils
// Не хеш из-за того, что не все внутрикодовые конструкции м.б. использованы хеше
var basics = new ( function()
{
	//Поиск эл-та по его ID. Заодно с сохранением его в кеше
	var $ = function(id)
	{
		if( !(id in $.elts) )
			$.elts[id] = document.getElementById(id);
		return $.elts[id];
	};
	
	$.elts = {};//устанавливаем пустой кеш ТОЛЬКО при создании basics!	
	this.$ = $;	//делаем публичную ссылку на ф-цию

	//Проверка, содержит ли массив 'a' элемент 'v' 
	$.inArray = function(a, v)
	{
		for (var i = a.length - 1; i >= 0; i--)	
			if (a[i] == v)
				return true;
		return false;
	};

	//определена ли переменная o
	$.defined = function(o)
	{
		return (typeof(o) != 'undefined');
	};
	//проверка на массив
	$.isArray = function(o)
	{
		if (o == null || typeof(o) != 'object' || typeof(o.length) != 'number')
			return false;
		// Check to see if the object is an instance of the window's Array object
		if ($.defined(Array) && $.defined(o.constructor) && o.constructor==Array) 
			return true;
		// It might be an array defined from another window object - check to see if it has an Array's methods
		if (typeof(o.join)=="function" && typeof(o.sort)=="function" && typeof(o.reverse)=="function")
			return true;
		// As a last resort, let's see if index [0] is defined
		return (o.length == 0 || $.defined(o[0]));
	};

	//Создает и возвращает div
	$.newDiv = function(html)
	{
		var r = document.createElement('div');
		if (html != null)
			r.innerHTML = html;
		return r;
	};

	//Устанавливает элементу el css-свойства
	//n=хеш (свойство->значение)
	$.css = function(el, n)
	{
		for (var i in n)	el.style[i] = n[i];
		return $;
	};

	// written by Dean Edwards, 2005
	// with input from Tino Zijdel - crisp@xs4all.nl
	// http://dean.edwards.name/weblog/2005/10/add-event/
	//Навешивает события типа type на элемент el. 
	//Работает одинаково на любых браузерах, 
	//позволяет навешивать несколько событий одного типа.
	$.addEvent = function(element, type, handler)
	{
		if (element.addEventListener)
			element.addEventListener(type, handler, false);
		else
		{
			//$$guid - это просто такое название
			if (!handler.$$guid) 
				handler.$$guid = $.addEvent.guid++;
			if (!element.events) 
				element.events = {};
			var handlers = element.events[type];
			if (!handlers)	{
				handlers = element.events[type] = {};
				if (element['on' + type]) handlers[0] = element['on' + type];
				element['on' + type] = handleEvent;
			}
	
			handlers[handler.$$guid] = handler;
		}
		return $;
	};

	$.addEvent.guid = 1;

	$.removeEvent = function(element, type, handler)
	{
		if (element.removeEventListener)
			element.removeEventListener(type, handler, false);
		else if (element.events && element.events[type] && handler.$$guid)
			delete element.events[type][handler.$$guid];
		return;
	};

	var handleEvent = function(event)
	{
		event = event || fixEvent(window.event);
		var returnValue = true;
		var handlers = this.events[event.type];

		for (var i in handlers)	{
			if (!Object.prototype[i])	{
				this.$$handler = handlers[i];
				if (this.$$handler(event) === false) 
					returnValue = false;
			}
		}

		if (this.$$handler) this.$$handler = null;
	
		return returnValue;
	};

	var fixEvent = function(event)
	{
		event.preventDefault = fixEvent.preventDefault;
		event.stopPropagation = fixEvent.stopPropagation;
		return event;
	};
	
	fixEvent.preventDefault = function()
	{
		this.returnValue = false;
		return;
	};
	
	fixEvent.stopPropagation = function()
	{
		this.cancelBubble = true;
		return;
	};

	// This little snippet fixes the problem that the onload attribute on the body-element will overwrite
	// previous attached events on the window object for the onload event
	if (!window.addEventListener) {
		document.onreadystatechange = function()
		{
			if (window.onload && window.onload != handleEvent)
			{
				$.addEvent(window, 'load', window.onload);
				window.onload = handleEvent;
			}	
		}
	}

	$.getElementsByClass = function(searchClass,node,tag)
	{
		var classElements = [];
		if (node == null) node = document;
		if (tag == null) tag = '*';
		var els = node.getElementsByTagName(tag);
		var elsLen = els.length;
		var pattern = new RegExp("(^|\s)"+searchClass+"(\s|$)");
		for (i = 0, j = 0; i < elsLen; i++) {
			if (pattern.test(els[i].className))	{
				classElements[j] = els[i];
				j++;
			}
		}
		return classElements;
	};

	var selectContents = function()
	{
		this.select();
	};

	$.inputsSelectedOnFocus = function()
	{
		var els = document.getElementsByTagName('INPUT');
		for (var i = els.length - 1; i >= 0; i--) {
			var el = els[i];
			if (el.type != 'text') continue;
			$.addEvent(el, 'focus', selectContents);
		}
	};

	$.addEvent(window, 'load', $.inputsSelectedOnFocus);

})();
