// {{MadCap}} //////////////////////////////////////////////////////////////////
// Copyright: MadCap Software, Inc - www.madcapsoftware.com ////////////////////
////////////////////////////////////////////////////////////////////////////////
// <version>1.0.0.0</version>
////////////////////////////////////////////////////////////////////////////////

var gInit                       = false;
var gIndexItems                 = new Array();
var gLinkMap                    = new CMCDictionary();
var gChunks                     = null;
var gAlphaMap                   = new CMCDictionary();
var gSelectedItem               = null;
var gStylesMap                  = new CMCDictionary();
var gEntryHeight                = 15;
var gSelectionColor             = null;
var gSelectionBackgroundColor   = "#cccccc";

function FindChunk( item )
{
    for ( var i = 0; i < gChunks.length; i++ )
    {
        var chunk   = gChunks[i];
        var start   = parseInt( chunk.getAttribute( "Start" ) );
        var count   = parseInt( chunk.getAttribute( "Count" ) );
        
        if ( item >= start && item < start + count )
        {
            return i;
        }
    }
}

function LoadChunk( index )
{
    var xmlParser   = new CMCXmlParser();
    var xmlDoc      = xmlParser.Load( parent.parent.gRootFolder + "Data/" + gChunks[index].getAttribute( "Link" ), false, null );
    var i           = parseInt( gChunks[index].getAttribute( "Start" ) );
    
    BuildIndex( xmlDoc.getElementsByTagName( "IndexEntry" )[0].getElementsByTagName( "Entries" )[0], document.getElementById( "CatapultIndex" ), i, 0 );
}

function LoadChunksForLetter( letter )
{
    var item    = gAlphaMap.GetItem( letter );
    var chunk   = FindChunk( item );
    
    while ( true )
    {
        LoadChunk( chunk );
        
        //
        
        if ( chunk == gChunks.length - 1 )
        {
            break;
        }
        
        var next    = gChunks[++chunk].getAttribute( "FirstTerm" ).charAt( 0 ).toLowerCase();
        
        if ( next > letter )
        {
            break;
        }
    }
}

function RefreshIndex()
{
    if ( !gChunks )
    {
        return;
    }
    
    var div         = document.getElementById( "CatapultIndex" ).parentNode;
    var firstIndex  = Math.floor( div.scrollTop / gEntryHeight );
    var lastIndex   = Math.ceil( (div.scrollTop + parseInt( div.style.height )) / gEntryHeight );
    
    for ( var i = firstIndex; i < lastIndex; i++ )
    {
        if ( !gIndexItems[i] )
        {
            var chunk   = FindChunk( i );
            
            if ( chunk >= 0 )
            {
                LoadChunk( chunk );
            }
        }
    }
    
    // Debug
    //window.status = "items: " + gIndexItems.length + " scrollTop: " + div.scrollTop + " height: " + height + " firstIndex: " + firstIndex + " lastIndex: " + lastIndex;
}

function BuildIndex( xmlNode, htmlNode, item, indent )
{
    for ( var i = 0; i < xmlNode.childNodes.length; i++ )
    {
        var entry = xmlNode.childNodes[i];
        
        if ( entry.nodeName != "IndexEntry" )
        {
            continue;
        }
        
        var div     = document.createElement( "div" );
        var term    = FMCGetAttribute( entry, "Term" );
        var links   = FMCGetChildNodesByTagName( entry, "Links" )[0].getElementsByTagName( "IndexLink" );
        
        if ( !term )
        {
            term = "";
        }
        
        div.style.position = "absolute";
        div.style.top = (gEntryHeight * item) + "px";
        div.style.textIndent = indent + "px";
        div.style.whiteSpace = "nowrap";
        htmlNode.appendChild( div );
        
        gIndexItems[item++] = div;
        
        var a;
        
        if ( links && links.length <= 1 )
        {
            a = document.createElement( "a" );
            
            if ( links.length == 1 )
            {
                var link = FMCGetAttribute( links[0], "Link" );
                
                link = (link.charAt( 0 ) == "/") ? ".." + link : link;
                
                a.setAttribute( "href", link );
                a.setAttribute( "target", "body" );
            }
            else
            {
                a.setAttribute( "href", "javascript:void( 0 );" );
            }
            
            a.onclick = function () { HighlightEntry( this.parentNode ); };
            
            a.appendChild( document.createTextNode( term ) );
        }
        else if ( links && links.length > 1 )
        {
            a = GenerateKLink( term, links );
        }
        
        for ( var key in gStylesMap.GetKeys() )
        {
            a.style[key] = gStylesMap.GetItem( key );
        }
        
        a.onmouseover = function() { this.style.color = "#ff0000"; };
        a.onmouseout = function() { this.style.color = gStylesMap.GetItem( "color" ) ? gStylesMap.GetItem( "color" ) : "#0055ff"; };
        
        div.appendChild( a );
        
        SetLinkMap( (indent / 16) + "_" + term.toLowerCase(), links );
        
        item = BuildIndex( entry.getElementsByTagName( "Entries" )[0], htmlNode, item, indent + 16 );
    }
    
    return item;
}

