
function showCustomPopup(el, popupName, dx, dy, hideFun)
{
	var popup = document.getElementById(popupName);
	popup.el = el;
	popup.dx = dx;
	popup.dy = dy;
	popup.hideFun = hideFun;
	if (popup.src == 'about:blank'){
		var pPath = '';
		var w = window;
		while (w != null){
			if (w.pPath != null){
				popup.src = w.pPath + 'popup&id=' + popupName;
				return false;
			}
			w = w.parent;
		}
	}
	popup_show(popup);
	return false;
}

function popup_loading(popupName, focusOnPopup)
{
	// 10.05.06 amoro:
	// тело меню храним в DIV'е на странице, откуда меню вызывается;
	// подробнее см. комментарий в PM_Draw()
	var popup = document.getElementById(popupName);
	// 14.06.06 amoro:
	// начального содержимого может и не быть
	var initialContent = window.document.getElementById(popupName + '_initialHtml');
	if (initialContent != null)
	{
		var frame_body = window.frames[popupName].document.body;
		frame_body.innerHTML = initialContent.innerHTML;
	}
	popup_show(popup, focusOnPopup);
}

// 14.06.06 amoro:
// иногда не нужно передавать фокус во всплывающее окно
function popup_show(popup, focusOnPopup)
{
	if (focusOnPopup == null)
		focusOnPopup = true;
	if(popup.el == null)
		return;
	popup.style.display = '';
	var a = popup.el.parentNode;
	var x = a.offsetWidth;
	var y = a.offsetHeight;
	while (a != null){
		x += a.offsetLeft;
		y += a.offsetTop;
		a = a.offsetParent;
	}
	if (popup.dx != null)
		x += popup.dx;
	if (popup.dy != null)
		y += popup.dy;
	var frame_body = window.frames[popup.id].document.body;
	var mainEl = frame_body.firstChild;
	while (mainEl != null)
	{
		if (mainEl.tagName == 'TABLE' || mainEl.tagName == 'DIV')
			break;
		mainEl = mainEl.nextSibling;
	}
	var height = popup.offsetHeight;
	if (mainEl != null)
	{
		popup.style.width = mainEl.offsetWidth;
		height = mainEl.offsetHeight;
	}
	if (popup.dh != null)
		height += popup.dh;
	var win_bottom = document.body.scrollTop + document.body.clientHeight;
	if (win_bottom < (y + height + 3))
		height = win_bottom - y - 3;
	if (height > 0)
		popup.style.height = height;
	popup.style.top  = y;
	if (x - popup.offsetWidth < 0){
		popup.style.left = x - popup.el.parentNode.offsetWidth;
	}else{
		popup.style.left = x - popup.offsetWidth;
	}
	if (focusOnPopup)
		popup.focus();
	setHandleOnFrames(window.top, popup, popup.hideFun);
	if (popup.afterShow)
		popup.afterShow();
}

window.popup_loading = popup_loading;

function popup_blur()
{
	hidePopup();
}
	
function popup_mouseup()
{
	hidePopup();
}

function hidePopup()
{
	// 05.07.06 amoro:
	// если есть календарь, скроем и его
	if (typeof(cal) != "undefined")
		cal.hideCalendar();
	// 16.05.06 amoro:
	// работаем не с текущим window, а с window.top
	var wnd = window.top;
	var popup = wnd.popup;
	if (popup == null)
		return;
	popup.style.display = 'none';
	restoreHandleOnFrames(wnd);
}

window.hidePopup = hidePopup;

function setHandleOnFrames(wnd, popup, popup_hide)
{
	var doc = wnd.document;
	// 31.08.06 amoro:
	// вместо ненадежного сохранения старых обработчиков
	// во вспомогательных полях, воспользуемся механизмом
	// множественных обработчиков
	if (doc.attachEvent)
	{
		// эмпирически установил, что IE в нарушение стандартов
		// позволяет назначать сколько угодно одинаковых обработчиков,
		// что нежелательно
		doc.detachEvent('onblur', popup_blur);
		doc.detachEvent('onmouseup', popup_mouseup);
		doc.attachEvent('onblur', popup_blur);
		doc.attachEvent('onmouseup', popup_mouseup);
	}
	else if (doc.addEventListener)
	{
		doc.addEventListener('blur', popup_blur, false);
		doc.addEventListener('mouseup', popup_mouseup, false);
	}
	wnd.popup			= popup;
	wnd.popup_hide		= popup_hide;
	var frames = wnd.frames;
	for (var i = 0; i < frames.length; i++){
		if (frames[i].name == "context_annotation_popup")
			continue;
		try{
			setHandleOnFrames(frames[i], popup);
		}catch (e){
		}
	}
}

