/*	menu.js
	Hierarchical menu using CSS and (where CSS is not enough) JavaScript+DOM

	Artur Zaprzała <zybi@talex.pl>
	Talex S.A. http://www.talex.pl/
	2002 - initial release
	2003 - portability improvements, cleanup, optimizations
	Works with: Mozilla 1.0, Konqueror 3.0, Opera 6.02/7.11, IE 5.0/5.5/6.0
*/

// config
var menu_id = 'm'
var menu_sep = 'm'
var menu_tr_id = 'mr'
var menu_delay = 250	// [ms]
var menu_box_top_padding = 2	// paddingTop
var menu_box_lr_padding = 0	// paddingLeft + paddingRight
var menu_box_border = 1
var menu_x_offset = -.1	// fraction of height
var menu_y_offset = .2	// fraction of height

if (!Array.prototype.pop) Array.prototype.pop = function () {	// pop method for IE 5.0 :(
	var v = this[this.length-1]
	this.length--
	return v
}
var m_timeout_id
var m_active = []
var m_tuned_width	// to detect window resize
var isopera = navigator.appName==='Opera'
var poor_opera = isopera && !document.childNodes	// hacks for Opera 6.x :(
var isopera7 = isopera && !poor_opera			// hacks for Opera 7.x :(
// REMEMBER: operator `in' is missing in IE 5.0 :(

function menu_hide(n) {
	while (m_active.length>n) m_active.pop().style.visibility = 'hidden'
}
function menu_hide_all() {
	m_timeout_id = null
	menu_hide(0)
	if (m_tuned_width!=document.body.offsetWidth) menu_layout()
}
function menu_onover(event) {
	if (m_timeout_id!=null) {
		window.clearTimeout(m_timeout_id)
		m_timeout_id = null
	}
	if (!this.submenu || m_active.length>this.m_level && this.submenu!==m_active[this.m_level])
		 menu_hide(this.m_level)
	if (this.submenu)
		(m_active[this.m_level] = this.submenu).style.visibility = 'visible'
}
var menu_hide_func = navigator.appName==='Konqueror' ? "menu_hide_all()" : menu_hide_all
function menu_onout(event) {
	if (m_timeout_id!=null) window.clearTimeout(m_timeout_id)
	m_timeout_id = window.setTimeout(menu_hide_func, menu_delay)
}
function is_menu_item(item) {
	// menu items have no class attribute specified
	if (item.nodeType) {		// DOM
		return item.nodeType===1 && !item.className
	} else if (item.getAttribute) {	// Opera 6 :(
		return typeof item.getAttribute('class')==="string"
	} else return false
}
function submenu_layout(menu, level, x0, y0) {
	// vertical menu
	//if (window.init_drag) init_drag(menu)	// XXX
	menu.onmouseover = menu_onover
	menu.onmouseout = menu_onout
	menu.submenu = menu
	menu.m_level = level
	var items = menu.childNodes
	var i = 0
	for (var j = 0; j<items.length; ++j) {
		var item = items[j]
		if (!is_menu_item(item)) continue
		var submenu = document.getElementById(menu.id+menu_sep+i++)
		if (submenu) {
			var x = x0+item.offsetWidth +menu_box_lr_padding+menu_box_border+menu_x_offset*item.offsetHeight
			var y = y0+item.offsetTop -menu_box_top_padding+menu_y_offset*item.offsetHeight
			if (poor_opera) y-= menu_box_border
			if (isopera7) submenu.style.width = submenu.offsetWidth+'px' // for style.left affects width in Opera
			submenu.style.left = x+'px'
			submenu.style.top = y+'px'
			submenu_layout(submenu, level+1, x, y)
			item.onblur = item.onmouseout = menu_onout
		}
		item.submenu = submenu
		item.m_level = level+1
		item.onfocus = item.onmouseover = menu_onover
	}
}
function menu_layout() {
	m_tuned_width = document.body.offsetWidth
	// horizontal menu
	var menu = document.getElementById(menu_tr_id)	// tr
	if (menu==null || menu.childNodes==null) return	// no menu or poor DOM
	var h = menu.parentNode.parentNode.offsetHeight	// menu root height (table)
	var items = menu.childNodes
	var i = 0
	var base = document.getElementById(menu_id).firstChild	// menu-base
	var x0 = base.offsetLeft
	var y0 = base.offsetTop
	for (var j = 0; j<items.length; ++j) {
		var item = items[j]
		if (!is_menu_item(item)) continue
		item = item.firstChild	// td.div
		var submenu = document.getElementById(menu_sep+i++)
		if (submenu) {
			var x = x0+item.parentNode.offsetLeft
			var y = y0+(item.offsetHeight+h)/2
			//if (item.parentNode.parentNode.offsetLeft<0) x+= item.offsetLeft	// Mozilla bug (1.0rc3)
			if (isopera7) submenu.style.width = submenu.offsetWidth+'px' // changing style.left would affect width in Opera
			submenu.style.left = x+'px'
			submenu.style.top = y+'px'
			submenu_layout(submenu, 0, x, y)
			item.onfocus = item.onmouseover = menu_onover
			item.onblur = item.onmouseout = menu_onout
			item.m_level = 0
		}
		item.submenu = submenu
	}
	if (poor_opera) {	// position marks in Opera 6.x (style.right is not implemented) :(
		items = document.getElementById(menu_id).getElementsByTagName('span')
		for (i=0; i<items.length; ++i) {
			var ob = items[i]
			if (ob.parentNode.parentNode.parentNode.id!=menu_id) continue
			ob.style.left = ob.parentNode.offsetLeft+ob.parentNode.offsetWidth-ob.offsetWidth+'px'
			//ob.style.left = ob.parentNode.parentNode.offsetWidth-2*ob.parentNode.offsetLeft-ob.offsetWidth+'px'

		}
	}
}
function DOMify_opera() {
	var items = document.getElementById(menu_id).getElementsByTagName('div')
	for (i=0; i<items.length; ++i) {
		var p = items[i].parentNode
		var p0 = p.parentNode
		if (p.childNodes==null) {
			p.childNodes = []
			p.firstChild = items[i]
		}
		if (p0.childNodes==null)
			p0.childNodes = []
		p0.childNodes.push(p)
		p.childNodes.push(items[i])
	}
}
function menu_init() {
	if (!document.getElementById) return	// no DOM
	if (poor_opera) DOMify_opera()
	menu_layout()
}
window.onload = menu_init

