﻿function checkHeaderKey(e, hsbox, type) {
    if (e.keyCode == 13) {
        return callHeaderSearch(hsbox, type);
    }
    return true;
}

function callHeaderSearch(sbox, type) {
    if (sbox.value == "Search this Site") {
        sbox.value = "";
    }

    var url = "/USGASearch.aspx?q=" + sbox.value;
    if (type != undefined && type != "All Topics" && type != "Spotlight") {
        url += "&f=" + encodeURIComponent("type:" + type);
    }

    window.location = url;
    return false;
}

function clearSearchText(el) {
    if (el.defaultValue == el.value) el.value = "";
}

// Begin lookahead
lookaheadParams = {
    workflows: "autocomplete",
    highlight: "true",
    fields: "title,text,uri,source,type,img,thumb",
    "q.type": "advanced",
    "join.rollup": "children",
    "l.synonyms.mode": "on",
    "q.filter": "AND(NOT(ISNULL(type)),NOT(ISNULL(uri)),NOT(ISNULL(source)))",
    "q.filter.type": "advanced",
    hits: 5,
    output: "full",
    facet: "concepts(maxnumbuckets=1)"
};

//function renderMedia(media) {
//    full_img = String(media.thumb).replace('/s/', '/l/');
//    html = '<div class="lookahead_result_img_wrap"><img src="' + media.thumb + '" alt="photo" border="0" class="lookahead_result_img lookahead_result_media" onclick="window.location = \'' + media.uri + '\'; return true;"/></div>';
//    html += '<div class="tooltip"><div class="tooltip_content"><img src="' + full_img + '" onclick="window.location = \'' + media.uri + '\'; return true;" alt="photo" border="0" class="lookahead_tooltip_img"/></div></div>';
//    return html;
//};

function renderMedia(media) {
    html = '<div class="lookahead_result_img_wrap"><img src="' + media.thumb + '" alt="photo" border="0" class="lookahead_result_img lookahead_result_media" onclick="window.location = \'' + media.uri + '\'; return true;"/></div>';
    html += '<div class="tooltip"><div class="tooltip_content"><img src="' + media.img + '" style="height: 187px; width:281px;" onclick="window.location = \'' + media.uri + '\'; return true;" alt="photo" border="0" class="lookahead_tooltip_img"/></div></div>';
    return html;
};


var didYouMeanType = "did_you_mean";
var typeOrderMap = {
    'Spotlight': 1,
    'News & Information': 2,
    'Photos & Videos': 3,
    'Rules of Golf': 4,
    'Courses': 5,
    'Store': 6
};
typeOrderMap[didYouMeanType] = 0;

function handleLookaheadResponse(data, queryTerm, responseCallback) {
    // handle "did you mean" results
    var i = 0;
    // make sure the query term is at least 3 characters long or the results won't be useful
    if (queryTerm != undefined && queryTerm.length > 2 && data.facets.length > 0 && data.facets[0].buckets.length > 0) {
        var label = data.facets[0].buckets[0].label;

        // if the suggestion is the same as the query term, 
        // or suggestion doesn't start with query term, ignore it 
        if (label.toLowerCase() == queryTerm.toLowerCase() || 
            label.toLowerCase().indexOf(queryTerm.toLowerCase()) != 0) { 
           label = ''; 
        }

        if (label != '') {
            var obj = new Object;
            obj.type = didYouMeanType;
            obj.label = suggestResult([label]);

            // add in the did you mean item and ensure we don't process it in the loop below
            data.documents.unshift(obj);
            i++;
        }
    }
    
    if (data.feedback) {
        $.each(data.feedback, function() {
            if (this.name == "cs.feedback" && this.message == "RESPONSE") {
                var props = this.properties;
                if (props["cs.feedback.response.type"] == "link") {
                    var spotlightItem = new Object();
                    spotlightItem.uri = props.url;
                    spotlightItem.title = props.title;
                    spotlightItem.text = props.content;
                    spotlightItem.type = "Spotlight";
                    data.documents.push(spotlightItem);
                }
            }
        });
    }
    
    for (; i < data.documents.length; i++) {
        data.documents[i].label = '';
        if (data.documents[i].img != undefined) {
            data.documents[i].label += renderMedia(data.documents[i]);
        }
        data.documents[i].label += '<div><div class="lookahead_result_title">' + data.documents[i].title + '</div>';
        if (data.documents[i].text != undefined) {
            content_text = data.documents[i].text
        } else {
            content_text = ''
        }
        data.documents[i].label += '<div class="lookahead_result_content">' + content_text + '</div><div style="clear:both;"></div></div>';
        data.documents[i].value = data.documents[i].uri;
    }

    responseCallback(data.documents);
}

