(function($) {
    $.fn.extend({
        pulldown: function(options) {

            var defaults = {
                css: {
                    closed: 'sys_international_flag_list_item_closed',
                    empty: 'sys_international_flag_list_item_empty',
                    loading: 'sys_international_flag_list_item_loading',
                    open: 'sys_international_flag_list_item_open',
                    item: 'sys_international_flag_list_item',
                    padder: 'sys_international_flag_list_padder',
                    tube: 'sys_international_flag_list_innertube',
                    wrapper: 'sys_international_flag_list_wrapper'
                },
                lang: {
                    empty: 'Click here to select an option',
                    loading: 'Please wait...',
                    open: 'Select an option or click here to close'
                }
            }

            var config = $.extend(true, {}, defaults, options);

            if (this.filter('ul, ol').length > 0) {

                $(document).click(function() {
                    $('.' + config.css.tube + ':visible').not(':animated').each(function() {
                        $(this).prev('.' + config.css.wrapper).children().click();
                    });
                });

            }

            this.filter('ul, ol').each(function() {
                var $list = $(this);

                /* Build a "faux" drop down box wrapper from divs and pixey dust */
                var $wrapper = $(document.createElement('div')).addClass(config.css.wrapper).addClass(config.css.closed);
                var $tube = $(document.createElement('div')).addClass(config.css.tube);
                var $padder = $(document.createElement('div')).addClass(config.css.padder);

                $wrapper.append($.pulldown_generate_list_item(config.lang.empty, config.css.empty));

                $wrapper.children().toggle(
                    function() {
                        var $this = $(this);
                        $('.' + config.css.tube + ':visible').each(function() {
                            $(this).prev('.' + config.css.wrapper).children().click();
                        });
                        $.pulldown_show($this.parent(), $this.parent().next('.' + config.css.tube), $this, config.css.open, config.css.closed, config.lang.open);
                    },
                    function() {
                        var $this = $(this);
                        $.pulldown_hide($this.parent(), $this.parent().next('.' + config.css.tube), $this, config.css.open, config.css.closed, config.lang.empty);
                    }
                );

                $list.children('li').each(function() {
                    var $item = $(this);
                    $tube.append($.pulldown_generate_list_item($item.html(), config.css.item));
                });

                $tube.find('a').click(function() {
                    $(document).unbind('click');
                    $(this)
                        .parents('.' + config.css.tube)
                        .prev('.' + config.css.wrapper)
                        .removeClass(config.css.open)
                        .addClass(config.css.loading)
                        .children()
                        .text(config.lang.loading);
                    $('.' + config.css.tube).slideUp(500);
                    return true;
                });

                $tube.hide();
                $list.after($wrapper);
                $wrapper.after($tube);
                $tube.after($padder);
                $list.remove(); /* hide the list */

            });

        }
    });
    $.extend({
        pulldown_generate_list_item: function(text, cssClass) {
            return $(document.createElement('div')).addClass(cssClass).html(text);
        }
    });
    $.extend({
        pulldown_hide: function(wrapper, tube, textNode, openClass, closedClass, text) {
            wrapper
                .removeClass(openClass)
                .addClass(closedClass);
            tube.slideUp(500);
            textNode.text(text);
        },
        pulldown_show: function(wrapper, tube, textNode, openClass, closedClass, text) {
            wrapper
                .removeClass(closedClass)
                .addClass(openClass);
            tube.slideDown(500);
            textNode.text(text);
        }
    });
})(jQuery);
