﻿// Global Variables
var m_winDebug;
var m_bDebugMode = (window.location.search.toString().search(/jsdebug/gi) > -1) ? true : false; // Determine debugging mode by "jsdebug" in querystring.
var m_oTopicNav; // TopicNav Node.
var m_TimerID; // Global Timer Object

var m_iWindowWidth;
var m_iWindowHeight;
var m_iViewportWidth; 
var m_iViewportHeight;
var m_iHorizontalScroll;
var m_iVerticalScroll;

var m_bUseIEFilters = false;

// ****************************************************************************

// Event Handlers
function Window_load(e)
{
    InitTopicNav(e);
}

function Window_unload(e)
{
    // Close the debugging window.
    if(m_winDebug && !m_winDebug.closed)
    {
        m_winDebug.close();
    }
    m_winDebug = null;
    m_oTopicNav = null;
}

function Document_mouseover(e)
{
    CleanUpMenus(e, this);
}

function TopicNavItem_mouseover(e)
{
    e = (e) ? e : ((window.event) ? event : null);
    if(e)
    {
        var oTarget;
        if(window.addEventListener)
        {
            oTarget = e.relatedTarget;
        }
        else
        {
            oTarget = e.fromElement;
        }
        if(oTarget != null && oTarget.tagName.toLowerCase() != "a")
        {
            CleanUpMenus(e, this);
            ActivateMenus(e, this, true);
        }
        window.status = GetLink(e, this);
        StopEventBubble(e);
    }
}

function TopicNavItem_click(e)
{
    e = (e) ? e : ((window.event) ? event : null);
    if(e)
    {
        FollowChildLink(e, this);
        StopEventBubble(e);
    }
}

function TopicNavItemAnchor_mouseover(e)
{
    e = (e) ? e : ((window.event) ? event : null);
    if(e)
    {
        StopEventBubble(e);
    }
}

function TopicNavItemAnchor_click(e)
{
    e = (e) ? e : ((window.event) ? event : null);
    if(e)
    {
        PreventEventDefault(e); // 10/18/2006 RickR - Bug in Safari doesn't stop default action.
    }
}

function TopicNavGroup_mouseover(e)
{
    e = (e) ? e : ((window.event) ? event : null);
    if(e)
    {
        StopEventBubble(e);
    }
}

// ****************************************************************************

// Topic Nav Initialization
function InitTopicNav(e)
{
    // Get the TopicNav.
    if(document.getElementById)
    {
        m_oTopicNav = document.getElementById("TopicNav");
        LabelTopicNavIDs(m_oTopicNav, "");
        ModifyTopicNavElements(m_oTopicNav);
    }

    function ModifyTopicNavElements(oNode)
    {
        if(window.addEventListener)
        {
            document.addEventListener("mouseover", Document_mouseover, false);
        }
        else
        {
            document.onmouseover = Document_mouseover;
        }
        
        var oDivs = oNode.getElementsByTagName("div");
        for(var i = 0; i < oDivs.length; i++)
        {
            var oDiv = oDivs[i];
            switch(oDiv.className)
            {
                case "TopicNavItem":
                    if(window.addEventListener) // DOM Level 2 Event Model
                    {   
                        oDiv.addEventListener("mouseover", TopicNavItem_mouseover, false);
                        oDiv.addEventListener("click", TopicNavItem_click, false);
                    }
                    else // DOM Level 0 Event Model
                    {
                        oDiv.onmouseover = TopicNavItem_mouseover;
                        oDiv.onclick = TopicNavItem_click;
                    }
                    AddChildMenuMarker(oDiv);  // TODO: This is performing slowly in IE due to image flicker.
                    break;
                case "TopicNavGroup":
                    if(window.addEventListener) // DOM Level 2 Event Model
                    {   
                        oDiv.addEventListener("mouseover", TopicNavGroup_mouseover, false);
                    }
                    else // DOM Level 0 Event Model
                    {
                        oDiv.onmouseover = TopicNavGroup_mouseover;
                    }
                    ShowSubmenu(e, oDiv, false);
                    break;
                default:
                    break;
            }
        }
        
        var oAs = oNode.getElementsByTagName("a");
        for(var i = 0; i < oAs.length; i++)
        {
            var oA = oAs[i];
            if(window.addEventListener) // DOM Level 2 Event Model
            {   
                oA.addEventListener("mouseover", TopicNavItemAnchor_mouseover, false);
                oA.addEventListener("click", TopicNavItemAnchor_click, false);
            }
            else // DOM Level 0 Event Model
            {
//                oA.onmouseover = TopicNavItemAnchor_mouseover; // Breaking IE for some reason.
                oA.onclick = TopicNavItemAnchor_click;
            }
        }
    }
    
    function AddChildMenuMarker(oNode)
    {
        if(HasChildMenu(oNode))
        {
            oNode.style.backgroundImage = "url(/images/global/arrow.gif)";
            oNode.style.backgroundRepeat = "no-repeat";
            oNode.style.backgroundPosition = "98% 50%";
        }
    }
    
    function LabelTopicNavIDs(oRootNode, sParent)
    {
        var oChildNodes = oRootNode.childNodes;
        var oCurrentNode;
        var iItemNum = 1;
        for(var i = 0; i < oChildNodes.length; i++)
        {   
            oCurrentNode = oChildNodes[i];
            if(oCurrentNode.nodeType == 1 && oCurrentNode.tagName.toLowerCase() == "div" && oCurrentNode.className == "TopicNavItem")
            {
                oCurrentNode.id = sParent + "I" + iItemNum.toString();
                iItemNum++;
            }
            if(oCurrentNode.childNodes.length > 0)
            {
                for(var j = 0; j < oCurrentNode.childNodes.length; j++)
                {
                    if(oCurrentNode.childNodes[j].nodeType == 1 && oCurrentNode.childNodes[j].tagName.toLowerCase() == "div" && oCurrentNode.childNodes[j].className == "TopicNavGroup")
                    {
                        oCurrentNode.childNodes[j].id = oCurrentNode.id + "G";
                        LabelTopicNavIDs(oCurrentNode.childNodes[j], oCurrentNode.childNodes[j].id)
                    }
                }        
            }
        }
    }
}
// ****************************************************************************

