// popup-util.js : Saitistika Popup Library

///////////////////////////////////////////////////////////////////////////////
// DOCUMENTATION
///////////////////////////////////////////////////////////////////////////////
/*

1. Create and attach
~~~~~~~~~~~~~~~~~~~~

-------------------------------------------------------------------------------
__popup_create(src, minWidth, minHeight, className)
-------------------------------------------------------------------------------

	Creates popup IFRAME

 - src
	Required. Source url for popup frame
 - minWidth
	Optional. Minimum popup width
 - minHeight
	Optional. Minimum popup height
 - className
	Optional. CSS class name for popup IFRAME
 * Return Value
	Popup IFRAME element

-------------------------------------------------------------------------------
__popup_attach_click_element(popupFrame, params, clickableElement, alignElement)
-------------------------------------------------------------------------------

	Attaches popup to element (popup appears on click)

 - popupFrame
	Required. Popup IFRAME created with __popup_create()
 - params
	Required. Parameter array. Array elements are copied and therefore
	don't need to persist
 - clickableElement
	Required. HTML element to click on which which popup will be attached
 - alignElement
	Optional. HTML element to which popup will be aligned. If not specified,
	clickableElement becomes alignElement

-------------------------------------------------------------------------------
__popup_attach_click_id(popupFrame, params, clickableId, alignId)
-------------------------------------------------------------------------------

	Same as __popup_attach_click_element(), but resolves elements by its IDs

-------------------------------------------------------------------------------
__popup_attach_hover_element(popupFrame, params, hoverableElement, alignElement, hideTimeout)
-------------------------------------------------------------------------------

	Attaches popup to element (popup appears on mouseover)

 - popupFrame
	Required. Popup IFRAME created with __popup_create()
 - params
	Required. Parameter array. Array elements are copied and therefore
	don't need to persist
 - hoverableElement
	Required. HTML element to hover on which which popup will be attached
 - alignElement
	Optional. HTML element to which popup will be aligned. If not specified,
	clickableElement becomes alignElement
 - hideTimeout
	Optional. Timeout to hide popup, default is 200ms

-------------------------------------------------------------------------------
Additional popup properties
-------------------------------------------------------------------------------

 - popupgroup
	Optional string value. If set, only one popup with the matching group
	can be visible at any time.
 - disableFilter
	On fiter-enabled browsers (such as IE 5+) disables usage of filter to
	show or hide popup. By default, if blendTrans filter exists in popup
	IFRAME's style, this filter is used to animate popup. There is no
	blendTrans filter in style unless you use your own style in
	__popup_create().
 - onshow
	User-defined function can be assigned to this property. The function has
	one parameter - popup IFRAME, and called every time popup is shown.
 - onhide
	User-defined function can be assigned to this property. The function has
	one parameter - popup IFRAME, and called every time popup is about to be
	hidden.

-------------------------------------------------------------------------------
Popup frame implementation
-------------------------------------------------------------------------------

Page that loads in popup IFRAME is strongly recommended to use this script as
well as calling page. It is strongly recommended also to create HTML element
in popup that includes all its contents and has id "content". Popup will work
without it, byt it helps to ensure crossbrowser compatibility.

This script will insert parent's stylesheets into the popup frame in place of
the <script> tag. But this not works in all browsers, so it is receommended to
include fallback stylesheet after this script. Or, it can be not fallback but
complete stylesheet.

Function __popevent_initialize() (without parameters), if defined in popup frame,
will be called every time popup displayed by the user.

You can use the following helper functions inside popup script:

 - __popup_getPopup()
	Returns popup IFRAME element (defined in parent window).
 - __popup_getElement()
	Returns element (defined in parent window) to which this popup is attached.
 - __popup_getAlignElement()
	Returns element (defined in parent window) to which this popup is aligned.
 - __popup_getParams()
	Returns the copy of parameters array passwd to one of attach functions.
 - __popup_update()
	Updates popup position and size. Can be called to notify popup about content
	changes.
 - __popup_closeCurrentPopup()
	Closes popup by script. Can be called to close popup if user completes action
	the popup is supposed to, such as selecting date in calendar.

*/

///////////////////////////////////////////////////////////////////////////////
// CREATE AND ATTACH FUNCTIONS
///////////////////////////////////////////////////////////////////////////////