function restoreHandleOnFrames(wnd)
{
	var doc				= wnd.document;
	// 31.08.06 amoro:
	// вместо ненадежного сохранения старых обработчиков
	// во вспомогательных полях, воспользуемся механизмом
	// множественных обработчиков
	if (doc.detachEvent)
	{
		doc.detachEvent('onblur', popup_blur);
		doc.detachEvent('onmouseup', popup_mouseup);
	}
	else if (doc.removeEventListener)
	{
		doc.removeEventListener('blur', popup_blur, false);
		doc.removeEventListener('mouseup', popup_mouseup, false);
	}
	if (wnd.popup_hide != null)
		wnd.popup_hide();
	wnd.popup			= null;
	
	var frames = wnd.frames;
	for (var i = 0; i < frames.length; i++){
		try{
			restoreHandleOnFrames(frames[i]);
		}catch (e){
		}
	}
}


function showDialog(url, w, h)
{
	window.dialogResult = null;
	if (window.showModalDialog){
		window.showModalDialog(url, window, 
			'dialogWidth:' + w + 'px;' +
			'dialogHeight:' + h + 'px;' +
			'status:no;resizeable:no;scroll:no;help:no');
	}
	else
	{
		window.top.captureEvents (Event.CLICK|Event.FOCUS);
		winModalWindow = 
		window.open (url, "ModalChild",
			"dependent=yes,status=no," +
			"width=" + w + "," +
			"height=" + h + "," +
			"screenX=" + (screen.width - w) / 2 + "," +
			"screenY=" + (screen.height - h) / 2 );
		winModalWindow.focus();
		window.top.onclick=IgnoreEvents;
		window.top.onfocus=HandleFocus;
	}
	return window.dialogResult;
}

// 31.03.06 amoro:
// добавил передачу доп. параметров (params)
// 06.07.06 amoro:
// добавил передачу номера области
function openClassif(attrname,numAttrInFindAttrs,areaNum,formAttrName,pPath,params){
	//получаем hidden
	var hiddenInput = window.document.forms["findAttrs"][formAttrName];
	
	// 18.04.06 amoro:
	// надо также передавать сведения о выбранной вкладке (ее поисковых объектах)
	var selWhere = window.document.forms["findAttrs"]["selwhere"];

	// 22.05.06 amoro:
	// тип логического объединения множественных значений классификаторов (И/ИЛИ/НЕ)
	var lop = window.document.forms["findAttrs"][formAttrName+"lop"];
	
	// 03.06.2007 kulch:
	// переделка вызова для получения диалога с новыми html-списками
	var queryUrl = pPath + 'find_selectclassif&title=' + escape(attrname) + 
		'&sel=' + hiddenInput.value + '&log_ops=true&lop=' + lop.value +
		'&attr=' + numAttrInFindAttrs + '&area=' + areaNum + '&selwhere=' + 
		selWhere.value + '&multi=1' + params;

	var res = showDialog(queryUrl, 600, 500);
	if(res != null)
	{
		// 30.03.06 amoro:
		// Сохранение результатов диалога в элементах формы
		hiddenInput.value = res.ID;
		var namesDisp = window.document.forms["findAttrs"][formAttrName + "_string"];
		namesDisp.value = res.Name;
		lop.value = res.LogicalOp;
		return true;
	}
	return false;
}

// 10.05.06 amoro:
// Из-за того, что меню может понадобиться раньше, чем
// оно первый раз отобразиться (и его фрейм загрузиться),
// приходится хранить начальный вариант тела меню в спец.
// DIV'е; в нижележащих функциях обрабатываются оба варианта
// (либо DIV, либо, если загружен, то фрейм)

