/**
 * jQuery DropOptions Plugin
 */


;(function($) {   
  
    /**
     *  Main function for applying dropoption functionality to HTML elements
     */
    $.fn.dropoptions = function(opts) {

        // merge with defaults
        var settings = $.extend({}, $.fn.dropoptions.defaults, opts);

        // for each element that matches..
        return this.each(function() {

            // replace existing content with the skeleton of our dropdown
            this.innerHTML = '<ul class="' + settings.main_class + '">' + settings.prefix + '<li class="' + settings.default_option_class + '"><a href="#" class="small-dd">' + settings.default_text  + '<span></span></a><ul></ul></li>' + settings.suffix + '</ul>';
            
            // create the open/close functionality 
            $('a', this).bind("click",{settings:settings}, _showOptions);

            $dropdown = $('ul.' + settings.main_class + ' ul', this);                         
            
           
            //$.each(settings.data, function() { $.fn.dropoptions.addOption($dropdown, this); });    
            $.fn.dropoptions.createQuick($dropdown, settings.data);                
                             
           
            // if they have specified an onclick callback, apply it
            if(settings.callback)
            {
                $dropdown.bind("click", settings.callback_data, function(e) {                
                    // event delegation
                    var $target = $(e.target);
                    if($target.is('a'))
                    {
                        return settings.callback.call($target.get(), e);                 
                    }
                });
            }
            
            // set the width and height of our dropdown list     
            $.fn.dropoptions.setWidth($dropdown, settings);
            $.fn.dropoptions.setHeight($dropdown, settings);   
            $dropdown.hide(); // just incase    
        });
    };
    
    // our default options
    $.fn.dropoptions.defaults = {
        callback: function(e) { 
             $this = $(this);
             $('li a', $this.parent().parent()).removeClass('selected');
             $this.addClass('selected');
             $.fn.dropoptions.updateDefault($this.parent().parent().parent(), $this.text()); 
             $.fn.dropoptions.closeSelects(); 
             return true;
        },
        callback_data:{},
        content: false,
        default_option_class: 'dd',
        default_text: 'dropdown options',
        main_class: 'dropOptions',
        max_options: 10,
        max_width: 300,
        min_width: 100,
        prefix: '',                
        suffix: ''
    };      
    
    /* PUBLIC FUNCTIONS */  
    
    $.fn.dropoptions.addOption = function($dropdown, data)
    {                     
        $dropdown.append($.fn.dropoptions.createOption(data));                
        if(data.selected)
        {                    
            $.fn.dropoptions.updateDefault($dropdown.parent(), data.text);
        }        
    };
    
    $.fn.dropoptions.createOption = function(data)
    {
        if(!data.link) { data.link = '#'; }
        var link = '<a href="' + data.link + '"';
        link += (data.val) ? ' index="' + data.val + '"' : '';                   
        link += (data.selected) ? ' class="selected">' : '>';
                       
        return '<li>' + link + data.text + '</a></li>';           
    };
    
    $.fn.dropoptions.createQuick = function($dropdown, data)
    {
        var html = '';
        for(var i = 0; i < data.length; i++)
        {
            html += $.fn.dropoptions.createOption(data[i]);             

            if(data[i].selected)
            {                    
                $.fn.dropoptions.updateDefault($dropdown.parent(), data[i].text);
            }                  
        }
        $dropdown.get(0).innerHTML = html;
    };
   
    /**
     *  Hide any dropdowns that are currently open
     */
    $.fn.dropoptions.closeSelects = function()
    {
        $('.' + $.fn.dropoptions.defaults.main_class + ' ul').hide();
    };   

    /**
     *  Utility function to check if an event was triggered inside a dropdown, if not then close any open dropdowns
     */
    $.fn.dropoptions.closeSelectsCheck = function(e)
    {
	    if ($(e.target).parents('.' + $.fn.dropoptions.defaults.main_class).length === 0) { $.fn.dropoptions.closeSelects(); }        
    };
    
    /**
     * Sets the height of the dropdown based on the max number of options to display setting
     */
    $.fn.dropoptions.setHeight = function($dropdown, settings)
    {
        if(settings.data.length > settings.max_options)
        {
            var $li = $('li', $dropdown).eq(settings.max_options);
            $dropdown.height($li.offset().top - $dropdown.offset().top);
        }
    };   
    
    /**
     *  Sets the width of the default option to match the width of the dropdown,
     *  which itself might first be contstrained by either the max_width or min_width settings.
     */
    $.fn.dropoptions.setWidth = function($dropdown, settings)
    {        
        if($dropdown.width() > settings.max_width)
        {
            $dropdown.width(settings.max_width);
        }
        else if($dropdown.width() < settings.min_width)
        {
            $dropdown.width(settings.min_width);
        }        
        
        // change the value of the default option to be the width of the dropdown ul        
        $('li.' + settings.default_option_class, $dropdown.parent().parent()).width($dropdown.width());      
    }; 
    
    /**
     *  Update the default (or "selected") option 
     */
    $.fn.dropoptions.updateDefault = function($dropdown, text)
    {
        $('a:first', $dropdown).html(text + "<span/>");
    };
    
    /* PRIVATE FUNCTIONS */    
    
    /**
     *  Show or hide the options, this is the event handler for clicking the open button
     */
    function _showOptions(e)
    {
        var settings = e.data.settings;
        var $ul = $(this).next('ul');
                    
        if($ul.css('display') == 'none') 
        {
            $.fn.dropoptions.closeSelects();
        }                            
                                                            
        $ul.toggle(); 
                           
        if($ul.css('display') != 'none' && settings.data.length > settings.max_options) 
        {
           var offset = $('.selected', $ul).eq(0).offset().top - $ul.offset().top;
           $ul.animate({scrollTop: offset}, 1);
        }                    
                            
        return false;
    };
    

    
    $(document).mousedown($.fn.dropoptions.closeSelectsCheck);

})(jQuery);

