// {{MadCap}} //////////////////////////////////////////////////////////////////
// Copyright: MadCap Software, Inc - www.madcapsoftware.com ////////////////////
////////////////////////////////////////////////////////////////////////////////
// <version>1.0.0.0</version>
////////////////////////////////////////////////////////////////////////////////

var gInit				= false;
var gCurrSelection		= null;
var gStyles				= new CMCDictionary();
var gClassToANodeMap	= new CMCDictionary();
var gSyncContinue		= false;
var gSyncTocPath		= null;

function SyncTOC( tocPath )
{
    Init();
    
    //
    
    gSyncTocPath = tocPath;
    
    var href        = parent.parent.frames["body"].document.location.href;
    var subsystem   = parent.parent.GetMasterHelpSystem();
    var fullTocPath = new Object();
    
    fullTocPath.tocPath = null;
    subsystem.GetFullTocPath( fullTocPath );
    
    if ( fullTocPath.tocPath )
    {
        tocPath = tocPath ? fullTocPath.tocPath + "|" + tocPath : fullTocPath.tocPath;
    }
    
    //

    var tocNode	= document.getElementById( "CatapultToc" ).getElementsByTagName( "div" )[0];
	var steps	= (tocPath == "") ? new Array( 0 ) : tocPath.split( "|" );
    
	for ( var i = 0; tocNode && i < steps.length; i++ )
	{
		tocNode = FindBook( tocNode, steps[i] );
	}
    
	if ( tocNode == null )
	{
		return;
	}

	var foundNode	= FindLink( tocNode, true );
	
	if ( !foundNode )
	{
		foundNode = FindLink( tocNode, false );
	}
    
	if ( foundNode )
	{
		SetSelection( FMCGetChildNodeByTagName( foundNode, "A", 0 ) );
		ScrollToVisible( foundNode );
	}
    
    //
    
    gSyncTocPath = null;
}

function FindBook( tocNode, step )
{
	var foundNode	= null;
	var a			= FMCGetChildNodeByTagName( tocNode, "A", 0 );
	var div			= FMCGetChildNodeByTagName( tocNode, "DIV", 0 );

	if ( FMCGetMCAttribute( a, "MadCap:chunk" ) )
	{
		gSyncContinue = true;
		CreateToc( a );

		return null;
	}
	else if ( div && div.style.display == "none" )
	{
		TocExpand( a );
	}

	for ( var i = 0; i < tocNode.childNodes.length; i++ )
	{
		if ( tocNode.childNodes[i].nodeName == "DIV" &&
			 tocNode.childNodes[i].firstChild.lastChild.nodeValue == step )
		{
			foundNode = tocNode.childNodes[i];
			
			break;
		}
	}
	
	return foundNode;
}

function FindLink( node, exactMatch )
{
	var foundNode	= null;
	var bodyHref	= GetBodyHref( exactMatch ).toLowerCase();
    var aNode		= FMCGetChildNodeByTagName( node, "A", 0 );
    var bookHref	= aNode.href;

	bookHref = bookHref.replace( /%20/g, " " );
	bookHref = bookHref.substring( bookHref.indexOf( "/Content/" ) + "/Content/".length );
	bookHref = bookHref.toLowerCase();
    
	if ( bookHref == bodyHref )
	{
		foundNode = node;
	}
	else
	{
		if ( FMCGetChildNodeByTagName( node, "DIV", 0 ).style.display == "none" )
		{
			TocExpand( aNode );
		}
		
		for ( var k = 1; k < node.childNodes.length; k++ )
		{
			var currNode		= node.childNodes[k];
			
			if ( currNode.nodeType != 1 || currNode.nodeName != "DIV" ) { continue; }
			
			var currTopicHref	= currNode.firstChild.href;
			
			currTopicHref = currTopicHref.replace( /%20/g, " " );
			currTopicHref = currTopicHref.substring( currTopicHref.indexOf( "/Content/" ) + "/Content/".length );
			currTopicHref = currTopicHref.toLowerCase();
			
			if ( !exactMatch )
			{
				var hashPos	= currTopicHref.indexOf( "#" );

				if ( hashPos != -1 )
				{
					currTopicHref = currTopicHref.substring( 0, hashPos );
				}
				
				var searchPos	= currTopicHref.indexOf( "?" );
				
				if ( searchPos != -1 )
				{
					currTopicHref = currTopicHref.substring( 0, searchPos );
				}
			}
            
			if ( currTopicHref == bodyHref )
			{
				foundNode = currNode;
				
				break;
			}
		}
	}
	
	return foundNode;
}