function gotoResults(keyword, type) {

    // add event tracking for category
    

    window.location = '/USGASearch.aspx?q=' + encodeURIComponent(keyword) + (type == undefined || type == 'Spotlight' ? '' : ('&f=' + encodeURIComponent('type:' + type)));
    return true;
}

function gotoRulesOfGolfResults(keyword, type) {
    return '/USGASearch.aspx?q=' + encodeURIComponent(keyword) + (type == undefined || type == "Spotlight" ? '' : ('&f=' + encodeURIComponent('type:' + type)));
}


function suggestResult(keywords) {

    html = '<li class="ui-menu-item-suggest"><div class="did_you_mean_right"><span onclick="return gotoResults($j(\'#header_search_input\').val());">See All</span></div><span class="lookahead_result_title">DID YOU MEAN: </span>';
    for (var i = 0, len = keywords.length; i < len; ++i) {
        html += '<span class="did_you_mean" onclick="return gotoResults(\'' + keywords[i] + '\');">' + keywords[i] + '</span>';
        if (i + 1 != len) {
            html += ', ';
        } else {
            html += '?';
        }
    }
    html += '</li>';
    return html;
}

// See note in _init function below
var shouldHandleClickOnScroll = $j.browser.msie && ((document.documentMode && document.documentMode <= 7) || (document.compatMode && document.compatMode <= 7));
var clickOnScroll = false;

