//
// Symbol/Site search Autocomplete
//
// CHECKED IN in SVN  svn://clientcvs:33000/svn41/blp2/trunk/public/javascripts/symautocomplete.js
//

// =========================================================
var symac_enable_new_site_search = true;

var symac_disable_gsa_search = BLOOMBERG && BLOOMBERG.global_var && BLOOMBERG.global_var.disable_gsa_search;

var symac_getSuggestionsUrl = (BLOOMBERG && BLOOMBERG.dev) ? "/search_assist/" : "/apps/data?pid=symautocomplete&Query=";

/* latest keyword from user input */
var symac_inputKeyword = "";

/* the keyword for which an HTTP request has been initiated */
var symac_sentKeyword = "";

/* query matching currently displayed results */
var symac_resultKeyword = "";

/* number of suggestions received as results for the keyword */
var symac_totalpositions = 0;

/* the maximum number of characters to be displayed for a suggestion */
var symac_suggestionMaxLength = 200;

/* the identifier used to cancel the evaluation with the clearTimeout method. */
var symac_delaySendTimer = null;

/* the currently selected suggestion (by arrow keys or mouse)*/
var symac_position = -1;

/* cache object containing the retrieved suggestions for different keywords */
var symac_oCache = new Object();
var symac_cachesize = 100;

/* the XMLHttp object for communicating with the server */
var symac_httpRequestor = createAJAXRequestor();

/* time to wait (in msecs ), before trying again if XMLHttpRequest is busy, set this to a number equal to average server response time */
var symac_delaySendMsec = 100;

/* default text */
var symac_defaultText = 'Search News, Quotes and Opinion';

var symac_skipSendCount = 0;  // count of skips to let prev http request finish
var symac_skipSendMax = 5;    // max skips/keystrokes to let prev request finish

var newsSearchURL = "http://search.bloomberg.com/search?site=wnews&client=wnews&output=xml_no_dtd&ie=UTF-8&oe=UTF-8&filter=p&getfields=wnnis&sort=date:D:S:d1&lr=-lang_ja&proxystylesheet=wnews&partialfields=-wnnis:NOAVSYND&q=";
var search_url_prefix = "http://search.bloomberg.com/search?";
var new_newsSearchURL = "http://search1.bloomberg.com/search/?content_type=all&page=1&q=";
var sitemapSearchURL = "http://search1.bloomberg.com/search?content_type=site_page&q=";
// =========================================================

function symac_handleFocus()
{
    var oKeyword = document.getElementById( "symac_keyword" );
    oKeyword.value = "";
    oKeyword.className = "symac_normalText";

    symac_inputKeyword = "";
    symac_resultKeyword = "";

    symac_position = -1;
    // fire tracking event
    BLOOMBERG.tracker.SearchAssist.trackEvent('Focus on search box', '');
}

// =========================================================

function symac_setPrompt()
{
    var oKeyword = document.getElementById( "symac_keyword" );
    oKeyword.value = symac_defaultText;
    oKeyword.className = "symac_grayText";
}

// =========================================================

// add delay to let event bubble down first
function symac_delayhandleLoseFocus( e )
{
    symac_setPrompt();
    setTimeout( "symac_hideSuggestions()", 500 );
}

// =========================================================

/* function that adds to a keyword an array of values */
function symac_addToCache( keyword, value )
{
    // clear cache if too big
    var num = 0;
    for (  var key in symac_oCache )
        num++;
    if( num >= symac_cachesize )
        symac_oCache = new Object();

    symac_oCache[ keyword ] = value;

}

// =========================================================

/** Look for results to match up with the input query. */
function symac_changeResults()
{
    // check if displayed results already match the input query
    if( symac_resultKeyword == symac_inputKeyword )
        return;

    // check if empty
    if( symac_inputKeyword == "" )
    {
        symac_hideSuggestions();
        symac_resultKeyword = symac_inputKeyword;
        return;
    }

    // check if in cache
    var tableData = symac_oCache[ symac_inputKeyword ];
    if( tableData )
    {
        symac_displayResults( tableData );
        symac_resultKeyword = symac_inputKeyword;
        return;
    }

    // delay send request to skip fast user keystrokes and reduce http requests
    if( symac_delaySendTimer != null )
        clearTimeout( symac_delaySendTimer );

    // try again
    symac_delaySendTimer = setTimeout( "symac_sendRequest()", symac_delaySendMsec );
}

