/**
 * @include  "js_common.js"
 * @include  "events.js"
 */

/**
 * @class
 * класс для создания подсказок к объектам и полям форм
 * 
 * @param {String} tcID - ID элемента в котором будут показываться подсказки
 * @param {String} tcClass - CSS-класс элемента в котором будут показываться подсказки
 */
function fh_helper_class(tcID, tcClass)
{
	/**
	 * ID элемента в котором будут показываться подсказки 
	 * @type String
	 */
	this.hid = (tcID) ? tcID : 'form_helper_div';

	/**
	 * CSS-класс элемента в котором будут показываться подсказки
	 * @type String
	 */
	this.className = (tcClass) ? tcClass : '';

	/**
	 * @private
	 * ссылка на элемент, в котором будут показываться подсказки
	 * @type HTMLElement 
	 */
	var _fh_hinter = _fh_Create.call(this, this.hid, this.className);

	/**
	 * @private
	 * хранит ссылку на массив с подсказками
	 * @type Object
	 */
	var _fh_titles = [];

	/**
	 * @public
	 * отступ сверху для элемента-контейнера с подсказкой
	 * @type Number
	 */
	this.marginTop = -5;

	/**
	 * @public
	 * отступ слева для элемента-контейнера с подсказкой
	 * @type Number
	 */
	this.marginLeft = -5;

	/**
	 * @public
	 * ширина элемента-контейнера с подсказкой
	 * @type Number
	 */
	this.hinter_width = 300;

	/**
	 * @public
	 * позиция подсказки относительно элемента для которого выводится подсказка
	 * @type String
	 */
	this.position = 'b';

	/**
	 * ссылка на самого себя, чтобы приватные методы могли обращаться к объекту
	 * @type fh_helper_class
	 */
	var __this = this;

	/**
	 * @public
	 * запускает подсказки для элементов формы
	 * подсказки будут активироваться по onFocus и убираться по onBlur
	 * желательно поместить вызов в window-onload
	 * 
	 * @param {Array/Object} taTargets - массив с массивами вида ['elem-id', 'текст подсказки']
	 * @return {Boolean} - FALSE если taTargets не массив
	 */
	this.form_runner = function(taTargets)
	{
		if (! (taTargets.constructor==Array  ||  taTargets.constructor==Object))
		{
			alert('fh_helper.form_runner\nПолучен не массив и не объект!');
			return false;
		}

		_copyTargets.call(this, taTargets);

		for (var lcKey in _fh_titles)
	    {
			var loObj = id(lcKey);
			if (loObj)
			{
				if (addEvent)
				{
					addEvent(loObj, 'focus', function(e) { _fh_show.call(this, e); });
					addEvent(loObj, 'blur', _fh_hide);
				}
				else
				{
					loObj.onfocus = function(e) { _fh_show.call(this, e); };;
					loObj.onblur = _fh_hide;
				}
			}
	    }

		return true;
	}

	/**
	 * 
	 * @param {Array/Object} taTargets - массив или объект с целями для подсказок
	 */
	function _copyTargets(taTargets)
	{
		_fh_titles = new Object();	// очищаем

		//	если получен массив
		if (taTargets.constructor==Array)
		{
			for (var i=0, lcKey='', lcTitle=''; i < taTargets.length; i++)
			{
				lcKey = taTargets[i][0];
				lcTitle = taTargets[i][1];

				_fh_titles[lcKey] = lcTitle;
			}
		}

		//	если получен объект
		if (taTargets.constructor==Object)
		{
		    for (var lcKey in taTargets) // обращение к свойствам объекта по индексу
		    {
		    	_fh_titles[lcKey] = taTargets[lcKey];
		    }
		}
	}

	/**
	 * @public
	 * запускает подсказки для элементов формы
	 * подсказки будут активироваться по onMouseOver и убираться по onMouseOut
	 * желательно поместить вызов в window-onload
	 * 
	 * @param {Array/Object} taTargets - массив с массивами вида ['elem-id', 'текст подсказки']
	 * @return {Boolean} - FALSE если taTargets не массив
	 */
	this.hover_runner = function(taTargets)
	{
		if (! (taTargets.constructor==Array  ||  taTargets.constructor==Object))
		{
			alert('fh_helper.hover_runner\nПолучен не массив и не объект!');
			return false;
		}
		
		_copyTargets.call(this, taTargets);

		for (var lcKey in _fh_titles)
		{
			var loObj = id(lcKey);
			if (loObj)
			{
				if (addEvent)
				{
					addEvent(loObj, 'mouseover', function(e) { _fh_show.call(this, e); });
					addEvent(loObj, 'mouseout', _fh_hide);
				}
				else
				{
					loObj.onmouseover = function(e) { _fh_show.call(this, e); };
					loObj.onmouseout = _fh_hide;
				}
			}
		}

		return true;
	}

	/**
	 * показывает "окошко" с подсказкой
	 * 
	 * @param {Event} e - ссылка на объект-событие
	 * @return {Boolean} void
	 */
	function _fh_show(e)
	{
		e = e || window.event;
		var loTarget = e.target || e.srcElement;

		//	если объект недоступен или только для чтения - ничего не показываем - выходим
		if (loTarget.readOnly  ||  loTarget.disabled) return false;

		var lcHelp = _fh_getHelp.call(this, loTarget.id);
		if (lcHelp == '') return false;

		_fh_hinter.innerHTML = lcHelp;

		_fh_hinter.style.width = __this.hinter_width + 'px';

		var laPos = _fh_getPos(loTarget);

		setXY(_fh_hinter, laPos[0], laPos[1]);

		_fh_hinter.style.display = 'block';

		return true;
	}

	/**
	 * @private
	 * рассчитывает координаты куда выводить блок с подсказкой
	 * 
	 * @param {HTMLElement} toTarget - ссылка на элемент для которого показываем подсказку
	 * @return {Number[]} - массив с координатами куда выводить подсказку 
	 */
	function _fh_getPos(toTarget)
	{
		var laPos = KL_getPageOffset(toTarget);
		var lnLeft = 0, lnTop = 0;
		var lnHeight = toTarget.offsetHeight;
		var lnWidth = toTarget.offsetWidth;
		
		switch(__this.position)
		{
			case 't':		//	показывать подсказки сверху от элемента
				lnTop =  laPos[1] - _fh_hinter.offsetHeight - __this.marginTop;
				lnLeft = laPos[0] + __this.marginLeft;
				break;

			case 'r':		//	показывать подсказки справа от элемента
				lnTop =  laPos[1];
				lnLeft = laPos[0] + lnWidth + __this.marginLeft;
	
				if ((lnLeft + __this.hinter_width + __this.marginLeft*3) >= pageWidth())
				{
					var lnMargin = (__this.marginLeft < 0) ? __this.marginLeft * -1 : __this.marginLeft;
					lnLeft = lnLeft + toTarget.offsetWidth - __this.hinter_width - lnMargin*2;
				}
				break;

			case "l":		//	показывать подсказки слева от элемента
				var lnTMargin = (__this.marginTop < 0) ? __this.marginTop * -1 : __this.marginTop;
				lnTop =  laPos[1] + lnTMargin;
				var lnLMargin = (__this.marginLeft < 0) ? __this.marginLeft * -1 : __this.marginLeft;
				lnLeft = laPos[0] - __this.hinter_width - lnLMargin*2;
				break;

			case 'b':		//	показывать подсказки снизу от элемента
				lnTop =  (laPos[1] + lnHeight + __this.marginTop);
				lnLeft = laPos[0];
	
				if ((lnLeft + __this.hinter_width + __this.marginLeft*3) >= pageWidth())
				{
					var lnMargin = (__this.marginLeft < 0) ? __this.marginLeft * -1 : __this.marginLeft;
					lnLeft = lnLeft + toTarget.offsetWidth - __this.hinter_width - lnMargin*2;
				}
				else lnLeft += __this.marginLeft;
		}

		return [lnLeft, lnTop];
	}

	/**
	 * @private
	 * возвращает ссылку на элемент-контейнер в котором будем выводить подсказки
	 * если нужно создает его 
	 * 
	 * @param {String} tcID - ID создаваемого элемента
	 * @param {String} tcClass - class создаваемого элемента
	 * @return {HTMLDivElement} - ссылка на элемент с подсказкой
	 */
	function _fh_Create(tcID, tcClass)
	{
		var loElem = id(this.hid);

		if (!loElem)
		{
			loElem = dce('div');
			loElem.id = tcID;
			if (tcClass != '') loElem.className = tcClass;
			dbac(loElem);
		}

		return loElem;
	}

	/**
	 * @private
	 * возвращает текст подсказки для элемента с ID равным tcID
	 * 
	 * @param {String} tcID - ID элемента для которого ищем подсказку
	 * @return {String} - текст подсказки для элемента с ID раным tcID
	 */
	function _fh_getHelp(tcID)
	{
		return (_fh_titles[tcID]) ? _fh_titles[tcID] : ''; 
	}

	/**
	 * @private
	 * прячет элемент-контейнер с подсказкой
	 * 
	 * @param {Event} e - ссылка на объект-событие (не используется)
	 * @return void
	 */
	function _fh_hide(e)
	{
		_fh_hinter.style.display = 'none';
	}
}

/**
//	пример массива который должен получить fh_helper_class.form_runner или fh_helper_class.hover_runner
var paFormHelperExample = new Array
(
	['id_of_element1', 'текст подсказки для этого элемента'],
	['id_of_element2', 'текст подсказки для этого элемента']
);
*/

/**
//	CSS-класс для блока с подсказкой
#form_helper_div
{
	display: none;
	position: absolute;
	z-index: 10;
	left: 100px;
	width: 200px;
	margin: 10px;
	padding: 5px;
	font-size: 1.1em;

	color :rgb(100, 30, 0);
	background-color: rgb(255, 255, 224);
	border: 1px solid rgb(100, 30, 0);

	text-align: left;
}
*/
