// Configuration:
Hilite = {
    /**
     * Element ID to be highlighted. If set, then only content inside this DOM
     * element will be highlighted, otherwise everything inside document.body
     * will be searched.
     */
    elementid: 'articleBody',
    
    /**
     * Whether we are matching an exact word. For example, searching for
     * "highlight" will only match "highlight" but not "highlighting" if exact
     * is set to true.
     */
    exact: true,

    /**
     * Maximum number of DOM nodes to test, before handing the control back to
     * the GUI thread. This prevents locking up the UI when parsing and
     * replacing inside a large document.
     */
    max_nodes: 1000,

    /**
     * Whether to automatically hilite a section of the HTML document, by
     * binding the "Hilite.hilite()" to window.onload() event. If this
     * attribute is set to false, you can still manually trigger the hilite by
     * calling Hilite.hilite() in Javascript after document has been fully
     * loaded.
     */
    onload: true,

    /**
     * Name of the style to be used. Default to 'hilite'.
     */
    style_name: 'stockLink',
    
    /**
     * Whether to use different style names for different search keywords by
     * appending a number starting from 1, i.e. hilite1, hilite2, etc.
     */
    style_name_suffix: false,

    /**
     * Set it to override the document.referrer string. Used for debugging
     * only.
     */
    debug_referrer: ''
};


/**
 * Highlight a DOM element with a list of keywords.
 */
Hilite.hiliteElement = function(elm, query) {
    if (!query || elm.childNodes.length == 0)
	return;

    var qre = new Array();
    var symbolmapper = {};
    var historymapper ={};

    for (var i = 0; i < query.length; i ++) {
        var myQuery=query[i];
        myQuery[0] = myQuery[0].toLowerCase();
        if (Hilite.exact)
            qre.push('\\b'+myQuery[0]+'\\b');
        else
            qre.push(myQuery[0]);
        symbolmapper[myQuery[0]]=myQuery[1];
		symbolmapper[myQuery[1]]=myQuery[2];
    }

    qre = new RegExp(qre.join("|"), "i");

    var textproc = function(node) {
        var match = qre.exec(node.data);
        if (match && !node.parentNode.href && symbolmapper[match[0].toLowerCase()] != null && historymapper[symbolmapper[match[0].toLowerCase()]] ==null) {
            var val = match[0];
			var val2 = symbolmapper[val.toLowerCase()];
            var k = '';
            var node2 = node.splitText(match.index);
            var node3 = node2.splitText(val.length);
           
            var left = document.createTextNode(" ("+symbolmapper[val2]+":");
            var stock = document.createTextNode(symbolmapper[val.toLowerCase()]);
            var right = document.createTextNode(")");
            
            if (node3.data == null){
                 node.parentNode.appendChild(left);
                 node.parentNode.appendChild(stock); 
                 node.parentNode.appendChild(right);
            }
            else{
                 node.parentNode.insertBefore(left,node3);
                 node.parentNode.insertBefore(stock,node3); 
                 node.parentNode.insertBefore(right,node3);
            }
            var link = node.ownerDocument.createElement('A');
            node.parentNode.replaceChild(link, stock);
            link.className = Hilite.style_name;
            link.href="/tools/quotes/index.jhtml?Page=QUOTE&Ticker="+symbolmapper[val.toLowerCase()];
            link.target="_blank";
            link.appendChild(stock);
            historymapper[symbolmapper[val.toLowerCase()]]=val.toLowerCase();
            symbolmapper[val.toLowerCase()]=null;
            return link;
        } else {
            return node;
        }
    };
    Hilite.walkElements(elm.childNodes[0], 1, textproc);
};

/**
 * Highlight a HTML document using keywords extracted from document.referrer.
 * This is the main function to be called to perform search engine highlight
 * on a document.
 *
 * Currently it would check for DOM element 'content', element 'container' and
 * then document.body in that order, so it only highlights appropriate section
 * on WordPress and Movable Type pages.
 */
