YAHOO.namespace("TermLookup");

YAHOO.TermLookup = {
    PopupId: 'TermLookupPopup',
    ClassName: 'TermLookup',
    Terms: new Array(),
    Roots: new Array(),
    RegEx: '',

init: function(e)
{
    //if (window.console) window.console.info('Starting TermLookup init...', this);
    
    // setup closure var for onSuccess
    var my = this;
    
    // find root elements
    my.Roots = YAHOO.util.Dom.getElementsByClassName(my.ClassName, "div");
    if (my.Roots && my.Roots.length > 0)
    {
        // load terms
        new Ajax.Request(YAHOO.TeachingToday.base_url + 'glossary/terms', {
            method: 'get',
            onSuccess: function(transport)
            {
                //if (window.console) window.console.info('Transport', transport);

                my.TermList = '';
                
                // check for JSON in header already. if not, parse out of body
                //if (window.console) window.console.info('JSON response: ', transport.responseText.replace(/: /g, '\n: '));
                try { 
                    if (transport.responseText.evalJSON)
                        json = transport.responseText.evalJSON(true);
                    else
                        json = eval('(' + transport.responseText + ')', this);
                }
                catch (exc) { if (window.console) window.console.info('Exception during parsing: ', exc); }
                if (window.console) window.console.info('JSON response after checks and parsing: ', json);
                
                if (json && json.terms)
                {
                    my.Terms = json.terms;
                    
                    // put in regex format
                    for (var t in my.Terms)
                    {
                        if (my.TermList.length > 0)
                            my.TermList += '|';
                        my.TermList += t.replace(/([\\\$\^[\]*?+{}.\(\)])/g, '\\$1');   // escape all special regex characters
                    }
                }
                else if (window.console)
                {
                    window.console.error('JSON did not return the "terms" object.');
                }

                // build regex
                var regexstr = "([\\s\\.\\(\\),'!:;-])(" + my.TermList + ")([\\s\\.\\(\\),'!:;-\\?])";
                my.RegEx = new RegExp(regexstr, "gi");

                //if (window.console) window.console.info('RegEx', regexstr);
        
                if (my.Terms 
                    && my.Terms.constructor.toString().indexOf("Object") > -1 
                    //&& my.Terms.length > 0
                    )
                {
                    // valid terms, find text block to walk and start the iteration
                    if (my.Roots && my.Roots.length > 0)
                    {
                        for(var i = 0; i < my.Roots.length; i++)
                        {
                            //if (window.console) window.console.info('Setting timeout for root:', my.Roots[i]);
                            setTimeout(my.setWalk(my.Roots[i]), 100);
                        }
                    } else {
                        if (window.console) window.console.error('No root elements were set.', my.Roots);
                    }
                }
            },
            onFailure: function(transport)
            {
                if (window.console) window.console.warn('Failed to load term list.', transport);
            }
        });
                    
        // setup Tooltip container
        this.Container = new YAHOO.widget.Overlay(this.PopupId, { 
            constraintoviewport: true,
            width: '208px',
            visible: false
            });
        if (!this.Container.render() && window.console) window.console.error('Failed to render term lookup tooltip pop-up.');

    }   // end if for my.Roots set and valid
    else
    {
        // this is okay--just means no content needs any term markup
        //if (window.console) window.console.error('Could not find any elements of class "' + my.ClassName + '"', my.Roots);
    }

    //if (window.console) window.console.info('Finished TermLookup init.', this);
},

setWalk: function(node)
{
    return (function() { YAHOO.TermLookup.walkTree(node); } );
},

walkTree: function(node)
{
    // this method only called after validating that there are terms to search, so no need to check again in each method call
    //if (window.console) window.console.info('Node & type', node, node.nodeType);
    // see if this is a text node, if so check
    if (node.nodeType == 3)
    {
        //debugger;
        /*
        if (window.console && node.nodeValue != '\n' && node.nodeValue != ' ' && node.nodeValue != '.');
            window.console.info('Node & type', node, node.nodeType);
        /*if (node.nodeValue != '\n' && node.nodeValue != ' ' && node.nodeValue != '.')
            debugger;*/
        /*if (node.nodeValue.match(/differentiated instruction/))
            debugger;*/
        try {
            if (node.parentNode && node.parentNode.nodeType == 1 && node.parentNode.childNodes.length == 1
                //&& node.parentNode.tagName && node.parentNode.tagName.toLowerCase() != 'a' // don't add an A tag within an A tag
                //&& node.parentNode.innerHTML.replace(/&nbsp;/, ' ') == node.nodeValue
                //&& node.parentNode.tagName.toLowerCase() == 'span'
                )
                /* A tag version
                node.parentNode.innerHTML = node.nodeValue.replace(this.RegEx, 
                    '$1<a class="' + this.PopupId + '" href="' + YAHOO.TeachingToday.base_url + 'glossary/index/$2' + // TODO: fix that \\2 should actually be the first letter of the uppercase term (maybe just grab the first letter in the PHP controller?)
                    '#$2' +    // TODO: fix so \\2 is url_title escaped (see CI code for matching regex)
                    '" title="View glossary description for this term" class="' + 
                    this.PopupId + // can't use this.ClassName as the YAHOO container overwrites with this.PopupId
                    '"' +
                    ' onmouseover="YAHOO.TermLookup.display(this, true); return false;" onmouseout="YAHOO.TermLookup.display(this, false); return false;"' +
                    '>$2</a>$3');
                */
                // SPAN tag version
                node.parentNode.innerHTML = node.nodeValue.replace(this.RegEx, 
                    '$1<span class="' + this.ClassName + '"' +
                    (node.parentNode.tagName && node.parentNode.tagName.toLowerCase() != 'a' // don't add an A tag within an A tag
                        ? ' onclick="window.open(\'' + YAHOO.TeachingToday.base_url + 'glossary/index/$2' + // TODO: fix that \\2 should actually be the first letter of the uppercase term (maybe just grab the first letter in the PHP controller?)
                        '#$2\', \'glossaryterm\', \'\');"'    // TODO: fix so \\2 is url_title escaped (see CI code for matching regex)
                        : '') +
                    ' onmouseover="YAHOO.TermLookup.display(this, true);" onmouseout="YAHOO.TermLookup.display(this, false);"' +
                    '>$2</span>$3');
        } catch (exc) { /* ignore stupid IE7 "Invalid Argument" errors when viewing (basically) empty nodes and trying to even _test_ for the node.parentNode property */ }
    }
    else if (node.children && node.children.length > 0)
    {
        // 'children' array only returns Element-type nodes
        var children = node.children;
        for (var i = children.length - 1; i >= 0; i--)
        { if (node.nodeType == 1 || node.nodeType == 3) setTimeout(this.setWalk(children[i]), 0); }
    }
    else if (node.childNodes && node.childNodes.length > 0)
    {
        // for anything that doesn't support the 'children' array
        var children = node.childNodes;
        var childrenLength = children.length;
        for (var i = children.length - 1; i >= 0; i--)
        { if (node.nodeType == 1 || node.nodeType == 3) setTimeout(this.setWalk(children[i]), 0); }
    }
    else
    {
        //if (window.console) window.console.warn('Unknown node & type: ', node, node.nodeType);
    }
},

display: function(elem, show) {
    // set default show to true
    if (!show && show !== false)
        show = true;
    this.Container.visible = true;
        
    //if (window.console) window.console.info(show, this);

    if (this.Container)//&& this.TermDefinitions)
    {
        // set context (where to position the tooltip)
        this.Container.cfg.setProperty('context', [elem, 'tr', 'bl']);
        // actually move the overlay
        this.Container.align('tr', 'bl');
        
        // set description
        this.Container.setHeader(elem.innerHTML);
        if (this.Terms[elem.innerHTML.toLowerCase()])
            this.Container.setBody(this.Terms[elem.innerHTML.toLowerCase()].description);
        else if (this.Terms[elem.innerHTML])
            this.Container.setBody(this.Terms[elem.innerHTML].description);
        else
        {
            var notFound = true;
            // see if the combination of the text and term have some kind of mixed cases
            for (t in this.Terms)
            {
                if (this.Terms[t].term.toLowerCase() == elem.innerHTML.toLowerCase())
                {
                    this.Container.setBody(this.Terms[t].description);
                    notFound = false;
                    break;
                }
            }
            
            if (notFound)
            {
                this.Container.setBody('*Missing glossary description*');
                if (window.console) window.console.error('Missing description for ' + elem.innerHTML, this.Terms);
            }
        }
        
        if (show)
            this.Container.show();
        else
            this.Container.hide();
            
    }
    else
    {
        if (window.console) window.console.error('Popup container not found.', this.PopupId);
    }
}

};





//if (window.console) window.console.info('Adding TermLookup init onContentReady...');

YAHOO.util.Event.onDOMReady(YAHOO.TermLookup.init, YAHOO.TermLookup, true);