// Menus

function CleanUpMenus(e, oNode)
{
    // Create array of menus to protect from cleanup.
    var aProtectedNodeIds = new Array();
    aProtectedNodeIds[aProtectedNodeIds.length] = oNode.id;
    
    GetParentNodes(oNode);
    
    var oNodes = m_oTopicNav.getElementsByTagName("div");
    for(var i = 0; i < oNodes.length; i++)
    {
        if(oNodes[i].className == "TopicNavItemActive" && !IsProtected(oNodes[i].id))
        {
            oNodes[i].className = "TopicNavItem";
        }
        
        if(oNodes[i].className == "TopicNavGroup" && !IsProtected(oNodes[i].id))
        {
            ShowSubmenu(e, oNodes[i], false);
        }
    }
    
    function GetParentNodes(oNode)
    {
        if(oNode.parentNode != null && oNode.parentNode.className == "TopicNavGroup")
        {
            aProtectedNodeIds[aProtectedNodeIds.length] = oNode.parentNode.id;
            if(oNode.parentNode.parentNode.className.search("TopicNavItem") > -1)
            {
                aProtectedNodeIds[aProtectedNodeIds.length] = oNode.parentNode.parentNode.id;
                GetParentNodes(oNode.parentNode.parentNode);
            }
        }   
    }
    
    function IsProtected(sId)
    {
        for(var i = 0; i < aProtectedNodeIds.length; i++)
        {
            if(aProtectedNodeIds[i] == sId)
            {
                return true;
            }
        }
        return false;
    }
}

function ActivateMenus(e, oNode, bShow)
{
    if(oNode.className == "TopicNavItem")
    {
        oNode.className = "TopicNavItemActive";
    }
    
    for(var i = 0; i < oNode.childNodes.length; i++)
    {
        var oChild = oNode.childNodes[i];
        // Check to make sure the node exists and is an HTML element with 
        // tag name of <div> and class name of "TopicNavGroup."
        if(typeof oChild != "undefined" && oChild.nodeType == 1 
            && oChild.tagName.toLowerCase() == "div" 
            && oChild.className == "TopicNavGroup")
        {
            ShowSubmenu(e, oChild, bShow);
        }
    }
    
    // Destroy objects.
    oChild = null;
    
    return true;
}

