/*
* Completely re-written by Scott Taylor, eMusic
* 2009, based on jQuery 1.3.2
*
* jQuery selectbox plugin
* Copyright (c) 2007 Sadri Sahraoui (brainfault.com)
* Licensed under the GPL license and MIT:
*   http://www.opensource.org/licenses/GPL-license.php
*   http://www.opensource.org/licenses/mit-license.php
* The code is inspired from Autocomplete plugin (http://www.dyve.net/jquery/?autocomplete)
*/

"use strict";

/*globals jQuery, $ */

jQuery.fn.extend({
	selectbox: function (options) {
		return this.each(function () {
			return new jQuery.SelectBox(this, options);
		});
	}
});

jQuery.SelectBox = function (selectobj, options) {
    var opt = jQuery.extend({
        inputClass : "selectbox",
        containerClass : "selectbox-wrapper",
        hoverClass : "current",
        currentClass : "selected",
        debug : false,
        wrapper : null,
        callback : false,
        clickCallback : null,
        blurCallback : null
    }, options),

    elm_id = selectobj.id,
	active = 0,
    parentForm,
    formTabItems,
	inFocus = false,
	hasfocus = 0,
	jSelect = $(selectobj),
	jContainer, jInput,

    root = opt.wrapper;

	jSelect = $(selectobj);
	jContainer = $('<div></div>').attr('id', elm_id + '_container').addClass(opt.containerClass);
	jInput = $('<input type="text" />')
                    .addClass(opt.inputClass)
                    .attr({
                        'id'          : elm_id + '_input',
                        'autocomplete': 'off',
                        'readonly'    : 'readonly',
                        'tabIndex'    :  jSelect.attr('tabindex')
                    });


	// hide select and append newly created elements
	jSelect.hide().before(jInput).before(jContainer);

    function hideAll() {
        $('.boxOpen').removeClass('boxOpen');
        $('.selectbox-wrapper').closest('.glowTop').andSelf().removeAttr('style');

        hasfocus = 0;
    }

    function toggleRoot() {
        if (root.hasClass('boxOpen')) {
            hideAll();
        } else {
            hideAll();
            root.addClass('boxOpen');
        }
    }

	function setCurrent() {
        var li, ar, el, last, temp;

		li = jContainer.find('li.' + opt.currentClass).get(0);
		ar = li.id.split('_');
		el = ar[ar.length - 1];
        last = jContainer.find('li:last');

        jSelect.find('option').removeAttr('selected');
		jSelect.val(el).trigger('change');

        if (last.get(0) == li) {
            li.className = 'selected';
            $(li.previousSibling).addClass('last');
        } else {
            last.addClass('last').siblings().removeClass('last');
        }

        temp = $(li).html();

        jInput.val(temp.replace('&amp;', '&'));

		hideAll();
	}

    function focusItem(e) {
        e.stopPropagation();
        e.preventDefault();

        $(this).addClass(opt.currentClass).siblings().removeClass(opt.currentClass);

        setCurrent();
    }

    function executeBlurFunction() {
        if (root.hasClass('boxOpen') && jQuery.isFunction(opt.blurCallback)) {
            opt.blurCallback(null, root);
        }

        hideAll();
    }

    function init() {
        var ul, li, optVal;

        $(window).blur(executeBlurFunction).click(executeBlurFunction);
        $('body').blur(executeBlurFunction).click(executeBlurFunction);

        ul = $('<ul></ul>');
		jSelect.children('option').each(function (i) {
			li = $('<li></li>');
            optVal = $(this).html().replace('&amp;', '&');

            li.attr('id', jInput.attr('id') + '_' + $(this).val()).html(optVal);

            if ($(this).is(':selected')) {
                jInput.val(optVal).addClass(opt.currentClass);
			}

            if (i === jSelect.children('option').length - 1) {
                li.className = 'last';
            }

            ul.append(li);
		});

        jContainer.append(ul).find('li').each(function () {
            $(this)
                .mouseover(function () {
                    $(this).addClass(opt.hoverClass);
                })
                .mouseout(function () {
                    $(this).removeClass(opt.hoverClass);
                })
                .click(focusItem);
        });

        if (root.find('option:selected').length) {
            $('#_input_'+ root.find('option:selected').val()).addClass('selected');
        }
    }

	function scroll(list, active) {
        var el;
        el= $(list[active]).get(0);
        list = jContainer.get(0);

        if (el.offsetTop + el.offsetHeight > list.scrollTop + list.clientHeight) {
            list.scrollTop = el.offsetTop + el.offsetHeight - list.clientHeight;
        } else if(el.offsetTop < list.scrollTop) {
            list.scrollTop = el.offsetTop;
        }
	}    

	function moveSelect(step) {
		var lis = jContainer.find('li');

        if (!lis || lis.length === 0) {
            return false;
        } else {
            active += step;

            //loop through list
            if (active < 0) {
                active = lis.size();
            } else if (active > lis.size()) {
                active = 0;
            }

            scroll(lis, active);
            lis.eq(active).addClass(opt.hoverClass).siblings().removeClass(opt.hoverClass);
        }
    }

    function focusFormWidget(e) {
        var currentIndex, newIndex, parentForm = $(this).closest('form');

        if (parentForm.length) {
            formTabItems = parentForm.find('input, button').not(':hidden');

            currentIndex = formTabItems.index(this);

            if (e.shiftKey) {
                if (currentIndex - 1 < 0) {
                    newIndex = formTabItems.length - 1;
                } else {
                    newIndex = currentIndex - 1;
                }
            } else {
                if (currentIndex + 1 >= formTabItems.length) {
                    newIndex = 0;
                } else {
                    newIndex = currentIndex + 1;
                }
            }
            formTabItems.eq(newIndex).get(0).focus();
        }
    }

//    jSelect
//    .keydown(function (e) {
//        switch (e.keyCode) {
//        case 9:  // tab
//            focusFormWidget.call(jInput, e);
//            break;
//        }
//    });

	jInput
    .click(function (e) {
        e.stopPropagation();
        e.preventDefault();

        if (jQuery.isFunction(opt.clickCallback)) {
            opt.clickCallback(e, root);
        }

        toggleRoot();
    });
//    .keydown(function (e) {
//        e.stopPropagation();
//        e.preventDefault();
//
//		switch (e.keyCode) {
//        case 38: // up
//            moveSelect(-1);
//            break;
//        case 40: // down
//            moveSelect(1);
//            break;
//        case 9:  // tab
//            focusFormWidget.call(this, e);
//            break;
//        case 13: // return
//            if (jQuery.isFunction(opt.clickCallback)) {
//                opt.clickCallback(e, root);
//            }
//            toggleRoot();
//            $('li.' + opt.hoverClass).trigger('click');
//            break;
//        case 27: //escape
//            if (jQuery.isFunction(opt.clickCallback)) {
//                opt.clickCallback(e, root);
//            }
//            toggleRoot();
//            break;
//		}
//	});

    return init();
};