function __popup_create(src, minWidth, minHeight, className) {
	var holder = __popup_u_find('__popup_holder');
	if (!holder) {
		if (document.body.insertAdjacentHTML) {
			document.body.insertAdjacentHTML('AfterBegin', '<div id="__popup_holder"></div>');
			holder = __popup_u_find('__popup_holder');
		} else {
			holder = document.body;
		}
	}

	var frame =
		document.createElement('iframe');
	if (!frame) return null;

	frame.src = src;
	frame.scrolling = 'no';
	frame.frameBorder = 'no';
	frame.style.display = 'none';
	frame.style.position = 'absolute';
	frame.style.zIndex = 1000;
	frame.className = className;
	frame.__popup_p_minWidth = minWidth;
	frame.__popup_p_minHeight = minHeight;
	
	__popup_a_frames_all.push(frame);
	
	return holder.appendChild(frame);
}

function __popup_attach_click_element(popupFrame, params, clickableElement, alignElement) {
	if (!popupFrame || !__popup_is_popup(popupFrame)) return false;
	if (!clickableElement || clickableElement.__popup_p_frame) return false;
	if (!alignElement) alignElement = clickableElement;
	alignElement.__popup_p_element = clickableElement;
	alignElement.__popup_p_frame = popupFrame;
	alignElement.__popup_p_align = alignElement;
	alignElement.__popup_p_params = __popup_u_cloneArray(params);
	alignElement.onclick = __popup_handler_eat;
	alignElement.ondblclick = __popup_handler_click;
	clickableElement.__popup_p_frame = popupFrame;
	clickableElement.__popup_p_align = alignElement;
	clickableElement.onclick = __popup_handler_click;
	clickableElement.ondblclick = __popup_handler_click;
	return true;
}

function __popup_attach_click_id(popupFrame, params, clickableId, alignId) {
	return __popup_attach_click_element(popupFrame, params,
		__popup_u_find(clickableId), __popup_u_find(alignId));
}

function __popup_attach_hover_element(popupFrame, params, hoverableElement, alignElement, hideTimeout) {
	if (!popupFrame || !__popup_is_popup(popupFrame)) return false;
	if (!hoverableElement || hoverableElement.__popup_p_frame) return false;
	if (!alignElement) alignElement = hoverableElement;
	alignElement.__popup_p_element = hoverableElement;
	alignElement.__popup_p_frame = popupFrame;
	alignElement.__popup_p_hideTimeout = hideTimeout;
	alignElement.__popup_p_align = alignElement;
	alignElement.__popup_p_params = __popup_u_cloneArray(params);
	//alignElement.onmousemove = __popup_handler_mousemove;
	//alignElement.onmouseout = __popup_handler_mouseout;
	alignElement.onclick = __popup_handler_eat;
	alignElement.ondblclick = __popup_handler_eat;
	hoverableElement.__popup_p_frame = popupFrame;
	hoverableElement.__popup_p_hideTimeout = hideTimeout;
	hoverableElement.__popup_p_align = alignElement;
	hoverableElement.onmousemove = __popup_handler_mousemove;
	hoverableElement.onmouseout = __popup_handler_mouseout;
	return true;
}

function __popup_attach_hover_id(popupFrame, params, hoverableId, alignId, hideTimeout) {
	return __popup_attach_hover_element(popupFrame, params,
		__popup_u_find(hoverableId), __popup_u_find(alignId), hideTimeout);
}

///////////////////////////////////////////////////////////////////////////////
// HELPER FUNCTIONS
///////////////////////////////////////////////////////////////////////////////

function __popup_getPopup() {
	if (window.__popup_p_d_frame) {
		return window.__popup_p_d_frame;
	} else {
		return null;
	}
}

function __popup_getElement() {
	if (window.__popup_p_d_element) {
		return window.__popup_p_d_element;
	} else {
		return null;
	}
}

function __popup_getAlignElement() {
	var e = __popup_getElement();
	if (e && e.__popup_p_align) {
		return e.__popup_p_align;
	} else {
		return e;
	}
}

function __popup_getParams() {
	var e = __popup_getAlignElement();
	if (e && e.__popup_p_params) {
		return e.__popup_p_params;
	} else {
		return null;
	}
}