function SetLinkMap( term, links )
{
    var linkMap = new CMCDictionary();
    
    for ( var i = 0; i < links.length; i++ )
    {
        linkMap.SetItem( FMCGetAttribute( links[i], "Title" ), FMCGetAttribute( links[i], "Link" ) );
    }
    
    gLinkMap.SetItem( term, linkMap );
}

function CreateIndex( htmlIndexHead, item, indent, xmlDoc )
{
    var chunks      = xmlDoc.getElementsByTagName( "Chunk" );
    var xmlHead     = xmlDoc.getElementsByTagName( "CatapultTargetIndex" )[0];
    var count       = parseInt( FMCGetAttribute( xmlHead, "Count" ) );
    var attributes  = xmlHead.attributes;
    
    for ( var i = 0; i < attributes.length; i++ )
    {
        var name    = attributes[i].nodeName;
        var value   = parseInt( attributes[i].nodeValue );
        
        if ( name.substring( 0, 5 ) != "Char_" && name.substring( 0, 5 ) != "char_" )
        {
            continue;
        }
        
        var first   = String.fromCharCode( name.substring( 5, name.length )  ).toLowerCase();
        var start   = gAlphaMap.GetItem( first );
        
        if ( start != undefined )
        {
            value = Math.min( value, start );
        }
        
        gAlphaMap.SetItem( first, value );
    }
    
    if ( chunks.length == 0 )
    {
        var xmlNode = xmlDoc.getElementsByTagName( "IndexEntry" )[0].getElementsByTagName( "Entries" )[0];
        var count   = 0;
        
        for ( var i = 0; i < xmlNode.childNodes.length; i++ )
        {
            var entry = xmlNode.childNodes[i];
            
            if ( entry.nodeName == "IndexEntry" )
            {
                var term    = FMCGetAttribute( entry, "Term" );
                
                if ( !term )
                {
                    term = "";
                }
                
                var first   = term.charAt( 0 ).toLowerCase();
                
                if ( gAlphaMap.GetItem( first ) == undefined )
                {
                    gAlphaMap.SetItem( first, count );
                }
                
                // When incrementing, must include all sub-level index entries
                
                count += entry.getElementsByTagName( "IndexEntry" ).length + 1;
            }
        }
        
        BuildIndex( xmlDoc.getElementsByTagName( "IndexEntry" )[0].getElementsByTagName( "Entries" )[0], htmlIndexHead, item, indent );
    }
    
    document.getElementById( "CatapultIndex" ).style.height = count * gEntryHeight + "px";
    gChunks = chunks;
}

function GenerateKLink( term, links )
{
    var a       = document.createElement( "a" );
    var topics  = "";
    
    for ( var i = 0; i < links.length; i++ )
    {
        if ( i > 0 )
        {
            topics += "||";
        }
        
        var link    = FMCGetAttribute( links[i], "Link" );
        
        link = (link.charAt( 0 ) == "/") ? ".." + link : link;
        
        topics += FMCGetAttribute( links[i], "Title" ) + "|" + link;
    }
    
    a.href = "javascript:void( 0 );";
    a.className = "MCKLink";
    a.setAttribute( "MadCap:topics", topics );
    a.onclick = function( e ) { HighlightEntry( this.parentNode ); FMCLinkControl( e, this ); return false; };
    a.onkeydown = function() { this.MCKeydown = true; };
    a.appendChild( document.createTextNode( term ) );
    
    return a;
}

