/*
 * Flyout menus for the University of Washington Home Page
 * University of Washington / Computing and Communications
 * April, 2000
 * Documentation can be found at
 *     http://www.washington.edu/webinfo/case/flyout/
 * $Id: flyout.js,v 1.10 2000/04/12 00:13:19 fmf Exp $
 */

var d = document;
var doDHTML = 0;

if (d.layers || d.all) {
    doDHTML = 1;

    initFlyLyr ();
    initToShow ();
    initDelay ();

    d.write ("<style type='text/css'>" +
		".flyout { visibility: hidden; position: absolute; " +
		"left: 0; top: 0; }<\/style>");
}

function makeLayer (id, title) {
    if (! doDHTML)
	return;
    var a = arguments;
    var numsp = new Array;
    numsp.max = 0;
    for (var j = 2; j < a.length; ++j) {
	numsp[j] = a[j].length;
	a[j] = a[j].replace (/^ +/, '');
	numsp[j] -= a[j].length;
	numsp.max = Math.max (numsp[j], numsp.max);
    }
    var fd = FlyLyr.defs;
    d.write ("<div id='l_" + id + "' class='flyout'>" +  
		"<table cellpadding='2' cellspacing='0' border='1' bgcolor='" +
		fd.background + "' bordercolor='" + fd.border + "'>");
    if (title) {
	var titleargs = "align='center'";
	if (fd.titlebackground)
	    titleargs += " bgcolor='" + fd.titlebackground + "'";
	d.write ("<tr>" +
		    buildCell (title,
				fd.titleclass ? fd.titleclass : fd.useclass,
				titleargs) + "<\/tr>");
    }
    var divstart = "<tr><td><table cellpadding='1' cellspacing='0' " +
		    "border='0'>\n";
    d.write (divstart);
    for (j = 2; j < a.length; ++j) {
	if (! a[j]) {
	    d.write ("<\/table><\/td><\/tr>" + divstart);
	    continue;
	}
	var args = null;
	var i = numsp[j];
	if (i < numsp.max)
	    args = "colspan=" + (numsp.max - i + 1);
	d.write ("<tr>");
	while (i-- > 0)
	    d.write ("<td><font size='1'>&nbsp;&nbsp;<\/font><\/td>");
	d.write (buildCell (a[j], fd.useclass, args) + "<\/tr>\n");
    }
    d.write ("<\/table><\/td><\/tr><\/table><\/div>\n");
    new FlyLyr (id);
}

function buildCell (str, fc, args) {
    var retstr = "<td";
    if (args)
	retstr += " " + args;
    var eqpos = str.indexOf ("=");
    if (eqpos > 0)
	retstr += "><a href='" + str.substr (eqpos + 1) + "'><font class='" +
		    fc + "'>" + str.substr (0, eqpos) + "<\/font><\/a>";
    else
	retstr += " class='" + fc + "'>" + str;
    return retstr + "<\/td>";
}

function positionLayerNS () {
    var img = this.image;
//    var ypos = img.y - 2;
    var ypos = img.y+17;
    var moveup = ypos + this.lyr.clip.bottom + FlyLyr.unmacOffset -
    			window.pageYOffset - window.innerHeight;
    if (moveup > 0)
    	ypos -= moveup;
    //this.lyr.moveTo (img.x + img.width + 2, ypos);
   this.lyr.moveTo (img.x - 2, ypos);
}

function positionLayer () {
    var img = this.image;
    //var xpos = img.offsetWidth;
    var xpos = -2;
    var ypos = 0;
    if (FlyLyr.usepos['startX'])
	xpos += FlyLyr.usepos['startX'];
    if (FlyLyr.usepos['startY'])
	ypos += FlyLyr.usepos['startY'];
    for (; img && img.parentElement; img = img.parentElement)
	if (FlyLyr.usepos[img.tagName]) {
	    xpos += img.offsetLeft;
	    ypos += img.offsetTop;
	}
    var moveup = ypos + this.lyr.offsetHeight -
		    d.body.scrollTop - d.body.clientHeight;
    if (moveup > 0)
	ypos -= moveup;
    this.lyr.style.pixelLeft = xpos;
    this.lyr.style.pixelTop = ypos;
    if (this.tbl)
	this.lyr.style.clip = 'rect ( 0px ' + this.tbl.offsetWidth + 'px ' +
				this.tbl.offsetHeight + 'px 0px )';
}

function FlyLyr (id) {
    this.lyr = findObj ('l_' + id);
    if (! d.all) {
        this.lyr.captureEvents (Event.MOUSEOUT | Event.MOUSEOVER);
	this.lyr.bgColor = FlyLyr.defs.background;
    }
    this.lyr.onmouseover = function () {
	FlyLyr.showing.stopdelay ()
	ToShow.stopdelay ();
    };
    this.lyr.onmouseout = function () { mOut () };
    this.id = id;
    if (this.lyr.children && FlyLyr.unmacOffset)
	this.tbl = this.lyr.children[0];
    FlyLyr.lyrs[id] = this;
    for (var a in FlyLyr.defs)
	this[a] = FlyLyr.defs[a];
}

