// 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,exchange) {
    if (!query || elm.childNodes.length == 0)
	return;

    var qre = new Array();
    var symbolmapper = {};
    var historymapper ={};
    var exchangemapper ={};

    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];
    }

    for (var i  =0; i<exchange.length; i ++){
        var myExchange = exchange[i];
        exchangemapper[myExchange[0]]=myExchange[1];
    }
    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 k = '';
            var node2 = node.splitText(match.index);
            var node3 = node2.splitText(val.length);
           
            var left;
            var  stockExchange=exchangemapper[symbolmapper[val.toLowerCase()]];
            if(stockExchange != null)
               left=document.createTextNode(" ("+stockExchange+": ");
            else
               left = document.createTextNode(" (");
            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="http://www.techweb.com/financialCenter/index.jhtml?Account=techweb&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'],
['3Com','COMS'],
['3M Company','MMM'],
['3M','MMM'],
['Adobe Systems','ADBE'],
['Adobe','ADBE'],
['Advanced Micro Devices','AMD'],
['Affiliated Computer','ACS'],
['Agilent Technologies','A'],
['Agilent','A'],
['Alcatel Lucent','ALU'],
['Alcatel','ALU'],
['Alcatel-Lucent Technologies','ALU'],
['Alcatel-Lucent','ALU'],
['Alltel','AT'],
['Amazon Corp.','AMZN'],
['Amazon','AMZN'],
['AMD','AMD'],
['American Power Conversion','APCC'],
['Analog Devices','ADI'],
['APC','APCC'],
['Apple Computer','AAPL'],
['Applied Materials','AMAT'],
['AT&T Inc.','T'],
['AT&T','T'],
['Autodesk, Inc.','ADSK'],
['Autodesk','ADSK'],
['Automatic Data Processing Inc.','ADP'],
['Avaya Inc.','AV'],
['Avaya','AV'],
['BellSouth','BLS'],
['Best Buy Co, Inc.','BBY'],
['Best Buy Co','BBY'],
['Best Buy','BBY'],
['BMC Software','BMC'],
['BMC','BMC'],
['Broadcom Corporation','BRCM'],
['Broadcom','BRCM'],
['Broadvision Inc.','BVSN'],
['Broadvision','BVSN'],
['CA, Inc.','CA'],
['CA','CA'],
['Canon Inc.','CAJ'],
['Canon','CAJ'],
['Check Point Software Technologies Ltd.','CHKP'],
['Check Point Software','CHKP'],
['Ciena Corp.','CIEN'],
['Ciena','CIEN'],
['Circuit City Group','CC'],
['Circuit City','CC'],
['Cisco Systems','CSCO'],
['Cisco','CSCO'],
['Citrix Systems','CTXS'],
['Citrix','CTXS'],
['CNet Networks','CNET'],
['CNet','CNET'],
['Comcast Corp.','CMCSA'],
['Comcast','CMCSA'],
['Computer Associates','CA'],
['Computer Sciences Corp.','CSC'],
['Computer Sciences','CSC'],
['Compuware Corp.','CPWR'],
['Compuware','CPWR'],
['Corning Inc.','GLW'],
['Corning','GLW'],
['Dell Inc.','Dell'],
['Dell','Dell'],
['Earthlink Inc.','ELNK'],
['Earthlink','ELNK'],
['Eastman Kodak','EK'],
['Eastman Kodak','EK'],
['eBay Inc.','EBAY'],
['eBay','EBAY'],
['EDS','EDS'],
['Electronic Arts Inc.','ERTS'],
['Electronic Arts','ERTS'],
['Electronic Data Systems','EDS'],
['EMC Corp', 'EMC'],
['EMC', 'EMC'],
['Expedia Inc.','EXPE'],
['Expedia','EXPE'],
['FedEx Corporation','FDX'],
['FedEx','FDX'],
['Gateway Inc.','GTW'],
['Gateway','GTW'],
['Google Inc.','GOOG'],
['Google','GOOG'],
['Hewlett Packard','HP'],
['Hewlett-Packard','HP'],
['HP','HP'],
['IBM','IBM'],
['Intel Corp.','INTC'],
['Intel','INTC'],
['International Bus Machines (IBM, Big Blue)','IBM'],
['International Business Machines','IBM'],
['Intuit Inc.','INTU'],
['Intuit','INTU'],
['Iomega Corp.','IOM'],
['Iomega','IOM'],
['Jabil Circuit','JBL'],
['Jabil Circuit','JBL'],
['JDS Uniphase Corp.','JDSU'],
['JDS Uniphase','JDSU'],
['Juniper Networks','JNPR'],
['Juniper Networks','JNPR'],
['Keane Inc.','KEA'],
['Keane.','KEA'],
['LSI Logic','AGR'],
['LSI Logic','AGR'],
['Micron Technology','MU'],
['Micron Technology','MU'],
['Microsoft Corp.','MSFT'],
['Microsoft','MSFT'],
['Motorola Corp.','MOT'],
['Motorola','MOT'],
['NCR Corp.','NCR'],
['NCR','NCR'],
['NetManage Inc.','NETM'],
['NetManage','NETM'],
['Network Appliance','NTAP'],
['Nokia Inc.','NOK'],
['Nokia','NOK'],
['Nortel Networks','NT'],
['Nortel','NT'],
['Novell Inc.','NOVL'],
['Novell','NOVL'],
['Novellus Systems','NVLS'],
['Novellus','NVLS'],
['NVIDIA Corp.','NVDA'],
['NVIDIA','NVDA'],
['Office Depot','ODP'],
['Office Depot','ODP'],
['OfficeMax Inc.','OMX'],
['OfficeMax','OMX'],
['Oracle Corp.','ORCL'],
['Oracle','ORCL'],
['Paychex Inc.','PAYX'],
['Paychex','PAYX'],
['Priceline','PCLN'],
['Priceline.com','PCLN'],
['Pricelinecom Inc.','PCLN'],
['Pricelinecom','PCLN'],
['Qwest Communications Int.','Q'],
['Qwest Communications','Q'],
['Qwest','Q'],
['RadioShack Corp.','RSH'],
['RadioShack','RSH'],
['Real Networks Inc.','RNWK'],
['Real Networks','RNWK'],
['Research In Motion Ltd.','RIMM'],
['Research In Motion','RIMM'],
['RIM','RIMM'],
['Sabre Holding Corp.','TSG'],
['Sabre Holding','TSG'],
['Sabre Holdings','TSG'],
['SanDisk Corporation','SNDK'],
['SanDisk','SNDK'],
['Sanmina-SCI Corp.','SANM'],
['Sanmina-SCI','SANM'],
['SAP','SAP'],
['SAP','SAP'],
['Solectron','SLR'],
['Solectron','SLR'],
['Sprint Nextel','S'],
['Sprint','S'],
['Sun Microsystems','JAVA'],
['Sun Microsystems','JAVA'],
['Symantec Corp.','SYMC'],
['Symantec','SYMC'],
['Tellabs Inc.','TLAB'],
['Tellabs','TLAB'],
['Texas Instruments','TXN'],
['TI','TXN'],
['Time Warner Inc.','TWX'],
['Time Warner','TWX'],
['Unisys Corp.','UIS'],
['Unisys','UIS'],
['Verisign Inc.','VRSN'],
['Verisign','VRSN'],
['Verizon Communications','VZ'],
['Verizon','VZ'],
['Viacom Inc.','VIAB'],
['Viacom','VIAB'],
['Vodafone Group Inc.','VOD'],
['Vodafone','VOD'],
['Xerox Corp.','XRX'],
['Xerox','XRX'],
['Yahoo Inc.','YHOO'],
['Yahoo','YHOO']];
 
