(function ($) {
    $.gsuggest = function (settings) {
        //Configuration settings for suggest(search)box
        $.gsuggest.config = {
            'debug': false,
            'url': '/suggest.cfc',
            'size':8,
            'cacheenabled': false,
            'cacheaggressive': false,
            'cachefoward': false, //true - complete cache dataset, false - incomplete cache datasets
            'casesensitive': false,
            'sort': false,
            'css0': { 'position': 'absolute', 'z-index': '1', 'display': 'none', 'font-size': '9pt' },
            'css': { 'position': 'absolute', 'background-color': '#ffffff', 'border': 'solid 1px #000000', 'border-bottom': '6px solid #003366', 'cursor': 'pointer', 'color': '#000000', 'padding': '0px', 'margin': '0px', 'left': '714px', 'top': '0px', 'overflow': 'hidden' }, 'highlight': '#bcd5ff', 'z-index': '2000'
        };



        if (settings) $.extend($.gsuggest.config, settings);

        var fillok = true;
        var cacheinit = true;

        var timerstart = null;
        var timerend = null;

        $.gsuggest.cachedata = [];
        $.gsuggest.cachekey = "";

        $.gsuggest.synctext = true;
        $.gsuggest.mouseoverok = false;
        $.gsuggest.mousepos = "";

        $.gsuggest.setcase =
    function (val) {
        if ($.gsuggest.config.casesensitive)
            return val;
        else
            return val.toLowerCase();
    };
        //suggestPos(maininput field that we type) upArrow,downArrow,tabFunctionality
        //checking the user input filed in the search text box.
        $.gsuggest.keydown =
    function (obj, e) {
        clearTimeout($.gsuggest.suggestDelay);
        if (e.which == 38 || e.which == 40) {
            $(obj).next().children("div:eq(" + $(obj).attr("suggestPos") + ")").blur();
            //       if (document.getElementById('_suggestBox') != null)
            //                var isSuggestBox = document.getElementById('_suggestBox').style.display;
            switch (e.which) {
                case 38: ///up

                    //if (isSuggestBox != "none")
                    //  {
                    if (parseInt($(obj).attr("suggestPos")) - 1 < -1)
                        $(obj).attr("suggestPos", $(obj).attr("suggestTtl"));
                    else
                        $(obj).attr("suggestPos", Math.max(-2, parseInt($(obj).attr("suggestPos")) - 1));
                    //}
                    break;

                case 40: //down
                    // if (isSuggestBox != "none") {
                    if (parseInt($(obj).attr("suggestPos")) + 1 > parseInt($(obj).attr("suggestTtl")))
                        $(obj).attr("suggestPos", "-1");
                    else
                        $(obj).attr("suggestPos", Math.min($(obj).attr("suggestTtl"), parseInt($(obj).attr("suggestPos")) + 1));
                    //}
                    break;
                case 9: //tab
                    if (parseInt($(obj).attr("suggestPos")) + 1 > parseInt($(obj).attr("suggestTtl")))
                        $(obj).attr("suggestPos", "-1");
                    else
                        $(obj).attr("suggestPos", Math.min($(obj).attr("suggestTtl"), parseInt($(obj).attr("suggestPos")) + 1));

                    break;
            }
            //Sync text is the text that we hover that shows up in the suggest text box
            $.gsuggest.synctext = true;
            $(obj).next().children("div:eq(" + $(obj).attr("suggestPos") + ")").focus();
        }
        //Enter Functionality in the else loop the first condition checks whether that if its the first character or not if its not the first character
        //it takes to the url aliased url otherewise in the else lopp it takes to the search page with the user inputed value
        else if (e.which == 13) {
            if ($(obj).attr("suggestPos") != -1) {
                if ($(obj).next().children("div:eq(" + $(obj).attr("suggestPos") + ")")[0].firstChild != null) {
                    var gotoURL = $(obj).next().children("div:eq(" + $(obj).attr("suggestPos") + ")")[0].firstChild.href;
                    window.location = gotoURL;
                    return false;
                }
            }
            else {
                window.location = "http://search.com/search?q=" + $('#field_id')[0].value + "&btnG=Search&entqr=0&output=xml_no_dtd&sort=date:D:L:d1&client=www_intertek&ud=1&y=12&oe=UTF-8&ie=UTF-8&proxystylesheet=www_intertek&x=30&site=www_";
                return false;
            }
        }
    };

        $.gsuggest.keyup =
    function (obj) {
        var objval = obj.value;

        //console.dir($.gsuggest.cachedata);
        if ($.gsuggest.config.debug) timerstart = new Date().getTime();

        if (objval == $(obj).attr("suggestLast")) return;

        if (objval.length == 0) {
            $(obj).attr("suggestLast", objval);
            $(obj).next().hide();
            return;
        }

        $(obj).attr("suggestLast", objval);

        var method = obj.form.name + '_' + obj.name;
        var surl = $.gsuggest.config.url + "?method=" + method + "&value=" + objval + "&callback=?"
        var data, datat;

        //fill() *must* be single threaded via fillok	       
        function fill(data) {
            while (!fillok) { };
            fillok = false;

            $(obj).next().empty();
            //$(obj).next().hide(); *we dont need to hide it unless the results are empty

            if ($.gsuggest.config.sort) data.sort();
    
            $(obj).attr("suggestTtl", Math.min($.gsuggest.config.size, data.length));
            for (i = 0; i < data.length; i++) {
                var modifyjsonstring = data[i];
                var modifyjsonURL = modifyjsonstring.split(",");

                //After receiving the json response building the results in the suggest box in the jsonn response we are receving the results in the ,
                //separated value so doing the string manipulation to break the string and build the anchor tag based on the result set.

                if (i == 0) {
                    if (data.length > 1) {
                        $(obj).next().append("<div class='autoSearch' style=\"padding: 3px; font-size: 11pt; border-bottom: 1px solid #CCC\"><a href='" + data[data.length - 1].substr(0, objval.length) + data[data.length - 1].substring(objval.length) + "' onclick='parent.location.href = this.href'><strong>See all results</strong></a> or Choose Below:</div>");
                    } else {
                        // $(obj).next().append("<h3 style=\"padding: 3px; font-size: 12pt; border-top: 1px solid #CCC; border-bottom: 1px solid #CCC; margin: 0; font-weight: 100; width: 260px;\">No suggested pages</h3>");

                    }
                }

                if (i < (data.length - 1)) {
                    $(obj).next().append("<div class=\"autoSearch\" style=\"padding: 4px 4px 4px 10px;\"><a href='" + modifyjsonURL[1] + "' onclick='parent.location.href = this.href'><strong>" + modifyjsonURL[0] + "</strong></a></div>");
                }
                else {
                    if (data.length > 1 ) {
                       // $(obj).next().append("<div style=\"padding: 3px; font-size: 11pt; border-top: 1px solid #CCC\"><a href='" + data[i].substr(0, objval.length) + data[i].substring(objval.length) + "' onclick='parent.location.href = this.href'><strong>View all results ...</strong></a></div>");
                    } else {
                        $(obj).next().append("<h3 style=\"padding: 3px; font-size: 10pt; margin: 0; font-weight: 100; width: 260px;\"><a href='" + data[i].substr(0, objval.length) + data[i].substring(objval.length) + "' onclick='parent.location.href = this.href'>No matching titles. <br />Click here to search all site content ...</a></h3>");
                    }


                }


                if (i == $.gsuggest.config.size) break;
            }

            if (i > 0 && !(data.length == 1 && $.gsuggest.setcase(data[0]) == $.gsuggest.setcase(objval))) {
                $(obj).attr("suggestPos", "-1");
                //$(obj).next().slideDown("fast");
                $.gsuggest.synctext = false;
                $.gsuggest.mouseoverok = false;
                $(obj).next().show();
            } else {
                $(obj).next().hide();
            }

            fillok = true;
        }

        //cache roll back -force cache forward if ttl suggest items less than max
        if (objval.indexOf($.gsuggest.cachekey) != 0 || (!$.gsuggest.config.cacheforward && !($(obj).attr("suggestTtl") < $.gsuggest.config.size))) {
            $.gsuggest.cachekey = $.gsuggest.setcase(objval);
        }
        //console.log("key: " + $.gsuggest.cachekey);
        if ($.gsuggest.cachedata[$(obj).attr("id") + $.gsuggest.cachekey] || ($(obj).attr("suggest_value") != null && $(obj).attr("suggest_value").length > 0)) {
            if (!$.gsuggest.cachedata[$(obj).attr("id") + $.gsuggest.cachekey] || !$.gsuggest.config.cacheenabled) {
                $.gsuggest.config.cacheforward = true;
                datat = eval($(obj).attr("suggest_value"));
                if ($.gsuggest.config.debug) $("#_debug").html("CACHE INIT<br>" + datat.join("<br>"));
            } else {
                datat = $.gsuggest.cachedata[$(obj).attr("id") + $.gsuggest.cachekey];
                if ($.gsuggest.config.debug) $("#_debug").html(datat.join("<br>"));
            }


            data = [];
            $.each(datat, function (i, val) {
                if ($.gsuggest.setcase(val).indexOf($.gsuggest.setcase(objval)) == 0) {
                    data.push(val);
                }
            })

            if ($.gsuggest.config.cacheenabled) { $.gsuggest.cachedata[$(obj).attr("id") + $.gsuggest.setcase(objval)] = data; $.gsuggest.cachekey = $.gsuggest.setcase(objval) }
            fill(data);
        } else {
            $.getJSON(surl, function (data) { if ($.gsuggest.config.cacheenabled) { $.gsuggest.cachedata[$(obj).attr("id") + $.gsuggest.setcase(objval)] = data; $.gsuggest.cachekey = $.gsuggest.setcase(objval); if ($.gsuggest.config.debug) $("#_debug").html("CACHE INIT<br>" + $.gsuggest.cachedata[$(obj).attr("id") + $.gsuggest.setcase(objval)].join("<br>")); } fill(data) });
        }

        if ($.gsuggest.config.debug) {
            timerend = new Date().getTime();
            $("#_debug_timer").html(timerend - timerstart);
        }

    };

        $("input[suggest=yes]").each(function (i) {
            if (this.id == null || this.id == '')
                $(this).attr("id", "_g§µggê§†_" + i)

            Init("#" + this.id)  
        }
    );

        function Init(id) {
            //this function is called on the page initialization and sets all the attributes and the functions for the text box.
            var suggest_id = "_suggestBox";
            var suggest_idChildren = "#" + suggest_id + " > *";
            //adding the attributes for the suggest key box

            $(id).attr("autocomplete", "off");
            $(id).keyup(function (e) { if (e.which == 27) { $(this).blur(); $(this).focus(); if (!$.gsuggest.config.cacheaggressive) { $.gsuggest.cachedata = []; $.gsuggest.cachekey = "" } } else if (e.which < 37 || e.which > 40) { $.gsuggest.suggestDelay = setTimeout("$.gsuggest.keyup(document.getElementById('" + $(this).attr("id") + "'))", (!!$.gsuggest.cachedata[$(this).attr("id") + $.gsuggest.cachekey]) ? 50 : (e.which == 13) ? 0 : 500); } });
            $(id).click(function () { $(this).blur(); $(this).focus() });
            $(id).blur(function () { $.gsuggest.mouseout = false; $(this).next().hide("slow"); $(this).attr("suggestPos", "-1"); });
            $(id).attr("suggestPos", "-1");
            $(id).keydown(function (e) { return $.gsuggest.keydown(this, e) });

            //set event handlers for suggest-box | no propgation
            $(suggest_idChildren).live("mouseover", function (e) { if (!$.gsuggest.mouseoverok) return false; $(this).parent().children("div:eq(" + $(this).parent().prev().attr("suggestPos") + ")").blur(); $(this).parent().prev().attr("suggestPos", $(this).prevAll().length); $(this).focus(); $.gsuggest.synctext = true; return false });
            $(suggest_idChildren).live("mouseout", function () { $(this).blur(); return false; });
            $(suggest_idChildren).live("focus", function () { $(this).css("background-color", $.gsuggest.config.highlight); if ($.gsuggest.synctext) { if ($(this).text() == "View all results ...") { } else { $(this).parent().prev().attr("value", $(this).text()) } }; return false; });
            $(suggest_idChildren).live("blur", function () { $(this).css("background-color", $(this).parent().css("background-color")); $(this).parent().prev().attr("value", $(this).parent().prev().attr("suggestLast")); return false; });
            $(suggest_idChildren).live("click", function () { $.gsuggest.synctext = true; return false; $(this).parent().prev().attr("suggestLast", $(this).text()); $(this).blur(); $(this).parent().prev().focus(); return false; });

            //create suggest-box, set width, and position
            $(id).after("<div id=\"" + suggest_id + "\" style=\"display:none\"></div>");
            $(id).next().css($.gsuggest.config.css0);
            $(id).next().css($.gsuggest.config.css);
            $(id).next().width($(id).width());
           // $(id).next().css("left", $(id).offset().left);
            $(id).next().css("top", $(id).offset().top + $(id).height() + 7);
        };
    };
})(jQuery);

jQuery(document).ready(function () {
    $().mousemove(function (e) {

        if ($.gsuggest.mousepos != e.pageX + '-' + e.pageY) {
            $.gsuggest.synctext = true;
            $.gsuggest.mouseoverok = true;
        }
        $.gsuggest.mousepos = e.pageX + '-' + e.pageY;
    });
})

//init
//jQuery(document).ready(function(){jQuery.gsuggest({'debug':true})});
//requires cache sets to be tied to attributes


/*
I have not decided if I want to add text-range support for autocomplete; my intent
was to memic the behavior of googles suggest and I feel that I have done this. However
I may decided to implement this as an optional setting in the future... */

