﻿// Glossary Tagger Script...

// Define Namespace...

if (!WillCurson) var WillCurson = {};
if (!WillCurson.GlossaryTagger) WillCurson.GlossaryTagger = {};

//--------------------------------------------------------------------------------

WillCurson.GlossaryTagger = function()
{
    // Globals...

    // Data Array...
    this.data = [];

    // Comma Delimited Tag List...
    this.tagList = null;

    // Overlay Div ID...
    this.overlayID = null;

    // Dialog Box Header ID...
    this.dialogBoxHeaderID = null;

    // Dialog Box Body ID...
    this.dialogBoxBodyID = null;

    // Dialog Box Div ID...
    this.dialogBoxID = null

    // The ID Of This Glossary Tagger...
    this.taggerID = null;

    // Scroll Poller...
    this.scrollPoller = null;

    // Vertical Offset...
    this.vOffset = 0;

    // Flags...
    // ----------

    // Browser Is Internet Explorer...
    this.isIE7 = false;

    // ----------
};

//--------------------------------------------------------------------------------

WillCurson.GlossaryTagger.prototype.init = function(data)
{
    // Init...

    try 
    {
        // Set Data Array...
        this.data = data;

        // Run Tagger...
        this.tag();
    }
    catch (e)
    {
        alert("GlossaryTagger.init Error: " + e.message);
    }
};

//--------------------------------------------------------------------------------

WillCurson.GlossaryTagger.prototype.mouseOver = function(node)
{
    // Mouse Over...

    try
    {
        // Set Cursor...
        node.style.cursor = "help";
    }
    catch (e)
    {
        alert("GlossaryTagger.mouseOver Error: " + e.message);
    }
};

//--------------------------------------------------------------------------------

WillCurson.GlossaryTagger.prototype.mouseOut = function(node)
{
    // Mouse Over...

    try
    {
        // Set Cursor...
        node.style.cursor = "default";
    }
    catch (e)
    {
        alert("GlossaryTagger.mouseOut Error: " + e.message);
    }
};

//--------------------------------------------------------------------------------

WillCurson.GlossaryTagger.prototype.tag = function()
{
    // Mouse Over...

    try
    {
        // Create Tag Types Array From Tag List...

        var tagTypes = new Array();
        tagTypes = this.tagList.split(",");

        // Tag Type Index...
        var tagType = 0;

        // Iterate Through Tag Types...
        for (tagType = 0; tagType < tagTypes.length; tagType++)
        {
            // Get All Tags Of Tag Type On The Page...
            var tags = document.getElementsByTagName(tagTypes[tagType]);

            // Glossary Term Index...
            var term = 0;

            // Iterate Through All Terms In The Data Array...

            for (term = 0; term < this.data.length; term++)
            {
                // Tag Index...
                var index = 0;

                // Iterate Throught All Tags Of Tag Type...

                for (index = 0; index < tags.length; index++)
                {
                    // Do Not Tag Tags With The 'title' or 'no_tag' CSS Class...
                    if ((tags[index].className.search(/title/i) == -1) &&
                        (tags[index].className.search(/no_tag/i) == -1))
                    {                
                        // Build Regular Expression To Match The Term In Any Text Case As A Whole Word...
                        var reg = new RegExp("\\b" + this.data[term][0] + "\\b", 'gi');

                        // Run The RegEx...
                        // match Is An Array...
                        // match[0] -> The Matched Text...
                        // match[0].length -> The Length Of The Matched Text...
                        // match.index -> The Start Index Of The Matched Text...
                        // match.input -> The Searched Text...

                        var match = reg.exec(tags[index].innerHTML);

                        // Iterate Through The Text Looking For The Term...

                        while (match != null)
                        {
                            // String To Replace Any Matched Text With...
                            var middle = "<span class=\"glossary\" title=\"Click for a definition\" " +
                            "onmouseover=\"" + this.taggerID + ".mouseOver(this);\" " +
                            "onmouseout=\"" + this.taggerID + ".mouseOut(this);\" " +
                            "onclick=\"" + this.taggerID + ".openDialogBox('" + term + "');\" " +
                            ">" +
                            match[0] + "</span>";

                            // Sub String The Searched Text Up To The Start Of The Matched Text...
                            var begin = tags[index].innerHTML.substring(0, match.index);

                            // Sub String The Text After The Matched Text...
                            var end = tags[index].innerHTML.substring(match.index + match[0].length);

                            // Set The Tags Text To The Beggining Text Plus The Replacement Text Plus The End Text...
                            tags[index].innerHTML = begin + middle + end;

                            // Set The Point At Which The Search Resumes To The End Of The Replacement Text...
                            reg.lastIndex = (match.index + middle.length);

                            // Search For The Next Match...
                            match = reg.exec(tags[index].innerHTML);
                        }
                    }
                }
            }
        }
    }
    catch (e)
    {
        alert("GlossaryTagger.tag Error: " + e.message);
    }
};

