/**************
Copyright (c) 2002 Ryan Schaeffer

Version 1.0

This utility allows a website to easily incorporate / configure dhtml menus
into the site. The Menu object is associated and 'anchor'ed w/ the MenuAnchor
object.

REQUIRES browsercheck.js
**************/

var g_curanchor = null
var g_menuanchors = []
var g_menus = []
var g_z = 20
var g_speed = (is.ns6) ? 20 : 50
var loaded = false

function activateMenus() { 
	for (var i=0; i<g_menuanchors.length; i++) g_menuanchors[i].activate() 
	if(is.ns4) {
		window.captureEvents(Event.MOUSEMOVE)
		window.onmousemove = Handle_OnMouseMove
		window.onresize = function() { if (is.ns4) location = self.location }
	} else document.onmousemove = Handle_OnMouseMove
}
var g_build = g_extras = ''
function buildMenus() { for (var i=0; i<g_menuanchors.length; i++) g_build += g_menuanchors[i].build() }
function writeMenus() {
	document.write((is.ns?"<div style='visibility:hidden;left:-1000;top:-1000;'>":"") + g_build + g_extras + (is.ns?"</div>":"") ) 
}

function g_getAnchorObj(s_menu) {
	for (var i=0; i < g_menuanchors.length; i++) {
		if (g_menuanchors[i].getID() == s_menu) return g_menuanchors[i]
	}
	return null
}

function g_getOffsets(id) {
	var offsets = new Object()
	var p = eval(docObj + q + id + q + divObj)
	offsets.l = offsets.t = 0
	while(p!=null) {
		offsets.l += p.offsetLeft
		offsets.t += p.offsetTop
		p = p.offsetParent
	}
	return offsets
}
	
function g_InBounds(l, t) {
	if (!g_curanchor) return
	var x = new Object
	var y = new Object
	x.p0 = g_curanchor.bounds.l + 2
	y.p0 = g_curanchor.bounds.t
	x.p1 = x.p0 + g_curanchor.bounds.w - 2
	y.p1 = y.p0 + g_curanchor.bounds.h
	
	var menu = g_curanchor.getMenu()
	if (menu.vert) { // vertical
		x.p2 = menu.bounds.l
		x.p3 = x.p2 + menu.bounds.w
		y.p2 = y.p1 + menu.bounds.h
		return (l >= x.p0 && t >= y.p0 && l <= x.p1 && t <= y.p1) || (l >= x.p2 && t >= y.p1 && l <= x.p3 && t <= y.p2)
	} else { // horizontal
		y.p2 = menu.bounds.t
		y.p3 = y.p2 + menu.bounds.h
		x.p2 = x.p1 + menu.bounds.w	
		return (l >= x.p0 && t >= y.p0 && l <= x.p1 && t <= y.p1) || (t >= y.p2 && l >= x.p1 && t <= y.p3 && l <= x.p2)
	}
}

function Handle_OnMouseMove(e) {
	var evt = (is.ns) ? e : window.event
	var l = (is.ns)? evt.pageX : evt.clientX + document.body.scrollLeft
	var t = (is.ns)? evt.pageY : evt.clientY + document.body.scrollTop
	if (!g_curanchor) return
	var menu = g_curanchor.getMenu()
	if ( (menu && menu.state=='open') && !g_InBounds(l,t) ) {
		g_closeOpenMenus()
		//g_up(menu)
	}
}

function g_up(menu) {
	if (!menu) return
	menu.stop = true
	setTimeout(menu.obj+".slideOut()",g_speed)
}

function g_closeOpenMenus() {
	for (var i=0; i<g_menus.length; i++) {
		if (!g_menus[i].firstover) g_up(g_menus[i])
	}
}

function Handle_OnMouseOver(s_anchormenu,e) {
	if (!loaded) return
	var evt = (is.ns) ? e : window.event
	var anchorobj = g_getAnchorObj(s_anchormenu)
	g_curanchor = anchorobj
	if (!g_curanchor) return
	if (!is.supported) {
		if (g_curanchor.rolloverfunc!=null) eval(g_curanchor.rolloverfunc.func+g_curanchor.rolloverfunc.params_over)
		return
	}
	var menu = g_curanchor.getMenu()
	if (!menu || menu.state=='open' || menu.state=='opening') return
	if (g_curanchor.rolloverfunc!=null) eval(g_curanchor.rolloverfunc.func+g_curanchor.rolloverfunc.params_over)
	g_closeOpenMenus()
	if (menu.firstover || (is.mac && (is.ie || is.ns6))) { menu.initCoords(this) }
	menu.initSlide()
	setTimeout(menu.obj+".slideIn()",g_speed)
}

function Handle_OnMouseOut(s_anchormenu) {
	if (!loaded) return
	var anchorobj = g_getAnchorObj(s_anchormenu)
	g_curanchor = anchorobj
	if (!g_curanchor) return
	if (!is.supported) {
		if (g_curanchor.rolloverfunc!=null) eval(g_curanchor.rolloverfunc.func+g_curanchor.rolloverfunc.params_off)
	}
}