function Init()
{
    if ( gInit )
    {
        return;
    }
    
    gInit = true;
    
    //
    
    var fontSize    = gStylesMap.GetItem( "fontSize" ) ? parseInt( gStylesMap.GetItem( "fontSize" ) ) : 12;
    
    gEntryHeight = fontSize + 3;
    
    //
    
    var xmlDoc  = parent.parent.GetMasterHelpSystem().GetIndex();
    
    CreateIndex( document.getElementById( "CatapultIndex" ), 0, 0, xmlDoc );
    RefreshIndex();
}

function HighlightEntry( node )
{
    if ( gSelectedItem )
    {
        var color           = gStylesMap.GetItem( "color" );
        var backgroundColor = gStylesMap.GetItem( "backgroundColor" );
        
        gSelectedItem.firstChild.style.color = color ? color : "#0055ff";
        gSelectedItem.firstChild.style.backgroundColor = backgroundColor ? backgroundColor : "Transparent";
    }
    
    gSelectedItem = node;
    
    if ( gSelectedItem )
    {
        if ( gSelectionColor )
        {
            gSelectedItem.firstChild.style.color = gSelectionColor;
        }
        
        gSelectedItem.firstChild.style.backgroundColor = gSelectionBackgroundColor;
    }
}

function SelectEntry( e )
{
    if ( !e )
    {
        e = window.event;
    }
    
    if ( e.keyCode == 116 )
    {
        return;
    }
    else if ( e.keyCode == 13 )
    {
        if ( gSelectedItem )
        {
            parent.parent.frames["body"].location.href = gSelectedItem.childNodes[0].href;
        }
        
        return;
    }
    
    var text            = document.getElementById( "searchField" ).value.toLowerCase();
    var textParts       = text.split( "," );
    var currIndexItem   = null;
    
    for ( var i = 0; i < textParts.length; i++ )
    {
        if ( i == 0 )
        {
            currIndexItem = SelectFirstLevel( FMCTrim( textParts[i] ) );
        }
        else
        {
            currIndexItem = SelectSubLevel( FMCTrim( textParts[i] ), currIndexItem );
        }
    }
    
    HighlightEntry( currIndexItem );
    document.getElementById( "CatapultIndex" ).parentNode.scrollTop = currIndexItem ? currIndexItem.offsetTop : 0;
    RefreshIndex();
}

function SelectFirstLevel( text )
{
    var first           = text.charAt( 0 );
    var item            = gAlphaMap.GetItem( first );
    var currIndexItem   = null;
    
    if ( item >= 0 )
    {
        var indexItem   = gIndexItems[item];
        
        for ( var i = item; ; i++ )
        {
            if ( !gIndexItems[i] )
            {
                LoadChunksForLetter( first );
                
                indexItem = gIndexItems[item];
            }
            
            currIndexItem = gIndexItems[i];
            
            var term    = currIndexItem.firstChild.firstChild.nodeValue.toLowerCase();
            
            if ( currIndexItem.style.textIndent != indexItem.style.textIndent )
            {
                continue;
            }
            else if ( term.substring( 0, text.length ) == text )
            {
                break;
            }
            else if ( term > text || term.charAt( 0 ) != first || i == gIndexItems.length - 1 )
            {
                break;
            }
        }
    }
    
    return currIndexItem;
}

function SelectSubLevel( text, indexItem )
{
    var level   = (parseInt( indexItem.style.textIndent ) / 16) + 1;
    var subText = text;
    
    if ( !indexItem.nextSibling || parseInt( indexItem.nextSibling.style.textIndent ) / 16 < level )
    {
        return indexItem;
    }
    
    var foundIndexItem  = indexItem.nextSibling;
    var currIndexItem   = foundIndexItem;
    
    while ( true )
    {
        if ( !currIndexItem )
        {
            break;
        }
        
        var currLevel   = parseInt( currIndexItem.style.textIndent ) / 16;
        
        if ( currLevel == level )
        {
            var subTerm = currIndexItem.firstChild.firstChild.nodeValue.toLowerCase();
            
            foundIndexItem = currIndexItem;
            
            if ( subTerm.substring( 0, subText.length ) == subText )
            {
                break;
            }
        }
        else if ( currLevel < level )
        {
            break;
        }
        
        currIndexItem = currIndexItem.nextSibling;
    }
    
    return foundIndexItem;
}

