/* -*- javascript -*-
     Copyright 2006 TJM Enterprises, Inc..
     All Rights Reserved
     System        : MENU_JS :
     Object Name   : $RCS_FILE$
     Revision      : $REVISION$
     Date          : Thu Feb 23 16:00:46 2006
     Created By    : Bradford McKesson, TJM Enterprises, Inc.
     Created       : Thu Feb 23 16:00:46 2006

     Last Modified : <030310.0724>
     ID            : $Id: js.etf,v 2.5 2004/03/25 21:58:00 jon Exp $
     Source        : $Source: /export/cvs/cvsroot/me/macros/js.etf,v $
     Description
     Notes
     $Log: js.etf,v $
     Revision 2.5  2004/03/25 21:58:00  jon
     Final release from steve

     */
// we leave onclick to the <A> tag
// we own style.position, top, left
var ie4 = document.all;
var nn6 = document.getElementById && !document.all;
var navDivTimeOut = null;

/* derived from
 * http://www.alistapart.com/articles/dropdowns/
 * Fix IE 6.0 hover event handling for <li> inside
 * Fix IE 6.0 <select> shine through problem
 * <ul id='nav'> for CSS menu system.
 */
var um_menu_id = "um_0"; // id of element containing main menu
var um_sub_menu_id = "sub_um_0"; // id of element containing all sub menus
var um_sub_menu_tag = "div"; // tag enclosing sub menus
var um_menu_close_delay = "100";
var um_event_handled = true; // value from event handler to signal event should not be processed further
window.startListDone = 0;
window.menu_current = false;
window.menu_can_close_current = false;
window.menu_closing_current = false;

window.startList = function() {
    if (!window.startListEvents) {
        window.startListEvents = true; // run once
        var main_menu = document.getElementById(um_menu_id);
        if (!main_menu) {
            // no menu in document
            window.startListEvents = false; // try again
            return true;
        }
        var main_menu_items = main_menu.getElementsByTagName('a');
        register_event('mouseout', main_menu, menu_mouse_out);
        for (j=0; j<main_menu_items.length; j++) {
            register_event('mouseover', main_menu_items[j], menu_item_mouse_over);
            register_event('mouseout', main_menu_items[j], menu_item_mouse_out);
            var submenu_box = menu_find_sub_menu(main_menu_items[j]);
            if (is_object(submenu_box) && submenu_box) {
                register_event('mouseover', submenu_box, menu_sub_mouse_over);
                register_event('mouseout', submenu_box, menu_sub_mouse_out);
                submenu_box.is_sub_menu = true;
                submenu_box.is_menu_item = false;
            }
        }

        var submenu = document.getElementById(um_sub_menu_id);
        var submenu_items = submenu.getElementsByTagName('a');
        for (j=0; j<submenu_items.length; j++) {
            //  register_event('mouseover', submenu_items[j], menu_sub_item_mouse_over);
            submenu_items[j].is_sub_menu = false;
            submenu_items[j].is_menu_item = true;
        }
    }

    if (document.all && document.getElementById) {
       if (window.startListDone == 1) {
           /**  cover <select> elements with <iframe>s taken from
              http://homepage.mac.com/igstudio/design/ulsmenus/vertical-uls-iframe.html
           **/
           var ieULs = document.getElementById(um_sub_menu_id).getElementsByTagName(um_sub_menu_tag);
           for (j=0; j<ieULs.length; j++) {
               var oldwidth = ieULs[j].offsetWidth;
               var oldheight = ieULs[j].offsetHeight;
               ieULs[j].innerHTML = ('<iframe src="about:blank" scrolling="no" frameborder="0" marginwidth="0" marginheight="0"></iframe>' + ieULs[j].innerHTML);
               // ieULs[j].innerHTML = ('<iframe id="iePad' + j + '" src="about:blank" scrolling="no" frameborder="0" style=""></iframe>' + ieULs[j].innerHTML);
               // var ieMat = document.getElementById('iePad' + j + '');
               // var ieMat = ieULs[j].childNodes[0];  alert(ieMat.nodeName); // also works...
               var ieMat = ieULs[j].firstChild;
               ieMat.style.width=oldwidth+"px";
               ieMat.style.height=oldheight+"px";
               ieULs[j].style.zIndex="500";
           }
           window.startListDone = 2;

       } else {
           // mg: the following seems to alleviate a condition where the menu wraps in a space smaller
           //     than it has available, often a refresh fixes.
           //     still happens sometimes though.
           //     need to find a way to keep menu from ever wrapping.
           //     a horizontal scroll bar at bottom of page is preferable to menu wrapping.
           if ((startListDone == 0) && document.all && document.getElementById && !window.startListDone) {
               window.startListDone = 1;
               window.setTimeout('startList()', 100);
           }
       }
    }
    return true;
} // startList