function ShowSubmenu(e, oNode, bShow)
{
    if(e)
    {
        if(e.type == "load")
        {
            oNode.style.position = "absolute";
            oNode.style.left = "198px";
            if(navigator.userAgent.toString().search("MSIE") > -1)
            {
                var iMSIEOffset = navigator.userAgent.indexOf("MSIE ") + 5;
                if(parseFloat(navigator.userAgent.substring(iMSIEOffset)) < 6)
                {
                    oNode.style.left = "196px";
                }
            }
            oNode.style.backgroundColor = "#ECEAEA";
            oNode.style.border = "solid 1px #A79E9E";
            oNode.style.borderTopWidth = "0";
            oNode.style.zIndex = "1";
            oNode.style.margin = "0";
            oNode.style.padding = "0";

            var sWidthValue = "198px";
            oNode.style.width = sWidthValue;
            oNode.style.maxWidth = sWidthValue;
            oNode.style.minWidth = sWidthValue;
            
            // Apply menu fade in/out transition ONLY IF browser is MSIE 5.5+ on Windows and the user has 8-bit color or better.
            if(navigator.userAgent.toString().search("MSIE") > -1 && navigator.userAgent.toString().search("Windows") > -1)
            {
                var iMSIEOffset = navigator.userAgent.indexOf("MSIE ") + 5;
                if(parseFloat(navigator.userAgent.substring(iMSIEOffset)) >= 5.5)
                {
                    if(window.screen.colorDepth >= 8)
                    {
                        oNode.style.filter = "progid:DXImageTransform.Microsoft.Fade(duration=0.25)";
                        m_bUseIEFilters = true;
                    }   
                }
            }
        }
    }

    var iIE_Top;                // Final coordinates for IE.
    var iGecko_Top;             // Final coordinates for Mozilla, Firefox, Netscape.
    var iKHTML_Top;             // Final coordinates for Safari, Konqueror.
    var iVerticalThreshold;     // Viewable area cannot be less than this without triggering an adjustment.
    var iVerticalAdjustment;    // Vertical adjustment of the menu due to small viewable area.
    var iVerticalAdjustmentMax; // The maximum amount of vertical adjustment allowed before menu goes off the top-edge of the screen.
    
    GetWindowGeometry();
    
    switch(oNode.id)
    {
        case "I1G":
            iIE_Top = 61;
            iGecko_Top = 59;
            iKHTML_Top = 56;
            iVerticalThreshold = 490;
            iVerticalAdjustmentMax = -190;
            break;
        case "I2G":
            iIE_Top = 87;
            iGecko_Top = 85;
            iKHTML_Top = 81;
            iVerticalThreshold = 610;
            iVerticalAdjustmentMax = -215;
            break;
        case "I3G":
            iIE_Top = 113;
            iGecko_Top = 111;
            iKHTML_Top = 106;
            iVerticalThreshold = 378;
            iVerticalAdjustmentMax = null;
            break;
        case "I4G":
            iIE_Top = 154;
            iGecko_Top = 152;
            iKHTML_Top = 145;
            iVerticalThreshold = 485;
            iVerticalAdjustmentMax = null;
            break;
        case "I5G":
            iIE_Top = 180;
            iGecko_Top = 178;
            iKHTML_Top = 170;
            iVerticalThreshold = 418;
            iVerticalAdjustmentMax = null;
            break;
        case "I6G":
            iIE_Top = 221;
            iGecko_Top = 219;
            iKHTML_Top = 209;
            iVerticalThreshold = 530;
            iVerticalAdjustmentMax = null;
            break;
        case "I7G":
            iIE_Top = 262;
            iGecko_Top = 260;
            iKHTML_Top = 248;
            iVerticalThreshold = 650;
            iVerticalAdjustmentMax = null;
            break;
        case "I8G":
            iIE_Top = 288;
            iGecko_Top = 286;
            iKHTML_Top = 273;
            iVerticalThreshold = 400;
            iVerticalAdjustmentMax = null;
            break;
        case "I9G":
            iIE_Top = 314;
            iGecko_Top = 312;
            iKHTML_Top = 298;
            iVerticalThreshold = 545;
            iVerticalAdjustmentMax = null;
            break;
        case "I2GI1G":
            iIE_Top = 0;
            iGecko_Top = 0;
            iKHTML_Top = 0;
            iVerticalThreshold = 0; // Shouldn't need to adjust because parent menu is taller.
            iVerticalAdjustmentMax = null;
            break;
        case "I2GI3G":
            iIE_Top = 52;
            iGecko_Top = 52;
            iKHTML_Top = 50;
            iVerticalThreshold = 0; // Shouldn't need to adjust because parent menu is taller.
            iVerticalAdjustmentMax = null;
            break;
        case "I2GI4G":
            iIE_Top = 93;
            iGecko_Top = 93;
            iKHTML_Top = 89;
            iVerticalThreshold = 0; // Shouldn't need to adjust because parent menu is taller.
            iVerticalAdjustmentMax = null;
            break;
        case "I2GI5G":
            iIE_Top = 134;
            iGecko_Top = 134;
            iKHTML_Top = 128;
            iVerticalThreshold = 0; // Shouldn't need to adjust because parent menu is taller.
            iVerticalAdjustmentMax = null;
            break;
        case "I2GI6G":
            iIE_Top = 160;
            iGecko_Top = 160;
            iKHTML_Top = 153;
            iVerticalThreshold = 0; // Shouldn't need to adjust because parent menu is taller.
            iVerticalAdjustmentMax = null;
            break;                   
        default:
            iIE_Top = 0;
            iGecko_Top = 0;
            iKHTML_Top = 0;
            iVerticalThreshold = 0;
            iVerticalAdjustmentMax = null;
            break;
    }
    
    iVerticalAdjustment = (m_iViewportHeight + m_iVerticalScroll) - iVerticalThreshold;
    iVerticalAdjustment = (iVerticalAdjustment > 0) ? 0 : iVerticalAdjustment;
    if(iVerticalAdjustmentMax != null)
    {
        iVerticalAdjustment = (iVerticalAdjustment < iVerticalAdjustmentMax) ? iVerticalAdjustmentMax : iVerticalAdjustment;
    }
        
    if(navigator.userAgent.toString().search("MSIE") > -1)
    {
        oNode.style.top = (iIE_Top + iVerticalAdjustment).toString() + "px";
    }
    else if(navigator.userAgent.toString().search("KHTML") > -1)
    {
        oNode.style.top = (iKHTML_Top + iVerticalAdjustment).toString() + "px";
    }
    else if(navigator.userAgent.toString().search("Gecko") > -1)
    {
        oNode.style.top = (iGecko_Top + iVerticalAdjustment).toString() + "px";
    }
    else
    {
        oNode.style.top = (iGecko_Top + iVerticalAdjustment).toString() + "px";
    }
    
    if(bShow)
    {
        if(m_bUseIEFilters) {oNode.filters.item(0).Apply();}
        oNode.style.display = "block";
        oNode.style.visibility = "visible";
        if(m_bUseIEFilters) {oNode.filters.item(0).Play();}
    }
    else
    {
        if(m_bUseIEFilters) {oNode.filters.item(0).Apply();}
        oNode.style.display = "none";
        oNode.style.visibility = "hidden";
        if(m_bUseIEFilters) {oNode.filters.item(0).Play();}
    }
}