function flyDefs (defs) {
    if (! defs)
	return;
    for (var d in defs)
	FlyLyr.defs[d] = defs[d];
}

function initFlyLyr () {
    FlyLyr.prototype.doHide = function () {
	this.stopdelay ();
	this.realHide ();
	this.image.src = this.outimg;
	FlyLyr.showing = null;
    };
    FlyLyr.prototype.doShow = function () {
	if (! this.image && ! (this.image = findObj (this.id)))
	    return;
	this.position ();
	this.realShow ();
	this.image.src = this.overimg;
	FlyLyr.showing = this;
    };
    FlyLyr.prototype.delayCallback = function () {
	if (this == FlyLyr.showing)
	    this.doHide ();
    };
    FlyLyr.prototype.setdelay = function () {
	this.delay = new Delay (this.timeout, this);
    };
    FlyLyr.prototype.stopdelay = function () {
	if (this.delay)
	    this.delay.stop ();
	return this.delay;
    };

    FlyLyr.lyrs = new Object ();
    FlyLyr.defs = {
	background: '#ffffff',
	titlebackground: '#333399',
	border: '#333399',
	useclass: 'navlink',
	titleclass: 'barlink',
	overimg: '/home/graphics/mo/arrow.gif',
	outimg: '/home/graphics/mo/noarrow.gif',
	pause: 250,
	timeout: 1000
    }
    FlyLyr.unmacOffset = navigator.platform.indexOf ("Mac") != -1 ? 0 : 16;

    if (d.all) {
    	FlyLyr.prototype.realHide = function () {
    	    this.lyr.style.visibility = 'hidden';
	};
    	FlyLyr.prototype.realShow = function () {
    	    this.lyr.style.visibility = 'visible';
	};
    	FlyLyr.prototype.position = positionLayer;
	var vers = navigator.appVersion.split ("MSIE ");
	vers = vers[vers.length - 1];
	FlyLyr.usepos = {
	    'BODY': 1,
	    'IMG': 1,
	    'TABLE': 1,
	    'TD': 1
	};
	if (parseInt (vers) < 5)
	    FlyLyr.usepos["TR"] = 1;
	else if (! FlyLyr.unmacOffset) {
	    FlyLyr.usepos["startX"] = 8;
	    FlyLyr.usepos["startY"] = 12;
	}
    } else {
    	FlyLyr.prototype.realHide = function () {
    	    this.lyr.visibility = 'hide';
	};
    	FlyLyr.prototype.realShow = function () {
    	    this.lyr.visibility = 'show';
	};
    	FlyLyr.prototype.position = positionLayerNS;
    }
}

function ToShow (lyr) {
    if (! lyr || lyr == FlyLyr.showing)
	return;
    this.lyr = lyr;
    ToShow.stopdelay ();
    ToShow.queued = this;
    this.delay = new Delay (FlyLyr.defs.pause, this);
}

function initToShow () {
    ToShow.stopdelay = function () {
	var q = ToShow.queued;
	if (q) {
	    q.delay.stop ();
	    ToShow.queued = null;
	}
	return q;
    };
    ToShow.prototype.delayCallback = function () {
	ToShow.queued = null;
	if (FlyLyr.showing)
	    FlyLyr.showing.doHide ();
	if (this.lyr)
	    this.lyr.doShow ();
    };
}

function Delay (delay, obj) {
    this.obj = obj;
    var uid = ++Delay.nuid;
    this.timeoutid = setTimeout ('Delay.dispatch (' + uid + ')', delay);
    this.uid = uid;
    Delay.disparr[uid] = this;
}

function initDelay () {
    Delay.prototype.stop = function () {
	clearTimeout (this.timerid);
	delete Delay.disparr[this.uid];
    };
    Delay.dispatch = function (uid) {
	var item = Delay.disparr[uid];
	if (! item)
	    return;
	item.obj.delayCallback ();
	item.stop ();
    };
    Delay.nuid = 0;
    Delay.disparr = new Object;
}

function findObj (n, od) { // was MM_findObj v3.0 from Macromedia Dreamweaver
    var p, i, x;
    if (! od)
	od = d;
    if ((p = n.indexOf ("?")) > 0 && parent.frames.length) {
	od = parent.frames[n.substring (p + 1)].document;
	n = n.substring (0, p);
    }
    if (! (x = od[n]) && d.all)
	x = od.all[n];
    for (i = 0; ! x && i < od.forms.length; i++)
	x = od.forms[i][n];
    for (i = 0; ! x && od.layers && i < od.layers.length; i++)
	x = findObj (n, od.layers[i].document);
    return x;
}

function mIn (id) {
    if (! doDHTML)
    	return;
    var lyr = FlyLyr.lyrs[id];
    if (! lyr)
	return;
    if (lyr == FlyLyr.showing)
	lyr.stopdelay ();
    else
	new ToShow (lyr);
}

function mOut () {
    if (! doDHTML)
	return;
    var lyr = FlyLyr.showing;
    if (! ToShow.stopdelay () && lyr)
	lyr.setdelay ();
}