function __popup_update() {
	if (window.parent && window.parent != window) {
		window.parent.__popup_update();
	}
	__popup_f_reposition();
}

function __popup_closeCurrentPopup() {
	var popup = window.__popup_p_d_frame;
	if (popup) {
		__popup_f_hide(popup);
	}
}

///////////////////////////////////////////////////////////////////////////////
// PUBLIC UTILITIES
///////////////////////////////////////////////////////////////////////////////

function __popup_u_find(id, doc) {
	if (!doc) doc = document;
	for (var i = 0; i < __popup_special_IDs.length; i+=2) {
		if (__popup_special_IDs[i] == id) {
			return __popup_special_IDs[i+1];
		}
	}
	if (doc.getElementById) {
		return doc.getElementById(id);
	}
	if (doc.all) {
		return doc.all[id];
	}
	return null;
}

function __popup_u_getWindow(popup) {
	if (popup.contentWindow) {
		return popup.contentWindow;
	}
	if (popup.contentDocument) {
		return popup.contentDocument.window;
	}
	return null;
}

function __popup_u_getDocument(popup) {
	if (popup.contentDocument) {
		return popup.contentDocument;
	}
	if (popup.contentWindow) {
		return popup.contentWindow.document;
	}
	return null;
}

///////////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION
///////////////////////////////////////////////////////////////////////////////

function __popup_initStyles() {
	if (parent && parent != window && parent.document) {
		var ps = parent.document.styleSheets;
		if (ps) {
			for (var i = 0; i < ps.length; i++) {
				if (ps[i].href) {
					document.writeln('<link rel="stylesheet" type="' + ps[i].type + '" href="' + ps[i].href + '" />');
				}
			}
			return;
		}
		var pde = parent.document.documentElement;
		var pdh = pde.firstChild;
		while (pdh) {
			if (pdh.tagName.toLowerCase() == 'head') {
				var pdn = pdh.firstChild;
				while (pdn) {
					if (pdn.tagName.toLowerCase() == 'link' && pdn.rel.toLowerCase() == 'stylesheet' && pdn.href) {
						document.writeln('<link rel="stylesheet" type="' + pdn.type + '" href="' + pdn.href + '" />');
					}
					pdn = pdn.nextSibling;
				}
				return;
			}
			pdh = pdh.nextSibling;
		}
	}
}

function __popup_f_newMouse() {

	this.x = this.y = 32767;

	this.move = function(x, y) {
		this.x = x;
		this.y = y;
	}

	this.__popup_f_getLeft = function() {
		return this.x;
	}
	this.__popup_f_getTop = function() {
		return this.y;
	}
	this.__popup_f_getWidth = function() {
		return 0;
	}
	this.__popup_f_getHeight = function() {
		return 0;
	}
}

var __popup_mouse = new __popup_f_newMouse();
var __popup_special_IDs = ['mouse', __popup_mouse];

function __popup_u_getLeft(e) {
	if (e.__popup_f_getLeft) {
		return e.__popup_f_getLeft();
	} else {
		var p = e, v = e.offsetLeft;
		while ((p = p.offsetParent) != null)
			v += p.offsetLeft;
		return v;
	}
}

function __popup_u_getTop(e) {
	if (e.__popup_f_getTop) {
		return e.__popup_f_getTop();
	} else {
		var p = e, v = e.offsetTop;
		while ((p = p.offsetParent) != null)
			v += p.offsetTop;
		return v;
	}
}

function __popup_u_getWidth(e) {
	if (e.__popup_f_getWidth) {
		return e.__popup_f_getWidth();
	} else {
		return e.offsetWidth;
	}
}

function __popup_u_getHeight(e) {
	if (e.__popup_f_getHeight) {
		return e.__popup_f_getHeight();
	} else {
		return e.offsetHeight;
	}
}

function __popup_u_getIndex(e, a) {
	if (!a.length) return -1;
	for (var i = 0; i < a.length; i++)
		if (e == a[i]) return i;
	return -1;
}

function __popup_u_cloneArray(a) {
	var r = [];
	for (var i in a) r[i] = a[i];
	return r;
}

var __popup_a_frames_all = [];
var __popup_a_frames_active = [];
var __popup_a_delay_timers = [];