// =========================================================

/** Send http request. */
function symac_sendRequest()
{
    // clear the timer
    symac_delaySendTimer = null;

    // check if empty query
    if( symac_inputKeyword == "" )
        return;

    // detect if a previous http request is in progress
    // and do nothing to let it finish and save valuable response in the cache;
    // this will reduce (cancelled) http requests;
    // limit the number of skips by a counter to cancel hanging http request
    if ( symac_skipSendCount++ < symac_skipSendMax  &&
            symac_httpRequestor &&
            ( symac_httpRequestor.readyState > 0  &&
                    symac_httpRequestor.readyState < 4 )
            )
        return;

    // actual send http request asyncronously
    symac_skipSendCount = 0;
    symac_sentKeyword = symac_inputKeyword;
    symac_directRequest( symac_sentKeyword );
}

function symac_directRequest( symac_sentKeyword )
{
    if ( window.bbabsurls )
    {
        // use proxy iframe to send ajax requests to different domain
        document.domain = "bloomberg.com";
        document.getElementById( 'symac_ajaxRequestorFrame' ).
                contentWindow.symacproxy_sendRequest( symac_sentKeyword );
    }
    else
    {
        sendAJAXRequest( symac_httpRequestor, "GET",
                symac_getSuggestionsUrl + encodeURIComponent( symac_sentKeyword ) , null,
                function() { passAJAXResponse( symac_httpRequestor,
                        symac_gotResponse ) } );
    }
}

// =========================================================

/** Handle http response. */
function symac_gotResponse( response )
{
    // server error?
    if( response.indexOf( "symac_suggestTable" ) > 0  ||
            response.indexOf( "noresults" ) > 0 )
        symac_addToCache( symac_sentKeyword, response );

    // check to match up results to input query;
    // if not in cache, might recur into another delayed send http request
    symac_changeResults();
}

// =========================================================