function GetBodyHref( fullHref )
{
	var bodyFrame		= parent.parent.frames["body"];
	var bodyLocation	= bodyFrame.document.location;
	var bodyHref		= bodyLocation.protocol + "//" + bodyLocation.host + bodyLocation.pathname + (fullHref ? bodyLocation.hash : "");
	
	bodyHref = bodyHref.replace( /\\/g, "/" );
	bodyHref = bodyHref.replace( /%20/g, " " );
    bodyHref = bodyHref.substring( bodyHref.indexOf( "/Content/" ) + "/Content/".length );
	
	return bodyHref;
}

function ScrollToVisible( node )
{
    var oldPosition     = FMCGetComputedStyle( node, "position" );
    
    node.style.position = "";
    
    //
    
    var scrollTop       = FMCGetScrollTop( window );
    var scrollBottom    = scrollTop + FMCGetClientHeight( window );
    var scrollLeft      = FMCGetScrollLeft( window );
    var scrollRight     = scrollLeft + FMCGetClientWidth( window );
    var nodeTop         = node.offsetTop + 3;                                      // "+ 3" is to account for body padding.
    var nodeLeft        = parseInt( node.style.textIndent ) + node.offsetLeft + 3; // "+ 3" is to account for body padding.
    var nodeHeight      = node.offsetHeight;
    var nodeWidth       = node.getElementsByTagName( "a" )[0].offsetWidth + parseInt( node.style.textIndent );
    
    if ( nodeTop < scrollTop )
    {
        FMCSetScrollTop( window, nodeTop );
    }
    else if ( nodeTop + nodeHeight > scrollBottom )
    {
        FMCSetScrollTop( window, Math.min( nodeTop, nodeTop - FMCGetClientHeight( window ) + nodeHeight ) );
    }
    
    if ( nodeLeft < scrollLeft )
    {
        FMCSetScrollLeft( window, nodeLeft );
    }
    else if ( nodeLeft + nodeWidth > scrollRight )
    {
        FMCSetScrollLeft( window, Math.min( nodeLeft, node.offsetLeft - FMCGetClientWidth( window ) + nodeWidth ) );
    }
    
    //
    
    node.style.position = oldPosition;
}

function SetSelection( aNode )
{
    if ( gCurrSelection )
    {
        var oldBGColor  = FMCGetMCAttribute( gCurrSelection, "MadCap:oldBGColor" );
        
        if ( !oldBGColor )
        {
            oldBGColor = "Transparent";
        }
        
        gCurrSelection.style.backgroundColor = oldBGColor;
    }
    
    gCurrSelection = aNode;
    gCurrSelection.setAttribute( "MadCap:oldBGColor", FMCGetComputedStyle( gCurrSelection, "backgroundColor" ) );
    gCurrSelection.style.backgroundColor = "#dddddd";
}

function BookOnClick( node )
{
    SetSelection( node );
    
    TocExpand( node );
    
    if ( node.href.indexOf( "javascript:" ) == -1 )
    {
        var frameName   = FMCGetMCAttribute( node, "MadCap:frameName" );
        
        if ( !frameName )
        {
            frameName = "body";
        }
        
        window.open( node.href, frameName );
    }
}

function ChunkOnClick( node )
{
    SetSelection( node );
    
    CreateToc( node );
    
    node.onclick = function() { BookOnClick( node ); return false; };
    
    if ( node.href.indexOf( "javascript:" ) == -1 )
    {
        parent.parent.frames["body"].document.location.href = node.href;
    }
}

function TopicOnClick( node )
{
    SetSelection( node );
    
    if ( node.href.indexOf( "javascript:" ) == -1 )
    {
        var frameName   = FMCGetMCAttribute( node, "MadCap:frameName" );
        
        if ( !frameName )
        {
            frameName = "body";
        }
        
        window.open( node.href, frameName );
    }
}

function GetOwnerHelpSystem( node )
{
    var currNode        = node;
    var ownerHelpSystem = null;
    
    while ( true )
    {
        if ( currNode.parentNode.id == "CatapultToc" )
        {
            ownerHelpSystem = parent.parent.GetMasterHelpSystem();
            
            break;
        }
        
        var a   = FMCGetChildNodeByTagName( currNode, "A", 0 );
        
        ownerHelpSystem = a["MadCap:helpSystem"];
        
        if ( !ownerHelpSystem && currNode.parentNode.id != "CatapultToc" )
        {
            currNode = currNode.parentNode;
        }
        else
        {
            break;
        }
    }
    
    return ownerHelpSystem;
}