// return submenu for a menu item element
// menu item 'rel' attribute is 'id' of sub menu container
function menu_find_sub_menu(inElem) {
    var submenu_id = '';
    submenu_id = get_attribute(inElem, 'rel');
    var submenu_elem = false;
    if (submenu_id.length) {
        // we have a submenu id
        submenu_elem = to_element(submenu_id);
    }
    return submenu_elem;
}


function _hide_sub_menu(inSub) {
    var submenu = to_element(inSub);
    var sstyle = submenu.style?submenu.style:submenu;
    sstyle.visibility = 'hidden';
}

function _hide_all_sub_menus() {
    var submenu = document.getElementById(um_sub_menu_id);
    var submenu_items = submenu.getElementsByTagName(um_sub_menu_tag);
    for (j=0; j<submenu_items.length; j++) {
        _hide_sub_menu(submenu_items[j]);
    }
}

function _show_sub_menu(inItem, inSub) {
    var submenu = to_element(inSub);
    var sstyle = submenu.style?submenu.style:submenu;
    var t = to_element(inItem);

    // place submenu below t
    var astyle = t.style?t.style:t;
    var atop = t.offsetTop;
    var aleft = t.offsetLeft;
    var aheight = t.offsetHeight;
    var awidth = t.offsetWidth;

    var stop = atop + aheight;
    var sleft = aleft;

    if (0) { //(document.all) {
        sstyle.pixelTop = stop;
        sstyle.pixelLeft = sleft;
    } else {
        sstyle.top = '' + stop + 'px';
        sstyle.left = '' + sleft + 'px';
    }
    sstyle.visibility = 'visible';
    info ('_show_sub_menu: stop: '+stop + '; sleft: '+sleft);
}

// prevent further JS event processing, but allow the default action
function _cancel_event(evt) {
    if(!evt) { var inEvt = window.event; } else { var inEvt = evt; }

    inEvt.cancelBubble = true;
    if (inEvt.stopPropagation) {
        inEvt.stopPropagation();
    }
    return false;
}

// close all currently visible submenu, show the new_current submenu
function _change_current_submenu(inMenu) {
    // submenu_elem = menu_find_sub_menu(sender_elem);
    var new_current = to_element(inMenu);
    if (window.menu_current != new_current) {
        _hide_all_sub_menus();
    }
    window.menu_current = new_current;
    if (window.menu_closing_current) {
        // we already did that
        clearTimeout(window.menu_closing_current);
        window.menu_closing_current = false;
    }
}

// close sub menus after a short delay (compensate for spurious mouse_out events)
function _delay_change_current_submenu(new_current) {
    if (window.menu_closing_current) {
        clearTimeout(window.menu_closing_current);
        window.menu_closing_current = false;
    }

    menu_id = get_attribute(new_current, 'id');
    window.menu_closing_current =
        setTimeout("_change_current_submenu('" + menu_id + "')", um_menu_close_delay);
    // _change_current_menu(submenu);
}

// ------------------------
// menu bar event
// ------------------------
function menu_mouse_over(evt) {
    var t = event_target(evt);
    info('> menu_mouse_over ' + get_attribute(t, 'rel'));
    info('< menu_mouse_over ' + get_attribute(t, 'rel'));
    _cancel_event(evt);
}

// assigned to <submenu_tag onmouseout>
// cannot close instantly bc user may only move back to menu bar which would show
// us again, causing flicker.
function menu_mouse_out(evt) {
    var t = event_target(evt);
    info('> menu_mouse_out ' +  get_attribute(t, 'rel'));
    // close any currently open submenus
    _delay_change_current_submenu(false);
    info('< menu_mouse_out ' +  get_attribute(t, 'rel'));
    _cancel_event(evt);
}

// -----------------------
// menu bar item event
// -----------------------

// Make sub menu visible, positioned below us
// assigned to <a onmouseover> in main menu
// local this is the <a> element
// value of name attribute is id of sub menu <div>
function menu_item_mouse_over(evt) {
    var t = event_target(evt);
    submenu_elem = menu_find_sub_menu(t);
    info('> menu_item_mouse_over ' +  get_attribute(t, 'rel'));
    if (submenu_elem) {
        _change_current_submenu(submenu_elem);
        _show_sub_menu(t, submenu_elem);
    } else {
        info ('submenu for '  +  get_attribute(t, 'rel') + ' not found');
    }

    info('< menu_item_mouse_over ' +  get_attribute(t, 'rel'));
    _cancel_event(evt);
}