var exchange = [['COMS','NSDQ'],
['MMM','NYSE'],
['ADBE','NSDQ'],
['AMD','NYSE'],
['ACS','NYSE'],
['A','NYSE'],
['ALU','NYSE'],
['AT','NYSE'],
['AMZN','NSDQ'],
['AMD','NYSE'],
['APCC','NSDQ'],
['ADI','NYSE'],
['AAPL','NSDQ'],
['AMAT','NSDQ'],
['T','NYSE'],
['ADSK','NSDQ'],
['ADP','NYSE'],
['AV','NYSE'],
['BBY','NYSE'],
['BMC','NYSE'],
['BRCM','NSDQ'],
['BVSN','OTCBB'],
['CA','NYSE'],
['CAJ','NYSE'],
['CHKP','NSDQ'],
['CIEN','NSDQ'],
['CC','NYSE'],
['CSCO','NSDQ'],
['CTXS','NSDQ'],
['CNET','NSDQ'],
['CMCSA','NSDQ'],
['CSC','NYSE'],
['CPWR','NSDQ'],
['GLW','NYSE'],
['DELL','NSDQ'],
['ELNK','NSDQ'],
['EK','NYSE'],
['EBAY','NSDQ'],
['ERTS','NSDQ'],
['EDS','NYSE'],
['EMC','NYSE'],
['EXPE','NSDQ'],
['FDX','NYSE'],
['GTW','NYSE'],
['GOOG','NSDQ'],
['HP','NYSE'],
['IBM','NYSE'],
['INTC','NSDQ'],
['INTU','NSDQ'],
['IOM','NYSE'],
['JBL','NYSE'],
['JDSU','NSDQ'],
['JNPR','NSDQ'],
['KEA','NYSE'],
['MU','NYSE'],
['MSFT','NSDQ'],
['MOT','NYSE'],
['NCR','NYSE'],
['NETM','NSDQ'],
['NTAP','NSDQ'],
['NOK','NYSE'],
['NT','NYSE'],
['NOVL','NSDQ'],
['NVLS','NSDQ'],
['NVDA','NSDQ'],
['ODP','NYSE'],
['OMX','NYSE'],
['ORCL','NSDQ'],
['PAYX','NSDQ'],
['PCLN','NSDQ'],
['Q','NYSE'],
['RSH','NYSE'],
['RNWK','NSDQ'],
['RIMM','NSDQ'],
['SNDK','NSDQ'],
['SANM','NSDQ'],
['SAP','NYSE'],
['SLR','NYSE'],
['S','NYSE'],
['JAVA','NSDQ'],
['SYMC','NSDQ'],
['TLAB','NSDQ'],
['TXN','NYSE'],
['TWX','NYSE'],
['UIS','NYSE'],
['VRSN','NSDQ'],
['VZ','NYSE'],
['VIA-B','NYSE'],
['VOD','NYSE'],
['XRX','NYSE'],
['YHOO','NSDQ']];

    if (q && (Hilite.elementid && (e = document.getElementById(Hilite.elementid))))
    {
	Hilite.hiliteElement(e, q, exchange);
    }
};

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
            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();
        };
    }
}

