﻿
Array.prototype.indexOf = function(obj, start) {
    for (var i = (start || 0); i < this.length; i++) {
        if (this[i] == obj) {
            return i;
        }
    }
}

jQuery.fn.quickfind = function(options) {

    return this.each(function() {

        var defaults = {
            defaultText: 'Please select'
        };

        var opts = jQuery.extend(defaults, options),
		$input = jQuery(this),
		$containerDivText = jQuery('<div class="quickfind_selected_item"></div>'),
		$newUl = jQuery('<ul class="quickfind_list"></ul>'),
		$containerDiv = jQuery('<div class="quickfind_select" tabindex="0"></div>'),
		itemIndex = -1,
		currentIndex = -1,
		keys = [],
		prevKey = false,
		newListItems = '';

        $containerDiv.insertAfter($input);
        $containerDivText.prependTo($containerDiv);
        $newUl.appendTo($containerDiv);
        $input.hide();

        if ($input.children('optgroup').length == 0) {
            $input.children().each(function(i) {
                var option = jQuery(this).text();
                var link = jQuery(this).find('a').attr('href');
                keys.push(option.charAt(0).toLowerCase());
                if (jQuery(this).attr('selected') == 'true') {
                    opts.defaultText = option;
                    currentIndex = i;
                }
                newListItems += '<li rel="' + (link == 'undefined' ? '' : link) + '">' + option + '</li>';
            });

            $newUl.html(newListItems);

            var $newLi = $newUl.children();
        } else {
            $input.children('optgroup').each(function(i) {

                var optionTitle = jQuery(this).attr('label'),
				$optGroup = jQuery('<li class="">' + optionTitle + '</li>');

                $optGroup.appendTo($newUl);

                var $optGroupList = jQuery('<ul></ul>');

                $optGroupList.appendTo($optGroup);

                jQuery(this).children().each(function() {
                    ++itemIndex;
                    var option = jQuery(this).text();

                    keys.push(option.charAt(0).toLowerCase());
                    if (jQuery(this).attr('selected') == true) {
                        opts.defaultText = option;
                        currentIndex = itemIndex;
                    }
                    newListItems += '<li>' + option + '</li>';
                })

                $optGroupList.html(newListItems);

                newListItems = '';
            });

            var $newLi = $newUl.find('ul li');
        }

        if (currentIndex != -1) {
            navigateList(currentIndex);
        } else {
            $containerDivText.text(opts.defaultText);
        }

        var newLiLength = $newLi.length;

        function newUlPos() {
            var containerPosY = $containerDiv.offset().top,
			containerHeight = $containerDiv.height() + 3,
			scrollTop = jQuery(window).scrollTop(),
			docHeight = jQuery(window).height(),
			newUlHeight = $newUl.height() + 3;

            containerPosY = containerPosY - scrollTop;
            if (containerPosY + newUlHeight >= docHeight) {
                $newUl.css('top', '-' + (newUlHeight + 5) + 'px');
            } else {
                $newUl.css('top', (containerHeight) + 'px');
            }
        }

        newUlPos();

        jQuery(window).resize(function(e) {
            newUlPos(e);
        });

        jQuery(window).scroll(function(e) {
            newUlPos(e);
        });

        function positionFix() {
            $containerDiv.css('position', 'relative');
        }

        function positionHideFix() {
            $containerDiv.css('position', 'static');
        }

        $containerDivText.click(function() {

            if ($newUl.is(':visible')) {
                $newUl.hide();
                positionHideFix()
                return false;
            }
            $('.homepage_content').css('z-index', '-1');
            $containerDiv.focus();

            $newUl.slideDown('fast');

            positionFix();
        });

        $containerDiv.blur(function() {
            $('.homepage_content').css('z-index', '1000');
            $newUl.hide();
            positionHideFix();
        });

        $containerDivText.hover(function(e) {
            var $hoveredTxt = jQuery(e.target);
            $hoveredTxt.addClass('quickfind_item_sel_hover');
        },
      function(e) {
          var $hoveredTxt = jQuery(e.target);
          $hoveredTxt.removeClass('quickfind_item_sel_hover');
      }
    );

        $newLi.hover(
      function(e) {
          var $hoveredLi = jQuery(e.target);
          $hoveredLi.addClass('quickfind_item_hover');
      },
      function(e) {
          var $hoveredLi = jQuery(e.target);
          $hoveredLi.removeClass('quickfind_item_hover');
      }
    );

        $newLi.click(function(e) {
            var $clickedLi = jQuery(e.target),
                text = $clickedLi.text(),
                rel = $clickedLi.attr('rel');

            if (rel != 'undefined')
                window.location = rel;

            currentIndex = $newLi.index($clickedLi);

            setSelectText(text);
            $newUl.hide();
            $containerDiv.css('position', 'static');
        });

        function setSelectText(text) {
            $input.val(text).change();
            $containerDivText.text(text);
        }

        function keyPress(element) {
            element.onkeydown = function(e) {
                if (e == null) {
                    var keycode = event.keyCode;
                } else {
                    var keycode = e.which;
                }

                switch (keycode) {
                    case 40: // down
                    case 39: // right
                        incrementList();
                        return false;
                        break;
                    case 38: // up
                    case 37: // left
                        decrementList();
                        return false;
                        break;
                    case 33: // page up
                    case 36: // home
                        gotoFirst();
                        return false;
                        break;
                    case 34: // page down
                    case 35: // end
                        gotoLast();
                        return false;
                        break;
                    case 13:
                    case 27:
                        $newUl.hide();
                        positionHideFix();
                        return false;
                        break;
                }

                keyPressed = String.fromCharCode(keycode).toLowerCase();
                var currentKeyIndex = keys.indexOf(keyPressed);

                if (typeof currentKeyIndex != 'undefined') {
                    e.preventDefault();
                    ++currentIndex;
                    currentIndex = keys.indexOf(keyPressed, currentIndex);

                    if (currentIndex == -1 || currentIndex == null || prevKey != keyPressed) currentIndex = keys.indexOf(keyPressed); //if no entry was found or new key pressed search from start of array
                    navigateList(currentIndex);

                    prevKey = keyPressed;
                }
            }
        }

        function incrementList() {
            if (currentIndex < (newLiLength - 1)) {
                ++currentIndex;
                navigateList(currentIndex);
            }
        }

        function decrementList() {
            if (currentIndex > 0) {
                --currentIndex;
                navigateList(currentIndex);
            }
        }

        function gotoFirst() {
            currentIndex = 0;
            navigateList(currentIndex);
        }

        function gotoLast(e) {
            currentIndex = newLiLength - 1;
            navigateList(currentIndex);
        }

        function navigateList(currentIndex) {
            $newLi.removeClass('hiLite')
			.eq(currentIndex).addClass('hiLite');
            var text = $newLi.eq(currentIndex).text();
            setSelectText(text);
        }

        $containerDiv.focus(function() {
            keyPress(this);
        });

        $containerDiv.click(function() {
            keyPress(this);
        });

    });
};