function GetWindowGeometry()
{
    if(window.outerWidth)
    {
        m_iWindowWidth = window.outerWidth;
        m_iWindowHeight = window.outerHeight;
    }
    
    if(window.innerWidth) // Most Browsers
    {
        m_iViewportWidth = window.innerWidth;
        m_iViewportHeight = window.innerHeight;
        m_iHorizontalScroll = window.pageXOffset;
        m_iVerticalScroll = window.pageYOffset;
    }
    else if(document.documentElement.clientWidth) // IE6 with DOCTYPE
    {
        m_iViewportWidth = document.documentElement.clientWidth;
        m_iViewportHeight = document.documentElement.clientHeight;
        m_iHorizontalScroll = document.documentElement.scrollLeft;
        m_iVerticalScroll = document.documentElement.scrollTop;
    }
    else if(document.body.clientWidth) // IE4 to IE6 without DOCTYPE
    {
        m_iViewportWidth = document.body.clientWidth;
        m_iViewportHeight = document.body.clientHeight;
        m_iHorizontalScroll = document.body.scrollLeft;
        m_iVerticalScroll = document.body.scrollTop;
    }
}

// ****************************************************************************

// Helper Functions
function StopEventBubble(e)
{
    if(window.addEventListener)
    {
        e.stopPropagation();
    }
    else if(window.attachEvent)
    {
        e.cancelBubble = true;
    }
}

function PreventEventDefault(e)
{
    if(window.addEventListener)
    {
        e.preventDefault();
    }
    else if(window.attachEvent)
    {
        e.returnValue = false;
    }
}

function HasChildMenu(oNode)
{
    for(var i = 0; i < oNode.childNodes.length; i++)
    {
        if(oNode.childNodes[i].className == "TopicNavGroup")
        {
            return true;
        }
    }
    return false;
}
// ****************************************************************************