function BuildToc( xmlNode, htmlNode, indent, fullPath )
{
    for ( var i = 0; i < xmlNode.childNodes.length; i++ )
    {
        var entry = xmlNode.childNodes[i];
        
        if ( entry.nodeName != "TocEntry" )
        {
            continue;
        }
        
        var div             = document.createElement( "div" );
        var a               = null;
        var img             = document.createElement( "img" );
        var title           = entry.getAttribute( "Title" );
        var link            = entry.getAttribute( "Link" );
        var frameName       = entry.getAttribute( "FrameName" );
        var chunk           = entry.getAttribute( "Chunk" );
        var mergeHint       = entry.getAttribute( "MergeHint" );
        var isBook          = (entry.childNodes.length > 0 || chunk || mergeHint);
        var bookIcon        = null;
        var bookOpenIcon    = null;
        var topicIcon       = null;
        var markAsNew       = null;
        
        // Create "div" tag. Append to HTML TOC node.
        
        div.style.textIndent = indent + "px";
        div.style.position = "relative";
        div.style.display = "none";
        htmlNode.appendChild( div );
        
        // Apply style
        
        var entryClass      = entry.getAttribute( "Class" );
        var className       = "TocEntry_" + ((entryClass == null) ? "TocEntry" : entryClass);
        var nameToValueMap  = gStyles.GetItem( className );
        
        if ( nameToValueMap )
        {
            bookIcon = nameToValueMap.GetItem( "BookIcon" );
            bookOpenIcon = nameToValueMap.GetItem( "BookOpenIcon" );
            topicIcon = nameToValueMap.GetItem( "TopicIcon" );
            
            var markAsNewValue	= nameToValueMap.GetItem( "MarkAsNew" );
            
            if ( markAsNewValue )
            {
				markAsNew = FMCStringToBool( markAsNewValue );
            }
            
            var aCached = gClassToANodeMap.GetItem( className );
            
            if ( aCached )
            {
                a = aCached.cloneNode( false );
            }
            else
            {
                a = document.createElement( "a" );
                
                for ( var key in nameToValueMap.GetKeys() )
                {
                    var value   = nameToValueMap.GetItem( key );
                    var style   = ConvertToCSS( key );
                    
                    a.style[style] = value;
                }
                
                gClassToANodeMap.SetItem( className, a.cloneNode( false ) );
            }
        }
        else
        {
            a = document.createElement( "a" );
        }
        
        // Create "a" tag. Append to "div" tag.
        
        if ( link && !mergeHint )
        {
            if ( link.indexOf( "/Content/" ) == 0 )
            {
                link = fullPath + link.substring( 1 );
            }
            
            a.setAttribute( "href", link );
            
            if ( !frameName )
            {
                frameName = "body";
            }
            
            a.setAttribute( "MadCap:frameName", frameName );
        }
        else
        {
            a.setAttribute( "href", "javascript:void( 0 );" );
        }
        
        //
        
        var ownerHelpSystem = GetOwnerHelpSystem( htmlNode );
        var subPath         = null;
        
        if ( mergeHint )
        {
            var subsystem   = ownerHelpSystem.GetSubsystem( parseInt( mergeHint ) );
            
            if ( !subsystem.GetExists() )
            {
                continue;
            }
            
            subPath = subsystem.GetPath();
            
            var fileName	= null;
            
            if ( window.name == "toc" )
            {
				fileName = "Toc.xml";
            }
            else if ( window.name == "browsesequence" )
            {
				fileName = "BrowseSequence.xml";
            }
            
            chunk = subPath + "Data/" + fileName;
            
            a["MadCap:helpSystem"] = subsystem;
        }
        
        //
        
        if ( isBook )
        {
            if ( chunk )
            {
                if ( !mergeHint )
                {
                    chunk = ownerHelpSystem.GetPath() + "Data/" + chunk;
                }
                
                a.onclick = function() { ChunkOnClick( this ); return false; };
                a.setAttribute( "MadCap:chunk", chunk );
            }
            else if ( entry.childNodes.length > 0 )
            {
                a.onclick = function() { BookOnClick( this ); return false; };
            }
            
            // Create "img" tag. Append to "a" tag.
            
            if ( bookIcon == "none" )
            {
                img = null;
            }
            else
            {
                img.src = bookIcon ? "../" + parent.parent.gSkinFolder + bookIcon.substring( 4, bookIcon.length - 1 ) : "Images/Book.gif";
                img.alt = "Book";
                img.setAttribute( "MadCap:altsrc", (!bookOpenIcon || bookOpenIcon == "none") ? "Images/BookOpen.gif" : "../" + parent.parent.gSkinFolder + bookOpenIcon.substring( 4, bookOpenIcon.length - 1 ) );
            }
        }
        else
        {
            a.onclick = function() { TopicOnClick( this ); return false; };
            
            if ( topicIcon == "none" )
            {
                img = null;
            }
            else
            {
                img.src = topicIcon ? "../" + parent.parent.gSkinFolder + topicIcon.substring( 4, topicIcon.length - 1 ) : "Images/Topic.gif";
                img.alt = "Topic";
            }
        }

        var markAsNewEntry		= entry.getAttribute( "MarkAsNew" );
        var markAsNewComputed	= markAsNewEntry ? FMCStringToBool( markAsNewEntry ) : markAsNew;
        
        if ( markAsNewComputed )
        {
            var newImg  = document.createElement( "img" );
            
            newImg.src = "Images/NewItemIndicator.bmp";
            newImg.alt = "New";
            newImg.style.width = "7px";
            newImg.style.height = "7px";
            newImg.style.position = "absolute";
            
            a.appendChild( newImg );
        }
        
        img ? a.appendChild( img ) : false;
        div.appendChild( a );
        
        // Create "text" node. Append to "a" tag.
        
        var text = document.createTextNode( title );
        
        a.appendChild( text );
        
        // Build TOC for child nodes
        
        BuildToc( entry, div, indent + 16, mergeHint ? subPath : fullPath );
    }
}