function g_MoveTo(id, x, y) {
	eval(docObj + q + id + q + styleObj + layerLeft + '=' + (x) )
	eval(docObj + q + id + q + styleObj + layerTop + '=' + (y) )
}

function g_MoveBy(id, x, y) {
	var newx = parseInt(eval(docObj + q + id + q + styleObj + layerLeft)) + x
	var newy = parseInt(eval(docObj + q + id + q + styleObj + layerTop)) + y
	g_MoveTo(id,newx,newy)
}


//*******************************************************************************************
//***************************** Menu Anchor *************************************************

function MenuAnchor(refid,w,h,l,t) {
	this.id = refid
	this.bounds = new Object
	this.bounds.h = h 
	this.bounds.w = w 

	this.dynamic = (l==null || t==null)
	this.bounds.l = l
	this.bounds.t = t

	this.rolloverfunc = null
	this.menu = null	
	g_menuanchors[g_menuanchors.length] = this

	this.obj = this.id + "Object"
	eval(this.obj + "=this")
}
{
var p = MenuAnchor.prototype
p.getID				= MenuAnchor_GetID
p.setMenu			= MenuAnchor_SetMenu
p.getMenu			= MenuAnchor_GetMenu
p.setRolloverInfo	= MenuAnchor_SetRolloverInformation
p.build				= MenuAnchor_BuildMenu
p.activate			= MenuAnchor_ActivateMenu
p.initCoords		= MenuAnchor_InitCoordinates
}
MenuAnchor.count = 0

function MenuAnchor_GetID() {	return this.id }
function MenuAnchor_SetMenu(m) { this.menu = m }
function MenuAnchor_GetMenu() { return this.menu }
function MenuAnchor_SetRolloverInformation(func, params_over, params_off) {
	this.rolloverfunc = new Object()
	this.rolloverfunc.func = func

	var paramlist = ''
	for (var i=0; i < params_over.length; i++) paramlist += '"' + params_over[i] + '",'
	if (params_over.length!=0) paramlist = paramlist.substring(0,paramlist.length-1)
	this.rolloverfunc.params_over = "(" + paramlist + ")"
	
	paramlist = ''
	for (var i=0; i < params_off.length; i++) paramlist += '"' + params_off[i] + '",'
	if (params_off.length!=0) paramlist = paramlist.substring(0,paramlist.length-1)
	this.rolloverfunc.params_off = "(" + paramlist + ")"
}
function MenuAnchor_BuildMenu() {	
	return (this.getMenu()) ? this.getMenu().build() : ''
}

function MenuAnchor_InitCoordinates() {
	if (!this.dynamic) return
	var offsets = (!is.ns4) ? g_getOffsets(this.getID()) : null
	this.bounds.l = (is.ns4) ? document.anchors[this.getID()].x : offsets.l
	this.bounds.t = (is.ns4) ? document.anchors[this.getID()].y : (offsets.t + (is.ns6 ? -5 : 0))
}

function MenuAnchor_ActivateMenu() {
	this.initCoords()
	if (this.getMenu()) this.getMenu().activate()
}

//*******************************************************************************************
//***************************** Menu  *******************************************************

function Menu(p,content) {
	this.id = 'libMenu'+(Menu.count++)
	this.content = content
	
	this.inc = 0
	this.zindex = 20
	this.stop = true
	this.state = 'closed'
	this.align = 'left'
			
	p.setMenu(this)
	this.parent = p
	this.vert = true
	this.bounds = new Object()
	this.clip = new Object()
	
	this.firstover = true
	g_menus[g_menus.length] = this

	this.obj = this.id + "Object"
	eval(this.obj + "=this")
}
{
var p = Menu.prototype
p.getID				= Menu_GetID
p.setParent			= Menu_SetParent
p.getParent			= Menu_GetParent
p.setHorizontal		= Menu_SetHorizontal
p.setVertical		= Menu_SetVertical
p.setAlignment		= Menu_SetAlignment
p.expand			= Menu_Expand
p.initSlide			= Menu_InitSlide
p.slideIn			= Menu_SlideIn
p.slideOut			= Menu_SlideOut
p.stopSlide			= Menu_StopSlide
p.collapse			= Menu_Collapse
p.build				= Menu_BuildMenu
p.initCoords		= Menu_InitCoordinates
p.activate			= Menu_ActivateMenu
p.clipTo			= Menu_ClipTo
p.clipBy			= Menu_ClipBy
}
Menu.count = 0

function Menu_GetID() { return this.id }
function Menu_SetParent(p) { this.parent = p }
function Menu_GetParent() { return this.parent }
function Menu_SetHorizontal() { this.vert = false }
function Menu_SetVertical() { this.vert = true }
function Menu_SetAlignment(position) { this.align = position }
function Menu_Expand() {
	eval(docObj + q + this.getID() + q + styleObj + '.visibility=' + visible)
}

function Menu_Collapse() { 
	eval(docObj + q + this.getID() + q + styleObj + '.visibility=' + hidden)
}