// Links
function GetLink(e, oNode)
{
    var sLink = "";
    var i = 0;
    do
    {
        if(typeof oNode.childNodes[i] != "undefined" && oNode.childNodes[i].nodeType == 1 
            && oNode.childNodes[i].tagName.toLowerCase() == "a")
        {
            sLink = oNode.childNodes[i].href;
        }
        i++;
    }
    while(i < oNode.childNodes.length || sLink == "");
    
    return sLink;
}

function FollowChildLink(e, oNode)
{
    sLink = GetLink(e, oNode);
        
    // Follow the link.
    // Criteria for opening in a new window.
    // If it is an external link.
    if(IsExternalLink(sLink))
    {
		window.open(sLink);
	}
	else
	{
		window.location.href = sLink;
	}
    
    // Destroy objects.
    oChild = null;
    
    function IsExternalLink(sLink)
    {
        // This is the regular expression that determines
        // whether a URL is external.
        var sExternalLinkPattern = /^http/; // Starts with "http"

        // This is an array of regular expressions that
        // are exceptions to the above.
        var sExternalLinkExceptions = new Array();
        sExternalLinkExceptions[0] = /www.aicpa.org/; // contains "www.aicpa.org"
        sExternalLinkExceptions[1] = /staging.aicpa.org/; // contains "staging.aicpa.org" 
        sExternalLinkExceptions[2] = /qa.aicpa.org/; // contains "qa.aicpa.org" 
        sExternalLinkExceptions[3] = /dev.aicpa.org/; // contains "dev.aicpa.org"
        
        var bIsExternalLink = sLink.search(sExternalLinkPattern) > -1 ? true : false;
       
        if(bIsExternalLink)
        {
            for(var i = 0; i < sExternalLinkExceptions.length; i++)
            {
                bIsExternalLink = sLink.search(sExternalLinkExceptions[i]) == -1 ? true : false;
                if (!(bIsExternalLink))
                {
					break;
                }
            }
        }
        
        return bIsExternalLink;
    }
}
// ****************************************************************************

// DEBUGGING
function DEBUG_WriteLine(sString)
{   
    sString = DEBUG_HTMLEncode(sString);
    DEBUG_WriteToDebugWindow(sString);
}

function DEBUG_DateWriteLine(sString)
{
    sString = DEBUG_HTMLEncode(sString);
    sString = DEBUG_GetDateStamp() + sString;
    DEBUG_WriteToDebugWindow(sString);
}

function DEBUG_HTMLWriteLine(sString)
{
    DEBUG_WriteToDebugWindow(sString);
}

function DEBUG_GetDateStamp()
{
    var oDate = new Date();
    var sDate = oDate.toTimeString() + "\t";
    sDate = sDate.fontcolor("#0000FF");
    sDate = sDate.bold();
    
    return sDate;
}

function DEBUG_HTMLEncode(sString)
{
    sString = sString.replace(/\</g, "&lt;");
    sString = sString.replace(/\>/g, "&gt;");
    sString = sString.replace(/\&/g, "&amp;");
    sString = sString.replace(/\'/g, "&#39;");
    
    return sString;
}

function DEBUG_WriteToDebugWindow(sString)
{
    
    sString += "<br />";
    if(m_winDebug && !m_winDebug.closed)
    {
        m_winDebug.document.writeln(sString);
    }
}

if(m_bDebugMode)
{
        // Open the Debugging Window
        m_winDebug = window.open("", "", "channelmode=no, directories=no, fullscreen=no, location=no, menubar=no, toolbar=no, resizable=yes, scrollbars=yes, width=800, height=600");
        // Debugging Window
        DEBUG_HTMLWriteLine("<font face='Courier'>");
        DEBUG_HTMLWriteLine("<b>JavaScript Debugging for " + window.location.href.toString() + "</b>");
        DEBUG_HTMLWriteLine(window.navigator.userAgent.toString().bold().fontcolor("blue"));
        DEBUG_HTMLWriteLine("<hr />");
        DEBUG_DateWriteLine("Debugging window opened.");
}

// Page Event Handlers
if(window.addEventListener) // DOM Level 2
{
    window.addEventListener("load", Window_load, false);
    window.addEventListener("unload", Window_unload, false);
}
else if(window.attachEvent) // IE 5+
{
    window.attachEvent("onload", Window_load);
    window.attachEvent("onunload", Window_unload);
}
else // DOM Level 0
{
    window.onload = Window_load;
    window.onunload = Window_unload;
}