function getMenuDoc(menuName)
{
	var frm = document.getElementById(menuName);
	if ((frm == null) || (frm.src == 'about:blank'))
		return window.document;
	var doc = window.frames[menuName].document;
	if (typeof(doc) == "undefined")
		return window.document;
	return doc;
}

// выбор элемента всплывающего меню
function selectPopupMenuItem(menuName, newId, oldId)
{
	var doc = getMenuDoc(menuName);
	
	var selItem = doc.getElementById(menuName + '_selected_item');
	if (oldId == null)
	{
		if (selItem != null)
			oldId = selItem.value;
	}
	if ((oldId+"") != "")
	{
		var oldCheckTag = doc.getElementById(menuName + "_ct_" + oldId);
		if (oldCheckTag != null)
			oldCheckTag.innerHTML = "";
	}
	var newCheckTag = doc.getElementById(menuName + "_ct_" + newId);
	var gurl = 'galka.gif';
	if (newCheckTag != null)
		newCheckTag.innerHTML = '<IMG ID="' + menuName + '_ci_' + newId + '" ALT="x" WIDTH=8 HEIGHT=8 SRC="' + gurl + '">';
	if (selItem != null)
	{
		selItem.value = newId;
	}
}

// сокрытие пункта меню
function hideMenuItem(name, id)
{
	var doc = getMenuDoc(name);
	var item = doc.getElementById(name + '_bar_' + id);
	if (item != null)
		item.style.display = 'none';
}

// показ пункта меню, опционально можно сделать его выбранным
function showMenuItem(name, id, active)
{
	var doc = getMenuDoc(name);
	if (active == null)
		active = false;
	var item = doc.getElementById(name + '_bar_' + id);
	if (item != null)
	{
		item.style.display = '';
		if (active)
			selectPopupMenuItem(name, id);
	}
}

// получение метки выбранного пункта меню
function getCheckedMenuItemId(name)
{
	var doc = getMenuDoc(name);
	var selItem = doc.getElementById(name + '_selected_item');
	if (selItem == null)
		return null;
	return selItem.value;
}

//	позиционирование в поле ввода однострочного текста
function getCaretPosition(el)
{
	if (document.selection)
	{
		// поганый IE
		var range = document.selection.createRange();
		range.moveStart('textedit', -1);
		return range.text.length;
	}
	else if (el.selectionStart)
	{
		// Gecko
		return el.selectionStart;
	}
	return el.value.length-1;
}

function setCaretPosition(el, pos)
{
	if (el.createTextRange)
	{
		// поганый IE
		var range = el.createTextRange();
		range.collapse(true);
		range.moveEnd('character', pos);
		range.moveStart('character', pos);
		range.select();
	}
	else if (el.selectionEnd)
	{
		// Gecko
		el.selectionEnd = pos;
	}
}

// получение границ слова (разделитель - пробел), на котором стоит курсор в поле ввода
function getInputSelectedWordCoords(el, str)
{
	var pos = getCaretPosition(el);
	var i, j;
	if (pos == 0)
		i = 0;
	else
		for	(i = pos-1; str.charAt(i) != ' ' && i > 0; i--);
	if (str.charAt(i) == ' ')
		i++;
	for (j = pos; str.charAt(j) != ' ' && j < str.length; j++);
	if (j < str.length && str.charAt(j) != ' ') // j-й символ не будет включен в результат
		j++;
	return { begin: i, end: j };
}

function getInputValueForAC(el, allowSpaces)
{
	var str = el.value + '';
	if (allowSpaces)
		return str;
	if (str.indexOf(' ') == -1)
		return str;
	var coords = getInputSelectedWordCoords(el, str);
	return str.substring(coords.begin, coords.end);
}

function setInputValueFromAC(el, str, allowSpaces, fullStr)
{
	if (str == null || str == ' ')
		return false;
	str = str.replace("&amp;", "&");
	if (fullStr != null && fullStr)
	{
		el.value = str;
		el.focus();
		window.elementForACFocus = el;
		return true;
	}
	if (!allowSpaces)
	{
		var sp_ind = str.indexOf(' ');
		if (sp_ind != -1)
			str = str.substring(0, sp_ind);
	}
	var old_str = el.value + '';
	var coords = getInputSelectedWordCoords(el, old_str);
	el.value = old_str.substring(0, coords.begin) + str + old_str.substring(coords.end);
	el.focus();
	window.elementForACFocus = el;
	setCaretPosition(el, coords.begin + str.length);
	return true;
}