$j.widget("custom.groupedcomplete", $j.ui.autocomplete, {
    mediaTypes: ["Photos & Videos"],

    _init: function() {
        // IE7 and below (and IE8 in IE7 standards mode) generates a blur even when clicking on the scrollbar.  to prevent that from closing the
        // lookahead, we need to determine if the user clicked on the scrollbar (the target of the mousedown event will be on the HTML node)
        // and then indicate to the blur handler that it should ignore the subsequent event it receives.  the mousedown event handler is added
        // and removed below when the autocomplete is opened and closed respectively.
        var self = this;

        // override the existing blur handler.  this is a modified copy of the default autocomplete blur handler
        this.element.unbind("blur.autocomplete");
        this.element.bind("blur.autocomplete", function(event) {
            //
            callback = function(event) {
                if (self.options.disabled) {
                    return;
                }

                // ignore the blur as the user clicked on the scrollbar
                if (clickOnScroll) {
                    clickOnScroll = false;

                    // ensure the element gets focus again since it shouldn't have lost it in the first place.  IE will scroll to the element
                    // receiving the focus.  so, we need to preserve the prior scroll coordinates and reset them after giving focus to the element.
                    var w = $j(window);
                    var scrollLeft = w.scrollLeft();
                    var scrollTop = w.scrollTop();
                    setTimeout(function() {
                        self.element.focus();
                        w.scrollLeft(scrollLeft);
                        w.scrollTop(scrollTop);
                    });

                    return;
                }

                clearTimeout(self.searching);
                // clicks on the menu (or a button to trigger a search) will cause a blur event
                self.closing = setTimeout(function() {
                    self.close(event);
                    self._change(event);
                }, 100);
            };

            // if we have to handle clicks on the scrollbar ourselves, then delay the execution of the callback to give the mousedown handler
            // time to receive the event
            if (shouldHandleClickOnScroll) {
                setTimeout(function() {
                    callback(event);
                }, 150);
            } else {
                callback(event);
            }
        });

        // unbind the default handler and bind one with our tweaks for the enter key
        this.element.unbind("keydown.autocomplete");
        this.element.bind("keydown.autocomplete", function(event) {
            var keyCode = $j.ui.keyCode;
            switch (event.keyCode) {
                case keyCode.PAGE_UP:
                    self._move("previousPage", event);
                    break;
                case keyCode.PAGE_DOWN:
                    self._move("nextPage", event);
                    break;
                case keyCode.UP:
                    self._move("previous", event);
                    // prevent moving cursor to beginning of text field in some browsers
                    event.preventDefault();
                    break;
                case keyCode.DOWN:
                    self._move("next", event);
                    // prevent moving cursor to end of text field in some browsers
                    event.preventDefault();
                    break;
                case keyCode.ENTER:
                case keyCode.NUMPAD_ENTER:
                    // when menu is open or has focus
                    if (self.menu.active) {
                        event.preventDefault();
                    } else {
                        callHeaderSearch($j("#header_search_input")[0]);
                        event.preventDefault();
                        break;
                    }
                    //passthrough - ENTER and TAB both select the current element
                case keyCode.TAB:
                    if (!self.menu.active) {
                        return;
                    }
                    self.menu.select(event);
                    break;
                case keyCode.ESCAPE:
                    self.element.val(self.term);
                    self.close(event);
                    break;
                default:
                    // keypress is triggered before the input value is changed
                    clearTimeout(self.searching);
                    self.searching = setTimeout(function() {
                        // only search if the value has changed
                        if (self.term != self.element.val()) {
                            self.selectedItem = null;
                            self.search(null, event);
                        }
                    }, self.options.delay);
                    break;
            }
        });
    },

    _renderMenu: function(ul, items) {
        var self = this;

        // preserve the relative ordering, but group the results by type
        var typeArray = [];
        var types = {};
        var media = {};
        var numRows = 0;
        for (var i = 0; i < items.length; i++) {
            var type = items[i].type.toString();

            // handle did you mean
            if (type == didYouMeanType) {
                typeArray.push(didYouMeanType);
                types[didYouMeanType] = [items[i]];
                continue;
            }

            var typeList = types[type];
            if (typeList == undefined) {
                typeList = [];
                types[type] = typeList;
                typeArray.push(type);
            }

            // return a max of 3 results per type unless this is media in which case we'll return 5
            // per type
            if ($j.inArray(type, self.mediaTypes) != -1) {
                // if this is the first item of this media type, add it to the type list and reconfigure
                // the label for the horizontal media layout
                items[i].isMedia = true;
                if (typeList.length == 0) {
                    typeList.push(items[i]);
                    numRows++;
                    items[i].label = '';
                    items[i].mediaCount = 0;
                }

                if (++typeList[0].mediaCount <= 5) {
                    typeList[0].label += renderMedia(items[i]);
                }
            } else if (typeList.length < 3) {
                typeList.push(items[i]);
                numRows++;
            }
        }

        // if we have more than 6 rows, take items off of each non-media type until we're down to 6 results
        var maxRows = 6;
        while (numRows > maxRows) {
            for (i = typeArray.length - 1; numRows > maxRows && i >= 0; i--) {
                typeList = types[typeArray[i]];
                // keep at least 1 result in each.  this will automatically handle the media types
                if (typeList.length > 1) {
                    typeList.pop();
                    numRows--;
                }
            }
        }

        // put the types in a predetermined order
        typeArray.sort(function(a, b) {
            var idx1 = a in typeOrderMap ? typeOrderMap[a] : Number.MAX_VALUE;
            var idx2 = b in typeOrderMap ? typeOrderMap[b] : Number.MAX_VALUE;
            return idx1 - idx2;
        });

        i = 0;
        keyword = $j('#header_search_input').val();
        for (i = 0; i < typeArray.length; i++) {
            type = typeArray[i];
            typeList = types[type];

            // handle did you mean
            if (type == didYouMeanType) {
                ul.append(typeList[0].label);
                continue;
            }

            // google tracking clicks here
            ul.append("<li class='lookahead_type_group lookahead_heading' onclick='lookaheadItemClick(\"" + type + "\"); return gotoResults(\"" + keyword + "\", \"" + type + "\");'><div class='left'>" + type + "</div><div class='seeall right'>See All Results</div></li>");
            for (var j in typeList) {
                if (typeList[j].isMedia != undefined && typeList[j].isMedia) {
                    typeList[j].label += '<div class="clear"></div>';
                }
                self._renderItem(ul, typeList[j]);
            }
        }
        //ul.append("<li class='lookahead_footer ui-corner-bottom'><div class='lookahead_heading' onclick='return gotoResults(\"" + keyword + "\");'>See All Results <img src='images/right-arrow.gif' alt='See All Results'/></div></li>");

        // google tracking all results clicks here
        ul.append("<li class='lookahead_footer ui-corner-bottom' style='padding: 0px 0px;'><img src='/images/see_all_results.png' style='height:26px; width:323px; padding:0px; padding-top:1px;' onclick='lookaheadAllResultsClick(\"" + keyword + "\"); return gotoResults(\"" + keyword + "\");' alt='See All Results' /></li>");
		
		// removing auto added by jquery class because we don't need border-radius on the top
		ul.removeClass("ui-corner-all");
		ul.addClass("ui-corner-bottom");
		
        // google tracking render of finished lookahead menu
        lookaheadRenderComplete();
        
    },

    // Somewhere in jquery ui 1.8.2-1.8.5, the inclusion of the label was wrapped in a call to text() which doesn't handle the HTML correctly.
    // We're overriding to include without escaping
    _renderItem: function(ul, item) {
        return $j("<li></li>")
			.data("item.autocomplete", item)
			.append("<a>" + item.label + "</a>")
			.appendTo(ul);
    },

    _positionAC: function(el, menuEl) {
        // workaround for FF bug
        var leftOffset = -7;
        var box = $j(el).offset();
        if (parseInt(box.left) != box.left) {
            leftOffset = -6;
        }

        $j(menuEl).show().position({
            my: "left top",
            at: "left bottom",
            of: this.element,
            offset: leftOffset + " 10",
            collision: "none"
        });
    },

    _suggest: function(items) {
        var ul = this.menu.element
                .empty()
                .zIndex(this.element.zIndex() - 1),
            menuWidth,
            textWidth;
        this._renderMenu(ul, items);
        // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
        this.menu.deactivate();
        this.menu.refresh();

		ul.css('position', 'absolute');
		
        this._positionAC(this.element, this.menu.element);

        menuWidth = ul.width("").width();
        textWidth = this.element.width();
        ul.width(Math.max(menuWidth, textWidth)); 

        // if the window is resized, ensure the autocomplete is positioned correctly
        var self = this;
        $j(window).bind('resize.autocomplete', function() {
            self._positionAC(self.element, self.menu.element);
        });
    }
});