function __popup_f_cancelDelay(popup) {
	var ix = __popup_u_getIndex(popup, __popup_a_frames_all);
	if (ix >= 0 && __popup_a_delay_timers[ix]) {
		window.clearTimeout(__popup_a_delay_timers[ix]);
		__popup_a_delay_timers[ix] = null;
	}
}

function __popup_f_hide_byIndex(ix) {
	if (ix >= 0 && ix < __popup_a_frames_all.length)
		__popup_f_hide(__popup_a_frames_all[ix]);
}

function __popup_f_hide_delay(popup, e) {
	var delay = e.__popup_p_hideTimeout ? e.__popup_p_hideTimeout : 200;
	var ix = __popup_u_getIndex(popup, __popup_a_frames_all);
	if (ix >= 0) {
		__popup_f_cancelDelay(popup);
		__popup_a_delay_timers[ix] = window.setTimeout('__popup_f_hide_byIndex(' + ix + ');', delay);
	}
}

function __popup_f_getFilter(popup) {
	var has_filters = false;
	try {
		has_filters = popup.filters;
	} catch (e) {
	}
	if (!popup.disableFilter && has_filters)
		if (popup.filters && popup.filters['blendTrans'])
			return popup.filters['blendTrans'];
	return null;
}

function __popup_f_show(popup, e) {
	__popup_f_cancelDelay(popup);
	if (e.__popup_p_element)
		e = e.__popup_p_element;
	var bInit =
		popup.style.display == 'none' || popup.__popup_p_element != e ||
		popup.__popup_p_notInit;
	popup.__popup_p_element = e;
	if (bInit) {
		var w = __popup_u_getWindow(popup);
		if (w) {
			popup.__popup_p_notInit = false;
			w.__popup_p_d_window = window;
			w.__popup_p_d_frame = popup;
			w.__popup_p_d_element = e;
			if (w.__popevent_initialize) {
				w.__popevent_initialize();
			}
		} else {
			popup.__popup_p_notInit = true;
		}
		var filter = __popup_f_getFilter(popup);
		if (filter) filter.apply();
		popup.style.display = 'block';
		popup.style.visibility = 'visible';
		if (filter) filter.play();
	}
	if (bInit && popup.__popup_p_notInit) { // opera workaround
		var ix = __popup_u_getIndex(popup, __popup_a_frames_all);
		if (ix >= 0) {
			window.setTimeout('__popup_f_show_byIndex(' + ix + ')', 50);
		}
	}
	if (!__popup_is_active(popup))
		__popup_a_frames_active.push(popup);
	__popup_f_reposition(popup);
	if (popup.popupgroup) {
		__popup_f_hidegroup(popup.popupgroup, popup);
		__popup_f_pushgroup(popup.popupgroup, popup);
	}
	if (popup.onshow) {
		popup.onshow(popup);
	}
}

function __popup_f_show_byIndex(ix) {
	if (ix >= 0 && ix < __popup_a_frames_all.length) {
		var popup = __popup_a_frames_all[ix];
		var e = popup.__popup_p_element;
		__popup_f_show(popup, e);
	}
}

function __popup_f_hide(popup) {
	if (popup.onhide) {
		popup.onhide(popup);
	}
	var filter = __popup_f_getFilter(popup);
	if (filter) filter.apply();
	if (!filter) popup.style.display = 'none';
	popup.style.visibility = 'hidden';
	popup.left = -popup.offsetWidth;
	popup.top = -popup.offsetHeight;
	if (filter) filter.play();
	popup.__popup_p_element = null;
	if (popup.popupgroup) {
		__popup_f_remgroup(popup.popupgroup, popup);
	}
	for (var i = 0; i < __popup_a_frames_active.length; i++) {
		if (__popup_a_frames_active[i] == popup) {
			__popup_a_frames_active.splice(i, 1);
			return;
		}
	}
}

function __popup_f_hideAll() {
	while (__popup_a_frames_active.length > 0)
		__popup_f_hide(__popup_a_frames_active.pop());
}