var gStylesDoc  = null; // Use global variable for XML doc because Safari deallocated the XML nodes when the XML doc was unloaded

function CacheStyles()
{
    var xmlParser   = new CMCXmlParser();
    
    gStylesDoc      = xmlParser.Load( parent.parent.gRootFolder + parent.parent.gSkinFolder + "Stylesheet.xml", false, null );
    
    var styles          = gStylesDoc.getElementsByTagName( "Style" );
    var tocEntryStyle   = null;
    
    for ( var i = 0; i < styles.length; i++ )
    {
        if ( styles[i].getAttribute( "Name" ) == "TocEntry" )
        {
            tocEntryStyle = styles[i];
        }
    }
    
    if ( tocEntryStyle )
    {
        var properties  = FMCGetChildNodesByTagName( tocEntryStyle, "Properties" );
        
        if ( properties.length > 0 )
        {
            var nameToValueMap  = new CMCDictionary();
            var props           = properties[0].childNodes;
            
            for ( var i = 0; i < props.length; i++ )
            {
                var prop    = props[i];
                
                if ( prop.nodeType != 1 ) { continue; }
                
                nameToValueMap.SetItem( prop.getAttribute( "Name" ), prop.firstChild.nodeValue );
            }
            
            gStyles.SetItem( "TocEntry_" + tocEntryStyle.getAttribute( "Name" ), nameToValueMap );
        }
        
        //
        
        var styleClasses    = tocEntryStyle.getElementsByTagName( "StyleClass" );
        
        for ( var i = 0; i < styleClasses.length; i++ )
        {
            var properties  = FMCGetChildNodesByTagName( styleClasses[i], "Properties" );
            
            if ( properties.length > 0 )
            {
                var nameToValueMap  = new CMCDictionary();
                var props           = properties[0].childNodes;
                
                for ( var j = 0; j < props.length; j++ )
                {
                    var prop    = props[j];
                    
                    if ( prop.nodeType != 1 ) { continue; }
                    
                    nameToValueMap.SetItem( prop.getAttribute( "Name" ), prop.firstChild.nodeValue );
                }
                
                gStyles.SetItem( "TocEntry_" + styleClasses[i].getAttribute( "Name" ), nameToValueMap );
            }
        }
    }
}

function ConvertToCSS( prop )
{
    if ( prop == "TopicIcon" || prop == "BookIcon" || prop == "BookOpenIcon" || prop == "HtmlHelpIconIndex" || prop == "MarkAsNew" )
    {
        return prop;
    }
    else
    {
        return prop.charAt( 0 ).toLowerCase() + prop.substring( 1, prop.length );
    }
}