//--------------------------------------------------------------------------------

WillCurson.GlossaryTagger.prototype.openDialogBox = function(termIndex)
{
    // Open Dialog Box...

    try
    {
        var overlay = document.getElementById(this.overlayID);
        var dialogBox = document.getElementById(this.dialogBoxID);

        // Display The Overlay...

        overlay.style.display = "block";
        dialogBox.style.display = "block";

        // Adjust Overlay Size To Cover Whole Page...

        var overlayHeight = document.documentElement.scrollHeight;
        overlay.style.height = overlayHeight + "px";

        // Set Vertial Position Of Dialog Box...

        this.vOffset = document.documentElement.scrollTop;
        var viewHeight = document.documentElement.offsetHeight;

        var dialogBoxHeightTokens = dialogBox.style.height.split("p");
        var dialogBoxHeight = parseInt(dialogBoxHeightTokens[0]);

        var vPosition = (this.vOffset + (viewHeight / 2) - (dialogBoxHeight / 2));

        dialogBox.style.top = vPosition + "px";

        // Set Horizontal Position Of Dialog Box...

        var hOffset = document.documentElement.scrollLeft;
        var viewWidth = document.documentElement.offsetWidth;

        var dialogBoxWidthTokens = dialogBox.style.width.split("p");
        var dialogBoxWidth = parseInt(dialogBoxWidthTokens[0]);

        var hPosition = (hOffset + (viewWidth / 2) - (dialogBoxWidth / 2));

        dialogBox.style.left = hPosition + "px";

        // Set Dialog Header Text...
        document.getElementById(this.dialogBoxHeaderID).innerHTML = this.data[termIndex][0];

        // Set Dialog Body Text...
        document.getElementById(this.dialogBoxBodyID).innerHTML = this.data[termIndex][1];
    
        // Start The Scroll Poller...
        this.scrollPoller = setInterval(this.taggerID + ".pollScroll()", 20);
    }
    catch (e)
    {
        alert("GlossaryTagger.openDialogBox Error: " + e.message);
    }
};

//--------------------------------------------------------------------------------

WillCurson.GlossaryTagger.prototype.closeDialogBox = function()
{
    // Close Dalog Box...

    try
    {
        var overlay = document.getElementById(this.overlayID);
        var dialogBox = document.getElementById(this.dialogBoxID);

        // Hide the overlay...

        overlay.style.display = "none";

        // Hide the dialog box...

        dialogBox.style.display = "none";

        // Stop the scroll polling...

        clearInterval(this.scrollPoller);
    }
    catch (e)
    {
        alert("GlossaryTagger.closeDialogBox Error: " + e.message);
    }
};

//--------------------------------------------------------------------------------

WillCurson.GlossaryTagger.prototype.pollScroll = function()
{
    // Poll Scroll...

    try
    {
        // Compares the current vertical offset with the one when the dialog box was positioned...
        // And closes the dialog box if the two are different i.e. scrolling has occurred...

        var currentOffset = document.documentElement.scrollTop;

        if (currentOffset != this.vOffset)
        {
            this.closeDialogBox();
        }
    }
    catch (e)
    {
        alert("GlossaryTagger.pollScroll Error: " + e.message);
    }
};

//--------------------------------------------------------------------------------