function __popup_f_hidegroup(group, popup) {
	var grp = __popup_groups[group];
	if (grp) {
		for (var i = 0; i < grp.length; i++) {
			if (grp[i] != popup) __popup_f_hide(grp[i]);
		}
	}
}
function __popup_f_pushgroup(group, popup) {
	if (__popup_groups[group]) {
		__popup_groups[group].push(popup);
	} else {
		__popup_groups[group] = [popup];
	}
}
function __popup_f_remgroup(group, popup) {
	var grp = __popup_groups[group];
	if (grp) {
		var s = -1;
		for (var i = 0; i < grp.length; i++) {
			if (grp[i] == popup) {
				s = i; break;
			}
		}
		if (s == 0) {
			__popup_groups[group] = grp.slice(1);
		} else if (s > 0) {
			__popup_groups[group] = grp.slice(0, s-1).concat(grp.slice(s+1));
		}
	}
}

function __popup_f_reposition_atElement(popup, e) {
	var win = __popup_u_getWindow(popup);
	var doc = __popup_u_getDocument(popup);
	var bdy = document.body;

	var x = __popup_u_getLeft(e);
	var y = __popup_u_getTop(e);
	var cx = __popup_u_getWidth(e);
	var cy = 0;
	
	var pl = e.__popup_padding_left ? e.__popup_padding_left : null;
	var pr = e.__popup_padding_right ? e.__popup_padding_right : null;
	var dsbl_t = e.__popup_disable_top ? e.__popup_disable_top : null;
	var dsbl_b = e.__popup_disable_bottom ? e.__popup_disable_bottom : null;
	
	if (win && doc && doc.body && doc.body.style) {
		doc.body.style.margin = doc.body.style.padding = 0;
		var ce = __popup_u_find('e__popup_content', doc);
		if (!ce) {
			if (navigator.appName && navigator.appName == 'Netscape') {
				cy = doc.body.offsetHeight;
			} else {
				cy = doc.body.scrollHeight;
			}
		} else {
			cy = ce.offsetHeight;
		}
	}
	if (popup.__popup_p_minWidth && cx < popup.__popup_p_minWidth) {
		cx = popup.__popup_p_minWidth;
	}
	if (popup.__popup_p_minHeight && cy < popup.__popup_p_minHeight) {
		cy = popup.__popup_p_minHeight;
	}
	
	var t_y = y;
	y += __popup_u_getHeight(e) + 1;
	
	if (dsbl_b || (!dsbl_t && (y + cy > bdy.scrollTop + (bdy.clientHeight?bdy.clientHeight:bdy.offsetHeight)))) {
		t_y -= cy + 1;
		if (dsbl_b || (t_y >= bdy.scrollTop)) {
			y = t_y;
		}
	}
	
	if (pl) x += pl; cx -= pl;
	if (pr) y -= pr;
	
	var filter = __popup_f_getFilter(popup);
	if (filter && filter.status == 2) filter = null;
	if (filter) filter.apply();
	popup.style.left = x + 'px';
	popup.style.top = y + 'px';
	popup.style.width = cx + 'px';
	popup.style.height = cy + 'px';
	if (filter) filter.play();
}

function __popup_f_reposition(popup) {
	if (popup) {
		var e = popup.__popup_p_element; if (!e) return;
		if (e.__popup_p_align) e = e.__popup_p_align;
		__popup_f_reposition_atElement(popup, e);
	} else {
		for (var i = 0; i < __popup_a_frames_active.length; i++) {
			__popup_f_reposition(__popup_a_frames_active[i]);
		}
	}
}

function __popup_f_toggle(popup, e) {
	if (e.__popup_p_element)
		e = e.__popup_p_element;
	if (__popup_is_active(popup)) {
		if (popup.__popup_p_element == e) {
			__popup_f_hide(popup);
		} else {
			__popup_f_show(popup, e);
		}
	} else {
		__popup_f_show(popup, e);
	}
}

function __popup_is_popup(e) {
	for (var i = 0; i < __popup_a_frames_all.length; i++) {
		if (__popup_a_frames_all[i] == e)
			return true;
	} return false;
}

function __popup_is_active(e) {
	for (var i = 0; i < __popup_a_frames_active.length; i++) {
		if (__popup_a_frames_active[i] == e)
			return true;
	} return false;
}

function __popup_handler_eat(_evt) {
	if (_evt) {
		_evt.cancelBubble = true;
	} else if (event) {
		event.cancelBubble = true;
	}
}