// menu bar item event
function menu_item_mouse_out(evt) {
    var t = event_target(evt);
    info('> menu_item_mouse_out ' +  get_attribute(t, 'rel'));
    _delay_change_current_submenu(false);
    info('< menu_item_mouse_out ' +  get_attribute(t, 'rel'));
    _cancel_event(evt);
}


// -----------------------
// sub menu event
// -----------------------

// assigned to submenu tag mouse over
function menu_sub_mouse_over(evt) {
    var t = event_target(evt);
    while (t && t.is_menu_item) {
        t = t.parentNode;
    }
    info('> menu_sub_mouse_over ' + get_attribute(t, 'rel'));
    _change_current_submenu(t);
    info('< menu_sub_mouse_over ' + get_attribute(t, 'rel'));
    _cancel_event(evt);
}

function menu_sub_mouse_out(evt) {
    var t = event_target(evt);
    while (t && t.is_menu_item) {
        t = t.parentNode;
    }
    info('> menu_sub_mouse_out ' + get_attribute(t, 'rel'));
    _delay_change_current_submenu(false);
    info('< menu_sub_mouse_out ' + get_attribute(t, 'rel'));
    _cancel_event(evt);
}

// -----------------------
// sub menu item event
// -----------------------
// unused
function menu_sub_item_mouse_over(evt) {
    var t = event_target(evt);
    info('> menu_sub_item_mouse_over ' + get_attribute(t, 'rel'));
    info('< menu_sub_item_mouse_over ' + get_attribute(t, 'rel'));
    // _cancel_event(evt);
}

function menu_sub_item_mouse_out(evt) {
    var t = event_target(evt);
    info('> menu_sub_item_mouse_out ' +  get_attribute(t, 'rel'));
    info('< menu_sub_item_mouse_out ' +  get_attribute(t, 'rel'));
    // _cancel_event(evt);
}

//------------------------------------------
// from common/browser/dom_functions.js
//------------------------------------------

// taken from http://www.quirksmode.org/js/events_properties.html
// return element triggering an event
function event_target(evt) {
    if(!evt) { var inEvt = window.event; } else { var inEvt = evt; }
    if (inEvt.target) {
        // w3c
        targ = inEvt.target;
    } else if (inEvt.srcElement) {
        // IE
        targ = inEvt.srcElement;
    }
    if (targ.nodeType == 3) {
        // defeat Safari bug
        targ = targ.parentNode;
    }

    return targ;
}

// Element.hasAttribute not defined in IE
function has_attribute(inElem, inAttr) {
    var out = false;
    if (is_object(inElem)) {
        if (inElem.hasAttribute) {
            out =  inElem.hasAttribute(inAttr);
        } else if (inElem.getAttribute) {
            out = inElem.getAttribute(inAttr);
            out = (out.length)?true:false;
        } else if (inElem[inAttr]) {
            out = true;
        }
    }
}


// paper over broken getAttribute in IE along with its inconsistant availability
function get_attribute(inElem, inAttr) {
    var out = ''; // w3c says nonexistant attribute returns empty string
    if (is_object(inElem)) {
        if (inElem.getAttribute) {
            out = inElem.getAttribute(inAttr);
            if (out === null) {
                out = '';
            }
        } else if (inElem[inAttr]) {
            out = inElem[inAttr];
        }
    }
    return out;
}

// Convert inElemID to a DOM Element
// allow functions below to take either a DOM Element or an id attribute name
// redundent with common/browser/dom_functions.js
function to_element(inElemID) {
    var elem = null;

    if (is_object(inElemID)) {
        elem = inElemID
    } else if (document.getElementById) {
        elem = document.getElementById(inElemID);
    } else if (document.all) {
        elem = document.all[inElemID];
    }

    if (!is_object(elem)) {
        if (window.error) {
            window.error('invalid element id: '+inElemID);
        }
        return false;
    }
    return elem;
} // to_element

// paper over difference between IE and w3c event models
function register_event(inEvtName, inTarget, inFunc) {
    if (is_function(inFunc) && is_object(inTarget)) {
        if (inTarget.addEventListener) {
            // w3c event model
            inTarget.addEventListener(inEvtName, inFunc, false);
        } else
        if (inTarget.attachEvent) {
            // IE event model
            inTarget.attachEvent('on' + inEvtName, inFunc);
        }
    } else {
        info("register_event: invalid function or target ");
    }
}

// mimic the PHP is_object() function
function is_object(inCandidate) {
    return ('object' == typeof(inCandidate));
}
function is_function(inFunc) {
    return (typeof(inFunc) == 'function');
}

window.info_count = 0;
// from fvlogger
function info(inMsg) {
/*
    window.info_count++;
    var p = document.createElement('p');
    var t = document.createTextNode('' + window.info_count + ': ' + inMsg);
    p.appendChild(t);
    document.body.appendChild(p);
*/
}