// показ всплывающего меню вариантов ввода
function showACSuggestion(el, id, area, attr, allowSpaces, dx, dy, hid)
{
	if (dx == null)
		dx = 3;
	if (dy == null)
		dy = -2;
	var str = getInputValueForAC(el, allowSpaces);
	window[id + '_str'] = str;
	var hname = id + '_hint';
	var hfElm = document.getElementById(hname);
	var hf  = frames[hname];
	var pop = window.top.popup;
	if (pop == null || pop.name != hname)
	{
		if (pop != null)
			hidePopup();
		hfElm.el = el;
		hfElm.dx = dx;
		hfElm.dy = dy;
		hfElm.dh = 5;
		hfElm.hideFun = abortACSuggest;
		hfElm.afterShow = afterShowACSugg;
		if (hfElm.src == 'about:blank')
		{
			var url = window.pPath + 'achint&id=' + hname + '&str=' + escape(str) + '&w=' + el.offsetWidth;
			if (area != null && attr != null)
				url += '&area=' + area + '&attr=' + attr;
			if (allowSpaces)
				url += '&spaces=on';
			if (hid != null)
			{
				url += '&hid=' + hid + '&full_str=' + escape(el.value);
			}
			hfElm.src = url;
			return;
		}
	}
	if (hf.loadData)
		hf.loadData(str, area, attr, el.value, hid);
}

function afterShowACSugg()
{
	var pwnd = frames[this.id];
	var sc = pwnd.search_complete;
	if (sc && pwnd.searchComplete)
		pwnd.searchComplete();
}

// отмена построения списка вариантов
window.elementForACFocus = null;
function abortACSuggest()
{
	var pop = window.top.popup;
	if (pop == null)
		return;
	if (window.elementForACFocus != null)
		window.elementForACFocus.focus();
	var pwnd = frames[pop.id];
	if (pwnd.abortLoading)
		pwnd.abortLoading();
}

// обработка нажатий клавиш в поле ввода со всплывающим меню вариантов
function inputWithACKeyUp(el, e, id, area, attr, allowSpaces, dx, dy, hid)
{
	if (allowSpaces == null)
		allowSpaces = false;
	if (e == null)
		e = window.event;
	if (e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 13)
		return; // клавиши вверх/вниз обрабатываются в другом месте
	showACSuggestion(el, id, area, attr, allowSpaces, dx, dy, hid);
}

// обработка нажатий спец. клавиш в поле ввода со всплывающим меню вариантов
function inputWithACKeyDown(el, e, id, allowSpaces)
{
	if (allowSpaces == null)
		allowSpaces = false;
	if (e == null)
		e = window.event;
	var pop = window.top.popup;
	if (pop == null || pop.name != (id + '_hint'))
		return true;
	var pwnd = frames[pop.id];
	switch(e.keyCode)
	{
		case 38:
			pwnd.selectPrev();
			return false;
		case 40:
			pwnd.selectNext();
			return false;
		case 13:
			if (pwnd.cannotSort())
			{
				e.cancelBubble = true;
				return false;
			}
			var str = pwnd.getSelection();
			hidePopup();
			// 30.08.06 amoro:
			// если ничего не выбрали в ниспадающем списке,
			// то надо отправлять запрос с тем, что ввел пользователь,
			// иначе, надо просто заменить текущее слово на выбранное
			if (str == null || str.Value == null || str.Value == '')
				return true;
			setInputValueFromAC(el, str.Value, allowSpaces, str.Type == 1);
			e.cancelBubble = true;
			return false;
	}
	return true;
}

// выбор конкретного варианта из списка
function chooseACSugg(id, str, allowSpaces, fullStr)
{
	if (id == null || str == null || str == '')
		return;
	var idLen = id.length;
	if (idLen <= 5 || id.substring(idLen-5) != '_hint')
		return;
	var eid = id.substring(0, idLen-5);
	var el = document.getElementById(eid);
	if (el == null)
		return;
	if (!setInputValueFromAC(el, str, allowSpaces, fullStr))
		return;
}

window.chooseACSugg = chooseACSugg;