function __popup_handler_click(_evt) {
	var target;

	if (_evt) {
		target = _evt.target ? _evt.target : _evt.srcElement;
		_evt.cancelBubble = true;
	} else if (event) {
		target = event.srcElement;
		event.cancelBubble = true;
	}
	if (!target) return true;

	var popup = null, e = null;

	if (target.__popup_p_frame) {
		popup = target.__popup_p_frame;
		e = target;
	} else if (target.__popup_p_element) {
		popup = target;
		e = target.__popup_p_element;
	}

	if (!popup || !e) return true;

	__popup_f_toggle(popup, target);
	popup.__popup_p_handleMouse = false;

	return false;
}

function __popup_handler_mousemove(_evt) {
	var target;

	if (_evt) {
		target = _evt.target ? _evt.target : _evt.srcElement;
		_evt.cancelBubble = true;
	} else if (event) {
		target = event.srcElement;
		event.cancelBubble = true;
	}
	if (!target) return true;

	var popup = null, e = null;

	if (target.__popup_p_frame) {
		popup = target.__popup_p_frame;
		e = target;
	} else if (target.__popup_p_element) {
		popup = target;
		e = target.__popup_p_element;
	}

	if (!popup || !e) return true;

	__popup_f_show(popup, e);
	popup.__popup_p_handleMouse = true;

	return false;
}

function __popup_handler_mouseout(_evt) {
	var target;

	if (_evt) {
		target = _evt.target ? _evt.target : _evt.srcElement;
		_evt.cancelBubble = true;
	} else if (event) {
		target = event.srcElement;
		event.cancelBubble = true;
	}
	if (!target) return true;

	var popup = null, e = null;

	if (target.__popup_p_frame) {
		popup = target.__popup_p_frame;
		e = target;
	} else if (target.__popup_p_element) {
		popup = target;
		e = target.__popup_p_element;
	}

	if (!popup || !e) return true;

	__popup_f_hide_delay(popup, e);
	popup.__popup_p_handleMouse = true;

	return false;
}

var __popup_groups = [];
var __popup_saved_window_load = window.onload;
var __popup_saved_window_resize = window.onresize;
var __popup_saved_window_scroll = window.onscroll;
var __popup_saved_document_click = document.onclick;
var __popup_saved_document_mousemove = document.onmousemove;
var __popup_saved_document_mouseout = document.onmouseout;

function __popup_event_window_load(_evt) {
	if (__popup_saved_window_load)
		__popup_saved_window_load(_evt);
}

function __popup_event_window_resize(_evt) {
	if (__popup_saved_window_resize)
		__popup_saved_window_resize(_evt);
		
	__popup_f_reposition();
}

function __popup_event_window_scroll(_evt) {
	if (__popup_saved_window_scroll)
		__popup_saved_window_scroll(_evt);
		
	__popup_f_reposition();
}

function __popup_event_document_click(_evt) {
	if (__popup_saved_document_click)
		__popup_saved_document_click(_evt);

	__popup_f_hideAll();
}

function __popup_event_document_mousemove(_evt) {
	if (__popup_saved_document_mousemove)
		__popup_saved_document_mousemove(_evt);

	try {
		if (_evt) {
			__popup_mouse.move(_evt.pageX, _evt.pageY);
		} else if (event) {
			__popup_mouse.move(event.clientX + document.body.scrollLeft, event.clientY + document.body.scrollTop);
		}
	} catch (e) {
		return;
	}
		
	var _window = window.__popup_p_d_window;
	var _popup = window.__popup_p_d_frame;
	var _e = window.__popup_p_d_element;
	
	if (!_window || !_popup || !_e || !_popup.__popup_p_handleMouse)
		return;

	_window.__popup_f_show(_popup, _e);
}

function __popup_event_document_mouseout(_evt) {
	if (__popup_saved_document_mouseout)
		__popup_saved_document_mouseout(_evt);

	var _window = window.__popup_p_d_window;
	var _popup = window.__popup_p_d_frame;
	var _e = window.__popup_p_d_element;
	
	if (!_window || !_popup || !_e || !_popup.__popup_p_handleMouse)
		return;

	_window.__popup_f_hide_delay(_popup, _e);
}

window.onload = __popup_event_window_load;
window.onresize = __popup_event_window_resize;
window.onscroll = __popup_event_window_scroll;
document.onclick = __popup_event_document_click;
document.onmousemove = __popup_event_document_mousemove;
document.onmouseout = __popup_event_document_mouseout;

__popup_initStyles();