Hilite.hilite = function() {
    var e = null;
    var q = [['3Com Corp.','COMS','NSDQ'],
['3Com','COMS','NSDQ'],
['3M Company','MMM','NYSE'],
['3M','MMM','NYSE'],
['Adobe Systems','ADBE','NSDQ'],
['Adobe','ADBE','NSDQ'],
['Accenture Ltd.','ACN ','NYSE'],
['Advanced Micro Devices','AMD','NYSE'],
['Affiliated Computer','ACS','NYSE'],
['Agilent Technologies','A','NYSE'],
['Agilent','A','NYSE'],
['Alcatel Lucent','ALU','NYSE'],
['Alcatel','ALU','NYSE'],
['Alcatel-Lucent Technologies','ALU','NYSE'],
['Alcatel-Lucent','ALU','NYSE'],
['Alltel','AT','NYSE'],
['Amazon Corp.','AMZN','NSDQ'],
['Amazon','AMZN','NSDQ'],
['AMD','AMD','NYSE'],
['American Power Conversion','APCC','NSDQ'],
['Analog Devices','ADI','NYSE'],
['APC','APCC','NSDQ'],
['Apple','AAPL','NSDQ'],
['Applied Materials','AMAT','NSDQ'],
['Arrow Electronics','ARW','NYSE'],
['AT&T Inc.','T','NYSE'],
['AT&T','T','NYSE'],
['Autodesk, Inc.','ADSK','NSDQ'],
['Autodesk','ADSK','NSDQ'],
['Automatic Data Processing Inc.','ADP','NYSE'],
['Avaya Inc.','AV','NYSE'],
['Avaya','AV','NYSE'],
['Avnet','AVT','NYSE'],
['Azerty','USTR','NSDQ'],
//['BellSouth','BLS',''],
['BearingPoint Inc.','BE ','NYSE'],
['Bell Microproducts','BELM','NSDQ'],
['Best Buy Co, Inc.','BBY','NYSE'],
['Best Buy Co','BBY','NYSE'],
['Best Buy','BBY','NYSE'],
['BMC Software','BMC','NYSE'],
['BMC','BMC','NYSE'],
['Brightpoint','CELL','NSDQ'],
['Broadcom Corporation','BRCM','NSDQ'],
['Broadcom','BRCM','NSDQ'],
['Broadvision Inc.','BVSN.OB','OTC BB'],
['Broadvision','BVSN',''],
['Business Objects','BOBJ ','NSDQ'],
['CA, Inc.','CA','NYSE'],
['CA','CA','NYSE'],
['Canon Inc.','CAJ','NYSE'],
['Canon','CAJ','NYSE'],
['CGI Group','GIB ','NYSE'],
['Check Point Software Technologies Ltd.','CHKP','NSDQ'],
['Check Point Software','CHKP','NSDQ'],
['Ciena Corp.','CIEN','NSDQ'],
['Ciena','CIEN','NSDQ'],
['Circuit City Group','CC','NYSE'],
['Circuit City','CC','NYSE'],
['Cisco Systems','CSCO','NSDQ'],
['Cisco','CSCO','NSDQ'],
['Citrix Systems','CTXS','NSDQ'],
['Citrix','CTXS','NSDQ'],
['CNet Networks','CNET','NSDQ'],
['CNet','CNET','NSDQ'],
['Comcast Corp.','CMCSA','NSDQ'],
['Comcast','CMCSA','NSDQ'],
['Computer Associates','CA','NYSE'],
['Computer Sciences Corp.','CSC','NYSE'],
['Computer Sciences','CSC','NYSE'],
['Compuware Corp.','CPWR','NSDQ'],
['Compuware','CPWR','NSDQ'],
['Convergys','CVG ','NYSE'],
['Corning Inc.','GLW','NYSE'],
['Corning','GLW','NYSE'],
['Dell Inc.','Dell','NSDQ'],
['Dell','Dell','NSDQ'],
['DST Systems','DST ','NYSE'],
['Earthlink Inc.','ELNK','NSDQ'],
['Earthlink','ELNK','NSDQ'],
['Eastman Kodak','EK','NYSE'],
['Eastman Kodak','EK','NYSE'],
['eBay Inc.','EBAY','NSDQ'],
['eBay','EBAY','NSDQ'],
['EDS','EDS','NYSE'],
['Electronic Arts Inc.','ERTS','NSDQ'],
['Electronic Arts','ERTS','NSDQ'],
['Electronic Data Systems','EDS','NYSE'],
['EMC Corp', 'EMC','NYSE'],
['EMC', 'EMC','NYSE'],
['Expedia Inc.','EXPE','NSDQ'],
['Expedia','EXPE','NSDQ'],
['FedEx Corporation','FDX','NYSE'],
['FedEx','FDX','NYSE'],
['Fiserv','FISV ','NSDQ'],
['Gateway Inc.','GTW','NYSE'],
['Gateway','GTW','NYSE'],
['General Dynamics','GD ','NYSE'],
['Google Inc.','GOOG','NSDQ'],
['Google','GOOG','NSDQ'],
['Hewlett Packard','HPQ','NYSE'],
['Hewlett-Packard','HPQ','NYSE'],
['HP','HPQ','NYSE'],
['IBM','IBM','NYSE'],
['IKON Office Solutions','IKN ','NYSE'],
['Ingram Micro','IM','NYSE'],
['Insight Enterprises','NSIT ','NSDQ'],
['Intel Corp.','INTC','NSDQ'],
['Intel','INTC','NSDQ'],
['International Bus Machines (IBM, Big Blue)','IBM','NYSE'],
['International Business Machines','IBM','NYSE'],
['Intuit Inc.','INTU','NSDQ'],
['Intuit','INTU','NSDQ'],
['Iomega Corp.','IOM','NYSE'],
['Iomega','IOM','NYSE'],
['Jabil Circuit','JBL','NYSE'],
['Jabil Circuit','JBL','NYSE'],
['JDS Uniphase Corp.','JDSU','NSDQ'],
['JDS Uniphase','JDSU','NSDQ'],
['Juniper Networks','JNPR','NSDQ'],
['Juniper Networks','JNPR','NSDQ'],
['L-3 Communiations','LLL ','NYSE'],
['Lockheed Martin','LMT ','NYSE'],
['Micron Technology','MU','NYSE'],
['Microsoft Corp.','MSFT','NSDQ'],
['Microsoft','MSFT','NSDQ'],
['Motorola Corp.','MOT','NYSE'],
['Motorola','MOT','NYSE'],
['NCR Corp.','NCR','NYSE'],
['NCR','NCR','NYSE'],
['NetManage Inc.','NETM','NSDQ'],
['NetManage','NETM','NSDQ'],
['Network Appliance','NTAP','NSDQ'],
['Nokia Inc.','NOK','NYSE'],
['Nokia','NOK','NYSE'],
['Nortel Networks','NT','NYSE'],
['Nortel','NT','NYSE'],
['Northrop Grumman','NOC ','NYSE'],
['Novell Inc.','NOVL','NSDQ'],
['Novell','NOVL','NSDQ'],
['Novellus Systems','NVLS','NSDQ'],
['Novellus','NVLS','NSDQ'],
['NVIDIA Corp.','NVDA','NSDQ'],
['NVIDIA','NVDA','NSDQ'],
['Office Depot','ODP','NYSE'],
['Office Depot','ODP','NYSE'],
['OfficeMax Inc.','OMX','NYSE'],
['OfficeMax','OMX','NYSE'],
['Oracle Corp.','ORCL111','NSDQ'],
['Oracle','ORCL','NSDQ'],
['Paychex Inc.','PAYX','NSDQ'],
['Paychex','PAYX','NSDQ'],
['Perot Systems','PER ','NYSE'],
['Progress Software','PRGS ','NSDQ'],
['Priceline','PCLN','NSDQ'],
['Priceline.com','PCLN','NSDQ'],
['Pricelinecom Inc.','PCLN','NSDQ'],
['Pricelinecom','PCLN','NSDQ'],
['Qwest Communications Int.','Q','NYSE'],
['Qwest Communications','Q','NYSE'],
['Qwest','Q','NYSE'],
['RadioShack Corp.','RSH','NYSE'],
['RadioShack','RSH','NYSE'],
['Real Networks Inc.','RNWK','NSDQ'],
['Real Networks','RNWK','NSDQ'],
['Research In Motion Ltd.','RIMM','NSDQ'],
['Research In Motion','RIMM','NSDQ'],
['RIM','RIMM','NSDQ'],
['SanDisk Corporation','SNDK','NSDQ'],
['SanDisk','SNDK','NSDQ'],
['Sanmina-SCI Corp.','SANM','NSDQ'],
['Sanmina-SCI','SANM','NSDQ'],
['SAP','SAP','NYSE'],
['SAP','SAP','NYSE'],
['Science Applications International','SAI ','NYSE'],
['Solectron','SLR','NYSE'],
['Solectron','SLR','NYSE'],
['Sprint Nextel','S','NYSE'],
['Sprint','S','NYSE'],
['Sun Microsystems','JAVA','NSDQ'],
['Sun Microsystems','JAVA','NSDQ'],
['Sybase','SY ','NYSE'],
['Synnex','SNX','NYSE'],
['Symantec Corp.','SYMC','NSDQ'],
['Symantec','SYMC','NSDQ'],
['Tech Data','TECD','NSDQ'],
['Tellabs Inc.','TLAB','NSDQ'],
['Tellabs','TLAB','NSDQ'],
['Texas Instruments','TXN','NYSE'],
['TI','TXN','NYSE'],
['Time Warner Inc.','TWX','NYSE'],
['Time Warner','TWX','NYSE'],
['Unisys Corp.','UIS','NYSE'],
['Unisys','UIS','NYSE'],
['Verisign Inc.','VRSN','NSDQ'],
['Verisign','VRSN','NSDQ'],
['Verizon Communications','VZ','NYSE'],
['Verizon','VZ','NYSE'],
['Viacom Inc.','VIAB','NYSE'],
['Viacom','VIAB','NYSE'],
['Vodafone Group Inc.','VOD','NYSE'],
['Vodafone','VOD','NYSE'],
['Xerox Corp.','XRX','NYSE'],
['Xerox','XRX','NYSE'],
['Yahoo Inc.','YHOO','NSDQ'],
['Yahoo','YHOO','NSDQ']];
 
    if (q && (Hilite.elementid && (e = document.getElementById(Hilite.elementid))))
    {
	Hilite.hiliteElement(e, q);
    }
};