/* populates the list with the current suggestions */
function symac_displayResults( tableData )
{
    var oSuggest = document.getElementById( "symac_suggest" );
    oSuggest.innerHTML = tableData;
    oSuggest.style.visibility = "visible";
    // unbind the onclick event on News bar a tag, and replace it with new function
    var a_ele = $("#symac_suggestTable a[href^=" + search_url_prefix + "]");
    if (a_ele.length > 0){
        a_ele[0].onclick = null;
        a_ele.click(function(evt){
            evt.preventDefault();
        });
        // unbind the onclick event on tr, and replace it with new function
        var tr_ele = a_ele.closest('tr');
        if (tr_ele.length > 0){
            tr_ele[0].onclick = null;
            tr_ele.click(function(){
                var tmp_href = a_ele.attr('href');
                symac_navigate_url(tmp_href);
            });
        }
    }
    // unbind the onclick event on SITE PAGES a tag, and replace it with new function
    // the 1st one is the TOPICS bar
    var site_pages_a = $("#symac_suggestTable .symac_topics a");
    if (site_pages_a.length > 0){
        site_pages_a[0].onclick = null;
        site_pages_a.slice(0,1).click(function(evt){
            evt.preventDefault();
        });
        // unbind the onclick event on tr, and replace it with new function
        var site_pages_tr = site_pages_a.closest('tr');
        if (site_pages_tr.length > 0){
            site_pages_tr[0].onclick = null;
            site_pages_tr.slice(0,1).click(function(){
                var site_pages_href = site_pages_a.attr('href');
                var target_url = get_sitemap_url(site_pages_a[0], site_pages_href);
                symac_navigate_url(target_url);
            });
        }
    }

    var search_url = symac_enable_new_site_search ? new_newsSearchURL : newsSearchURL;
    var keyword = document.getElementById("symac_keyword").value;
    search_url = search_url + keyword;

    var suggestTable = document.getElementById( "symac_suggestTable" );
    if( suggestTable )
    {
        //remove all news search result and append predefined one if disable_gsa_search setting is on
        if (symac_disable_gsa_search){
            $("#symac_suggestTable tr.symac_news").remove();
            var cur_index = suggestTable.rows.length;
            var news_bar = "<tr onmouseover=\"symac_handleOnMouseOver(this);\" onclick=\"location.href=document.getElementById( 'symac_a"+cur_index+"' ).href;\" id=\"symac_tr"+cur_index+"\" class=\"symac_news symac_separatorRow\"><td align=\"left\" colspan=\"2\" class=\"col1\"><a onclick=\"return false;\" href=\""+search_url+"\" id=\"symac_a"+cur_index+"\"><img width=\"8\" height=\"8\" border=\"0\" src=\"http://cdn.images.bloomberg.com/r06/homepage/arrow-green-blue.gif\" alt=\"\">  News </a></td></tr>";
            $("#symac_suggestTable tbody").append(news_bar);
            cur_index += 1;
            var search_item = "<tr onmouseover=\"symac_handleOnMouseOver(this);\" onclick=\"location.href=document.getElementById( 'symac_a"+cur_index+"' ).href;\" id=\"symac_tr"+cur_index+"\" class=\"symac_news odd symac_resultRow\"><td align=\"left\" colspan=\"2\" class=\"col1\"><a onclick=\"return false;\" href=\""+search_url+"\" id=\"symac_a"+cur_index+"\">Search news</a></td></tr>";
            $("#symac_suggestTable tbody").append(search_item);
        }
        symac_totalpositions = suggestTable.rows.length;
        symac_position = document.getElementById( "symac_hltposition" ).value;
        symac_highlightKeyword( symac_position );
        // register dropdown table row event
        BLOOMBERG.tracker.SearchAssist.registerRowEvent(suggestTable);
    }
    else
    {
        symac_totalpositions = 0;
        symac_position = -1;
    }

    $("#symac_suggest #noresults").remove();
    var wrapper = $("#symac_suggest");
    if (wrapper.length > 0){
        wrapper.append('<div id="sym_see_all"><a id="sym_see_all_anchor" href="'+search_url+'">See all search results</a></div>');
    }
}
// the source should be a dom object, not a jquery set
function get_sitemap_url(source, url){
    var ret = url;
    var sitemap_bar = $("#symac_suggestTable .symac_topics a");
    var keywords = symac_inputKeyword;
    if (symac_enable_new_site_search && sitemap_bar.length > 0 && sitemap_bar[0] == source && keywords.length > 0){
        ret = sitemapSearchURL + encodeURIComponent(keywords);
    }
    return ret;
}
// =========================================================

/* function that handles the keys that are pressed */
function symac_handleKeyUp(e) {
    // get the event
    e = ( !e ) ? window.event : e;

    // get the event's target
    target = ( !e.target ) ? e.srcElement : e.target;

    if (target.nodeType == 3)
        target = target.parentNode;

    // get the character code of the pressed button
    code = (e.charCode) ? e.charCode :
            ((e.keyCode) ? e.keyCode :
                    ((e.which) ? e.which : 0));
    // use keydown event to capture Enter event to prevent facebook login dialog from being popping up for IE users
    if (e.type == "keydown"){
        if (code == 13) {
            // save the keyword to use for newsSearchURL
            var keyword = document.getElementById("symac_keyword").value;

            // force loose focus from the input field as if on-click
            symac_delayhandleLoseFocus();
            document.getElementById("symac_keyword").blur();

            // check to see if any function is currently selected
            if (symac_position >= 0) {
                // fire tracking event
                BLOOMBERG.tracker.SearchAssist.triggerRowEvent(document.getElementById("symac_tr" + symac_position));
                var source_ele = document.getElementById("symac_a" + symac_position);
                var source_url = source_ele.href;
                var target_url = get_sitemap_url(source_ele, source_url);
                symac_navigate_url(target_url);
            }
            else if (symac_trim(keyword) != "") {
                // fire tracking event
                BLOOMBERG.tracker.SearchAssist.trackEvent('Search', keyword);
                symac_perform_site_search(keyword);
            }
            
            try {
                window.event.cancelBubble = true;
                event.returnValue = false;
            } catch(e) { }
        }
    }
    // check to see if the event was keyup
    if (e.type == "keyup") {
        /* if enter is pressed */
        if (code == 13) {
            //do nothing, it's already handled in "keydown" event
        }
        else
        // if the down arrow is pressed we go to the next suggestion
        if (code == 40) {
            oldTR = document.getElementById("symac_tr" + symac_position++);

            if (symac_position == symac_totalpositions) {
                symac_position = 0;
            }
            newTR = document.getElementById("symac_tr" + symac_position);

            // deselect the old selected suggestion
            symac_highlightRow(oldTR, false);

            // select the new suggestion
            symac_highlightRow(newTR, true);
        }
        else
        // if the up arrow is pressed we go to the previous suggestion
        if (code == 38) {
            oldTR = document.getElementById("symac_tr" + symac_position--);

            if (symac_position == -1) {
                symac_position = symac_totalpositions - 1;
            }
            newTR = document.getElementById("symac_tr" + symac_position);

            // deselect the old selected symac_position
            symac_highlightRow(oldTR, false);

            // select the new suggestion
            symac_highlightRow(newTR, true);
        }
        else {
            // get input query and normalize space/uppercase
            // will ignore such edits
            var keyword = document.getElementById("symac_keyword").value;
            keyword = symac_normalizeKeyword(keyword);
            if (keyword == symac_inputKeyword)
                return;

            // clear the selection until the new result is displayed
            symac_deselectAll();
            symac_position = -1;
            // handle query on-change
            symac_inputKeyword = keyword;
            symac_changeResults();
        }
    }
}