function Menu_BuildMenu() {
	this.div = 	"<DIV ID='"+this.getID()+"' STYLE='position:absolute; left:0; top:0; z-index:"+this.zindex+"; visibility:hidden;"+(!is.ie4?"width:0;":"")+"'>" + this.content + "</DIV>"
	return this.div
}

function Menu_InitCoordinates() {
	var divw = eval(docObj + q + this.getID() + q + divObj + dynWidth)
	var divh = eval(docObj + q + this.getID() + q + divObj + dynHeight)
	if (!is.ie4) {
		eval(docObj + q + this.getID() + q + styleObj + '.width='+divw)
		eval(docObj + q + this.getID() + q + styleObj + '.height='+divh)
	}
	this.bounds.h = divh
	this.bounds.w = divw

	var p = this.getParent()
	if (!p) return
	var dif = 0
	if (this.vert) {
		if (this.align=='center') dif = (this.bounds.w - p.bounds.w)/2
		else if (this.align=='right') dif = (this.bounds.w - p.bounds.w)
		this.bounds.l = (p.bounds.l-dif)
		this.bounds.t = (p.bounds.t+p.bounds.h)
		g_MoveTo(this.getID(), this.bounds.l, ((p.bounds.t+p.bounds.h)-this.bounds.h) )
	}
	else { // horizontal menu
		if (this.align=='center') dif = (this.bounds.h - p.bounds.h)/2
		else if (this.align=='bottom') dif = (this.bounds.h - p.bounds.h)
		this.bounds.l = (p.bounds.l+p.bounds.w)
		this.bounds.t = p.bounds.t
		g_MoveTo(this.getID(), ((p.bounds.l+p.bounds.w)-this.bounds.w), this.bounds.t)
	}
	this.firstover = false
}

function Menu_ActivateMenu() {
	if (is.ns4) { this.clip = eval(docObj + q + this.getID() + q + styleObj + ".clip") }
}

function Menu_ClipTo(t, r, b, l) {
	this.clip.top = t
	this.clip.right = r
	this.clip.bottom = b
	this.clip.left = l
	if (!is.ns4) eval(docObj + q + this.getID() + q + styleObj + ".clip = 'rect("+t+" "+r+" "+b+" "+l+")'")
}

function Menu_ClipBy(t, r, b, l) {
	this.clipTo( (this.clip.top + t), (this.clip.right + r), (this.clip.bottom + b), (this.clip.left + l) )
}

function Menu_InitSlide() {
	var p = this.getParent()
	if (this.inc == 0) this.inc = Math.ceil(this.bounds.h/(this.bounds.h*.05))
	if (this.vert) {
		this.clipTo(this.bounds.h, this.bounds.w, this.bounds.h, 0)
		g_MoveTo(this.getID(), this.bounds.l, ((p.bounds.t+p.bounds.h)-this.bounds.h) )
	} else {
		this.clipTo(0, this.bounds.w, this.bounds.h, this.bounds.w)	
		g_MoveTo(this.getID(), ((p.bounds.l+p.bounds.w)-this.bounds.w), this.bounds.t )
	}
	this.stop = false
	this.state = 'opening'
	this.expand()
}

function Menu_SlideIn() {
	if (!this.stop ) {
		if (this.vert) {
			if (this.clip.top > this.inc) {
				this.clipBy(-(this.inc),0,0,0)
				g_MoveBy(this.getID(), 0, this.inc)
				setTimeout(this.obj+".slideIn()",g_speed)
			} else this.stopSlide('open')
		} else {
			if (this.clip.left > this.inc) {
				this.clipBy(0,0,0,-(this.inc))
				g_MoveBy(this.getID(), this.inc, 0)
				setTimeout(this.obj+".slideIn()",g_speed)
			} else this.stopSlide('open')
		}
	}
}

function Menu_SlideOut() {
	if (this.stop ) {
		if (this.vert) {
			if (this.clip.top < (this.bounds.h-this.inc)) {
				this.clipBy(this.inc,0,0,0)
				g_MoveBy(this.getID(), 0, -(this.inc))
				setTimeout(this.obj+".slideOut()",g_speed)
			} else if (this.state!='closed') this.stopSlide('closed')
		} else {
			if (this.clip.left < (this.bounds.w-this.inc)) {
				this.clipBy(0,0,0,this.inc)
				g_MoveBy(this.getID(), -(this.inc), 0)
				setTimeout(this.obj+".slideOut()",g_speed)
			} else if (this.state!='closed') this.stopSlide('closed')
		}
	}
}

function Menu_StopSlide(newstate) {
	var p = this.getParent()
		if (this.vert) g_MoveTo(this.getID(), this.bounds.l, (p.bounds.t+p.bounds.h) )
		else g_MoveTo(this.getID(), (p.bounds.l+p.bounds.w), this.bounds.t )
	this.stop = true
	this.state = newstate
	if (this.state=='open') this.clipTo(0, this.bounds.w, this.bounds.h, 0)
	else {
		this.clipTo(0, this.bounds.w, this.bounds.h, this.bounds.w)
		this.collapse()
		if (p.rolloverfunc!=null) eval(p.rolloverfunc.func+p.rolloverfunc.params_off)
	}
}
