DD.event.onReady('head', function() {
    var z = 200;
    var known = {};
    var isKnown = function(obj) {
        return obj.getAttribute? known[obj.getAttribute('uniqueList')] : false;
    };
    var setAsKnown = function(obj, prop) {
        if (obj.getAttribute) {
            known[obj.getAttribute('uniqueList')] = prop;
        }
    };
    var setup = function(trigger, list) {
        list.trigger = trigger;
        list.className = 'flyOut';
        trigger.className = 'arrow';
        var arrow = document.createElement('em');
        trigger.appendChild(arrow);
        var appear = function() {
            clearTimeout(list.pause);
            if (!list.animating && !isKnown(list)) {
                var self = isKnown(list);
                killSeveral(known, list);
                setAsKnown(list, list);
                var coords = DD.dom.getPosition(trigger);
                list.style.zIndex = z++;
                DD.dom.addClass(trigger, 'hover');
                DD.fade(list, true, {time:120, step:10, also: function(obj, tween) {
                    obj.style.top = tween*obj.offsetHeight + 'px';
                }, end:fadeFinished});
                list.style.left = coords[0] + 1 + 'px';
                list.style.top = coords[1] + trigger.offsetHeight + 'px';
            }
            if (list.animating && list.direction == -1) {
                DD.animate.reverse(list);
                //DD.animate.stop(list);
                //DD.opacity(list, 1);
            }
        };
        var kill = function() { /* these are local! */
            if (isKnown(list)) {
                if (list.animating && list.direction == 1) {
                    DD.animate.reverse(list);
                }
                else {
                    DD.animate.stop(list);
                    DD.fade(list, false, {time:120, step:10, end:fadeFinished});
                }
            }
        };
        var disappear = function() {
            list.pause = setTimeout(kill, 300);
        };
        var fadeFinished = function() {
            setAsKnown(list, (list.tween > 0)? list : false);
            if (!isKnown(list)) {
                DD.dom.removeClass(trigger, 'hover');
            }
        };
        var eventHandlers = {'mouseover': appear, 'focus': appear, 'mouseout': disappear, 'blur': disappear};
        var elementsThatListen = {trigger: trigger};
        var subAnchors = list.getElementsByTagName('a');
        var subAnchorsLen = subAnchors.length;
        for (var i=0; i<subAnchorsLen; i++) {
            elementsThatListen[i] = subAnchors[i];
        }
        for (var a in elementsThatListen) {
            for (var e in eventHandlers) {
                DD.event.add(elementsThatListen[a], e, eventHandlers[e]);
            }
        }
    };
    var killSeveral = function(known, self) {
        for (var o in known) {
            if (!self || (known[o] && known[o] != self)) {
                clearTimeout(known[o].pause);
                if (self && known[o].animating && known[o].direction == 1) {
                    DD.animate.reverse(known[o]);
                }
                else {
                    DD.animate.stop(known[o]);
                    DD.opacity(known[o], 0);
                }
                DD.dom.removeClass(known[o].trigger, 'hover');
                setAsKnown(known[o], false);
            }
        }
    };
    
    /* collect and call assign-event-handlers function */
    var head = DD.dom.id('head');
    var anchors = head.getElementsByTagName('a');
    for (var i=0; i<anchors.length; i++) {
        anchors[i].tabIndex = i+1;
    }
    var lists = head.getElementsByTagName('ul');
    var movedLists = [];
    for (var i=0; i<lists.length; i++) {
        lists[i].setAttribute('uniqueList', Math.random());
        if (DD.dom.ancestor(lists[i].parentNode, {nodeName: 'UL'})) {
            setup(lists[i].parentNode.firstChild, lists[i]);
            document.body.insertBefore(lists[i], document.body.firstChild);
            i = i-1; /* because you just picked up and moved something */
        }
    }
    DD.event.delegate('#wrap', 'mousedown', function(obj, e) {
        var node = e.srcElement || e.target;
        if (!DD.dom.ancestor(node, {nodeName: 'A'})) {
            killSeveral(known, false);
        }
    });
});