// =========================================================

// new functions for Lingospot site search
function symac_perform_site_search(keyword){
    if (keyword && keyword.length > 0){
        var search_url = symac_enable_new_site_search ? new_newsSearchURL : newsSearchURL;
        window.location.href = search_url + encodeURIComponent( keyword );
    }    
}

function symac_get_keyword_from_url(url){
    var matches = url.match('[?&]q=([^&$]*)');
    var tmp_keyword = '';
    if (matches){
        // need to decode the keyword, because it's already encoded once in the url
        tmp_keyword = decodeURIComponent(matches[1]);
    }
    return tmp_keyword;
}

function symac_navigate_url(url){
    if (url.indexOf(search_url_prefix) == 0){
        var tmp_keyword = symac_get_keyword_from_url(url);
        symac_perform_site_search(tmp_keyword);
    }else{
        window.location.href = url;
    }
}

/* function that removes the style from all suggestions*/
function symac_deselectAll()
{
    // there is an extra news item
    for( var i = 0; i < symac_totalpositions; i++ )
    {
        var oCrtTr = document.getElementById( "symac_tr" + i );
        symac_highlightRow( oCrtTr, false );
    }
}

// =========================================================

/* function that handles the mouse entering over a suggestion's area 
 event */
function symac_handleOnMouseOver( oTr )
{
    symac_deselectAll();
    symac_highlightRow( oTr, true );
    symac_position = oTr.id.substring( 8, oTr.id.length );
}

// =========================================================

/* function that hides the layer containing the suggestions */
function symac_hideSuggestions()
{
    var oSuggest = document.getElementById( "symac_suggest" );
    oSuggest.style.visibility = "hidden";
}

// =========================================================

/* highlight default selection */
function symac_highlightKeyword( rownum )
{
    // deselect all suggestions
    symac_deselectAll();

    //set the default symac_position
    symac_position = rownum;

    // highlight the selected suggestion
    var hltrow = document.getElementById( "symac_tr" + rownum );
    symac_highlightRow( hltrow , true );
}

// =============================================

function symac_highlightRow( row, doHlt )
{
    var hltidx = row.className.indexOf( "_highlight" );

    if( doHlt  &&  hltidx < 0 )
        row.className = row.className +  "_highlight";
    else if ( !doHlt  &&  hltidx > 0 )
        row.className = row.className.substring( 0, hltidx );
}

// =============================================

function symac_normalizeKeyword( str )
{
    // trim spaces if any
    str = str.replace( / +/g, " " );
    str = str.replace( /^ +/, "" );
    str = str.replace( / +$/, "" );

    // commented out as per portfolio tracker item 3043355
    //str = str.toUpperCase();  // convert to upper case

    return str;

}

// =============================================

function symac_trim( str )
{
    str = str.replace(/^\s+|\s+$/g,"");
    return str;
}

