﻿//Original code inspiration: http://www.pengoworks.com/workshop/jquery/autocomplete.htm and http://dyve.net/jquery/?autocomplete
//I just added the "asp mvc and jquery-ui friendliness" to their original works
//Free to use how ever you want: http://docs.jquery.com/License
(function($) {
    jQuery.fn.autocomplete = function(url, accepted, noresults) {
        $.ajaxSetup({ cache: false });
        this.each(function() {
            var element = this;
            new jQuery.autocomplete(this, url, accepted, noresults);
        });

        // Don't break the chain
        return this;
    };
    jQuery.autocomplete = function(element, url, accepted, noresults) {
        var activeIndex = -1;
        var results = document.createElement("div");
        var $results = $(results);
        var currentId = '';

        // Add to body element
        $results.addClass('ui-corner-all');
        $results.css('position', 'absolute');
        $results.css({
                width: "0px",
                height: "330px",
                top: "0px",
                left: "0px"
            });

        $("body").append(results);

        $(element).keydown(
            function(e) {
                switch (e.keyCode) {
                case 38:
                        // up
                    moveUp();
                    e.preventDefault();
                    break;
                case 40:
                        // down
                    moveDown();
                    e.preventDefault();
                    break;
                case 13:
                        // return
                    e.preventDefault();
                    if (accepted != null) {
                        accepted(currentId);
                    }
                    $results.html('');
                    break;
                }
            });

        $(element).keyup(
            function(e) {
                switch (e.keyCode) {
                case 38:
                // up
                case 40:
                // down
                case 9:
                // tab
                case 13:
                        // return
                    break;
                default:
                    performSearch();
                    break;
                }
            });

        function moveUp() {
            if (activeIndex > 0) {
                activeIndex -= 1;
            }

            highlightValue();
        }

        function moveDown() {
            var count = $results.find("tr").length;

            if (activeIndex < 0) {
                activeIndex = 0;
            } else {
                activeIndex += 1;
            }
            if (activeIndex == count) {
                activeIndex = count - 1;
            }

            highlightValue();
        }

        function highlightValue() {
            $results.find("tr").each(
                function(index) {
                    if (index == activeIndex) {
                        currentId = $(this).attr('id');
                        $(this).addClass('ui-widget-header');
                    } else {
                        $(this).removeClass('ui-widget-header');
                    }
                });
        }

        function performSearch() {
            var searchStringFromElement = $(element).val();
            if (searchStringFromElement) {
                $.ajaxSetup({ cache: false });
                //var noCacheDate = Date().getTime();
                $.getJSON(url, { searchString: searchStringFromElement }, populateSearchResults);
            } else {
                $results.html('');
                $results.css({
                        width: "0px",
                        top: "0px",
                        left: "0px"
                    });
            }
        }

        function populateSearchResults(data) {
            activeIndex = -1;
            $results.html('');
            var finalHtml = '<table class="ui-corner-all ui-widget-content" style="width: ' + $(element).width() + 'px">';
            var currentValue = $(element).val().toLowerCase();
            for (index = 0; index < data.length; index++) {
                var formattedGameName = data[index].Value;
                var ImageUrl = data[index].ImageUrl;
                var indexOf = formattedGameName.toLowerCase().indexOf(currentValue);
                if (indexOf != -1 && currentValue.length >= 1) {
                    formattedGameName = data[index].Value.substr(0, indexOf)
                        + '<strong>' + data[index].Value.substr(indexOf, currentValue.length)
                            + '</strong>' + data[index].Value.substr(indexOf + currentValue.length);
                }

                var imageTag = '<img src="' + ImageUrl + '" style="padding-right:3px; vertical-align:middle; width:55px; height:65px;" />';

                finalHtml += '<tr id="' + data[index].Key + '" style="cursor: pointer;" class="ui-corner-all ui-widget-content"><td>' + imageTag + formattedGameName + '</td></tr>';
            }

            if (data.length == 0) {
                finalHtml += '<tr><td>' + noresults + '</td></tr>';
            }

            finalHtml += '</table>';
            $results.append(finalHtml);
            $results.find('tr').each(
                function() {
                    $(this).hover(
                        function() {
                            whenHover(this);
                        });

                    $(this).click(
                        function() {
                            currentId = $(this).attr('id');
                            accepted(currentId);
                            $results.html('');
                        });
                });

            // get the position of the input field right now (in case the DOM is shifted)
            var pos = findPos(element);
            // either use the specified width, or autocalculate based on form element
            var iWidth = $(element).width();
            // reposition
            $results.css({
                    width: parseInt(iWidth + 17) + "px",
                    top: (pos.y + element.offsetHeight) + "px",
                    left: pos.x + "px"
                });
            $.ajaxSetup({ cache: true });
        }

        function findPos(obj) {
            var curleft = obj.offsetLeft || 0;
            var curtop = obj.offsetTop || 0;
            while (obj = obj.offsetParent) {
                curleft += obj.offsetLeft;
                curtop += obj.offsetTop;
            }
            return { x: curleft, y: curtop };
        }

        function whenHover(element) {
            $results.find("tr").each(
                function(index) {
                    $(this).removeClass('ui-widget-header');
                });

            $(element).addClass('ui-widget-header');
            currentId = $(element).attr('id');
        }
    };
})(jQuery);