function CreateToc( a )
{
	StartLoading();
	
	//
	
	var headNode	= a.parentNode;
    var xmlFile     = FMCGetMCAttribute( headNode.getElementsByTagName( "a" )[0], "MadCap:chunk" );
    
    FMCRemoveMCAttribute( a, "MadCap:chunk" );
    
    var xmlPath     = (xmlFile.indexOf( "/" ) == -1) ? parent.parent.gRootFolder + "Data/" + xmlFile : xmlFile;
    var xmlParser   = new CMCXmlParser( a );
    var xmlDoc      = xmlParser.Load( xmlPath, true, OnTocXmlLoaded );
}

function OnTocXmlLoaded( xmlDoc, a )
{
    if ( !xmlDoc || !xmlDoc.documentElement )
    {
        EndLoading();
        
        return;
    }
    
    var headNode	= a.parentNode;
    var indent      = parseInt( headNode.style.textIndent );
    var helpSystem  = GetOwnerHelpSystem( headNode );
    var path        = helpSystem.GetPath();
    
    indent += (headNode.parentNode.id == "CatapultToc") ? 0 : 16;
    
    BuildToc( xmlDoc.documentElement, headNode, indent, path );
    
    //
    
    TocExpand( a );
    
    //
    
    EndLoading();
    
    //
    
    if ( gSyncContinue )
    {
		gSyncContinue = false;
		SyncTOC( gSyncTocPath );
    }
}

function StartLoading()
{
// IE bug: This causes the tab outline not to show and also causes the TOC entry fonts to look bold.
//	if ( document.getElementsByTagName( "div" )[1].filters )
//	{
//		document.getElementsByTagName( "div" )[1].style.filter = "alpha( opacity = 10 )";
//	}
	/*else*/ if ( document.getElementsByTagName( "div" )[1].style.MozOpacity != null )
	{
		document.getElementsByTagName( "div" )[1].style.MozOpacity = "0.1";
	}
    
    var img	= document.createElement( "img" );
    
    img.id = "Loading";
    img.src = "Images/Loading.gif";
    img.alt = "Loading";
    img.style.width = "74px";
    img.style.height = "26px";
    img.style.position = "absolute";
    img.style.top = ((FMCGetScrollTop( window ) + (FMCGetClientHeight( window ) - 26) / 2)) + "px";
    img.style.left = ((FMCGetScrollLeft( window ) + (FMCGetClientWidth( window ) - 74) / 2)) + "px";
    
    document.body.appendChild( img );
}

function EndLoading()
{
	var div	= document.getElementById( "Loading" );
	
	div.parentNode.removeChild( div );
	
// IE bug: This causes the tab outline not to show and also causes the TOC entry fonts to look bold.
//	if ( document.getElementsByTagName( "div" )[1].filters )
//	{
//		document.getElementsByTagName( "div" )[1].style.filter = "alpha( opacity = 100 )";
//	}
	/*else*/ if ( document.getElementsByTagName( "div" )[1].style.MozOpacity != null )
	{
		document.getElementsByTagName( "div" )[1].style.MozOpacity = "1.0";
	}
}

function Init()
{
    if ( gInit )
    {
        return;
    }
    
    gInit = true;
    
    //
    
    FMCPreloadImage( "Images/Loading.gif" );
    CacheStyles();
    CreateToc( document.getElementById( "CatapultToc" ).getElementsByTagName( "div" )[0].getElementsByTagName( "a" )[0] );
}

function TocExpand( node )
{
    var tocEntries  = node.parentNode.childNodes;
    
    for ( var i = 0; i < tocEntries.length; i++ )
    {
        var tocEntry = tocEntries[i];
        
        if ( tocEntry.nodeName != "DIV" )
        {
            continue;
        }
        
        tocEntry.style.display = (tocEntry.style.display == "none") ? "block" : "none";
    }
    
    var imgs    = node.getElementsByTagName( "img" );
    
    if ( imgs.length == 2 )
    {
        FMCImageSwap( node.getElementsByTagName( "img" )[1], "swap" );
    }
    else if ( imgs.length == 1 )
    {
        FMCImageSwap( node.getElementsByTagName( "img" )[0], "swap" );
    }
    
    ScrollToVisible( node.parentNode );
}