Hilite.walkElements = function(node, depth, textproc) {
    var skipre = /^(script|style|textarea)/i;
    var count = 0;
    while (node && depth > 0) {
        count ++;
        if (count >= Hilite.max_nodes) {
            var handler = function() {
                Hilite.walkElements(node, depth, textproc);
            };
            setTimeout(handler, 50);
            return;
        }

        if (node.nodeType == 1) { // ELEMENT_NODE
            if (!skipre.test(node.tagName) && node.childNodes.length > 0) {
                node = node.childNodes[0];
                depth ++;
                continue;
            }
        }
        else if (node.nodeType == 3) { // TEXT_NODE
            if (!node.nextSibling || !node.previousSibling 
            	|| node.nextSibling.nodeType!=8 || node.previousSibling.nodeType!=8
            	|| node.nextSibling.data!="No Quote Ends" || node.previousSibling.data!="No Quote Starts") {
            	node = textproc(node); 
            }
        }

        if (node.nextSibling) {
            node = node.nextSibling;
        } else {
            while (depth > 0) {
                node = node.parentNode;
                depth --;
                if (node.nextSibling) {
                    node = node.nextSibling;
                    break;
                }
            }
        }
    }
};

// Trigger the highlight using the onload handler.
if (Hilite.onload) {
    if (window.attachEvent) {
        window.attachEvent('onload', Hilite.hilite);
    } else if (window.addEventListener) {
        window.addEventListener('load', Hilite.hilite, false);
    } else {
        var __onload = window.onload;
        window.onload = function() {
            Hilite.hilite();
            __onload();
        };
    }
}