function insertCarrot(trigger, tip) {
    var parent_padding = parseInt(trigger.parent().css('padding-left'));
    var x_pos = trigger.position().left + (trigger.width() / 2) - parent_padding;
    var y_pos = trigger.position().top + trigger.outerHeight() - 10;
    var carrot = $j('<div class="carrot"></div>');
    carrot.css({ position: 'absolute', top: y_pos, left: x_pos, zindex: 20001 });
    tip.before(carrot);
    carrot.css('z-index', 10001); //ie7 hack
}

function quoteQuery(query) {
    return query.replace("\\", "\\\\").replace("\"", "\\\"");
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// handle google analytics events
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

function lookaheadAllResultsClick(label) {
    //alert("_gaq.push(['_trackEvent', 'PredictiveSearchPageView', 'SeeAllResultsClick', \'" + label + "\']);");
    _gaq.push(['_trackEvent', 'PredictiveSearchPageView', 'SeeAllResultsClick', '\'' + label + '\'']);
}

function lookaheadItemClick(label) {
    //alert("_gaq.push(['_trackEvent', 'PredictiveSearchPageView', 'ItemClick', \'" + label + "\']);");
    _gaq.push(['_trackEvent', 'PredictiveSearchPageView', 'ItemClick', '\'' + label + '\'']);
}

function lookaheadRenderComplete() {
    //alert("_gaq.push(['_trackEvent', 'PredictiveSearchPageView', 'DisplayMenu']);");
    _gaq.push(['_trackEvent', 'PredictiveSearchPageView', 'DisplayMenu']);
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
// end google analytics events 
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~


$j(document).ready(function() {
    $j("#header_search_input").groupedcomplete({
        source: function(request, response) {
            json = $j.ajax({
                url: "/Json.aspx",
                data: $j.extend(lookaheadParams, { query: 'QUERY("' + quoteQuery(request.term) + '", qlang=simple, cs.enabled=true)', qlang: 'advanced', jsoncallback: '?' }),
                dataType: 'jsonp',
                //              username: 'attivio',
                //              password: 'u.s.open',
                success: function(data) {
                    handleLookaheadResponse(data, request.term, response);
                }
            });
        },

        open: function() {
            // set up the mousedown handler which looks for a click on the scrollbar. we do this when the lookahead is opened so that
            // we don't affect the performance of the site
            if (shouldHandleClickOnScroll) {
                $j(document).bind('mousedown.autocomplete_iescroll', function(event) {
                    if (event.target.nodeName.toLowerCase() == 'html') {
                        clickOnScroll = true;
                    }
                });
            }

            $j('.lookahead_result_img_wrap').each(function() {
                $j(this).tooltip({
                    position: 'bottom right',
                    predelay: 1000,
                    relative: true,
                    onShow: function() {
                        var trigger = this.getTrigger();
                        var tip = this.getTip();
                        insertCarrot(trigger, tip);
                        //var horizontal_adjustment = trigger.parent().position().left + ((trigger.parent().outerWidth() - tip.outerWidth()) / 2) - 2;
                        var horizontal_adjustment = 13;
                        var vertical_adjustment = trigger.position().top + trigger.outerHeight() + 1;
                        tip.css({ position: 'absolute', top: vertical_adjustment, left: horizontal_adjustment });
                    },
                    onHide: function() {
                        $j('.carrot').remove();
                    }

                });

            });
            $j('.lookahead_type_group').hover(
                function() {
                    $j('.seeall', this).fadeIn();
                },
                function() {
                    $j('.seeall', this).fadeOut();
                }
            );
            $j('#header_search_input_wrap').addClass('header_search_trigger');
        },

        focus: function(event, ui) {
            return false;
        },

        select: function(event, ui) {

            // since 'return false' sometimes results in blowing away the google 
            // analytics event queue before it can empty, try setting preventDefault() 
            // on the event instead
            var ev = event || window.event;
            ev.preventDefault();
        
            if (ui.item.isMedia == undefined || !ui.item.isMedia) {

                // google tracking for item click
                lookaheadItemClick(ui.item.type);

                // handle special Rules of Golf handling:
                if (ui.item.type == "Rules of Golf") {
                    window.location = gotoRulesOfGolfResults(window.keyword, "Rules of Golf");
                } else {
                    window.location = ui.item.uri;
                }
            }
            //return false;
        },

        close: function() {
            // stop tracking scrollbar clicks as the lookahead is closed
            if (shouldHandleClickOnScroll) {
                $j(document).unbind('mousedown.autocomplete_iescroll');
            }

            $j('#header_search_input_wrap').removeClass('header_search_trigger');

            // remove the window resize handler for autocomplete
            $j(window).unbind('resize.autocomplete');
        }
    });
});
