(function($){

    $.fn.mdsgnDropdown = function(options) {

        var defaults = {
            name:               'Mdsgn jQuery Plugin Repository . Dropdown',
            version:            '0.1',
            customClass:        '',
            dropdownClass:      '',
            persistentClass:    'persistent',
            collapsibleClass:   'collapsible',
            textClass:          'text',
            buttonClass:        'button',
            expandedClass:      'expanded',
            collapsedClass:     'collapsed',
            mode:               'select',   // 'select'|'box'
            openEasing:         'easeOutBack',
            closeEasing:        'easeInBack',
            triggerType:        'all',      // 'all'|'button'
            triggerEvent:       'click',    // 'hover'|'click'
            defaultText:        'Seleccione una opcion',

            buildHtmlMarkup:    false,

            openDelay:          1000,
            closeDelay:         1000,
            openTime:           600,
            closeTime:          500,

            selectOptions:      null,

            preventDefault:   true,
            stopPropagation:  true
        }

        // Options Merge
        var options = $.extend(defaults, options);

        /**
         * Id del Obejto Dropdown
         */
        var _dropdownId  = null;

        /**
         * Id del select que se esta reemplazando
         */
        var _selectId    = null;

        /**
         * Texto Actual
         */
        var _actualText  = options.defaultText;


        // PRIVATE METHODS
        // DOM Getters
        var _getDropdown    = function() {return $('#' + _dropdownId);}
        var _getSelect      = function() {return (_selectId == null) ? null : $('#' + _selectId);}
        var _getPersistent  = function() {return $('#' + _dropdownId + ' .' + options.persistentClass);}
        var _getText        = function() {return _getPersistent().children('.' + options.textClass);}
        var _getButton      = function() {return _getPersistent().children('.' + options.buttonClass);}
        var _getCollapsible = function() {return $('#' + _dropdownId + ' .' + options.collapsibleClass);}
        var _getTrigger     = function() {return (options.triggerType == 'all') ? _getPersistent() : _getButton();}

        var _buildDropdownHtml = function() {
            var _html = _dropdownHtml;
            var _classes = options.dropdownClass + ' ' + options.customClass + ' ' + _getSelect().attr('class');
            _html = _html.replace(/{dropdown-class}/gi, _classes);
            _html = _html.replace(/{dropdown-id}/gi, _dropdownId);
            _html = _html.replace(/{persistent-class}/gi, options.persistentClass);
            _html = _html.replace(/{text-class}/gi, options.textClass);
            _html = _html.replace(/{button-class}/gi, options.buttonClass);
            _html = _html.replace(/{collapsible-class}/gi, options.collapsibleClass);

            return _html;
        }

        var _dropdownHtml = ''
        + '<ul class="{dropdown-class}" id="{dropdown-id}">'
        + '    <li class="{persistent-class}">'
        + '        <span class="{text-class}"></span>'
        + '        <span class="{button-class}"><span></span></span>'
        + '    </li>'
        + '    <li class="{collapsible-class}">'
        + '        <ul>'
        + '        </ul>'
        + '    </li>'
        + '</ul>';

        var _buildOptionHtml = function(_this) {
            var _html = _optionHtml;
            var _class = (_this.attr('selected') == 'selected') ? 'selected ' : '';
            _html = _html.replace(/{value}/gi, _this.val());
            _html = _html.replace(/{label}/gi, _this.text());
            _html = _html.replace(/{class}/gi, _class);
            return _html;
        }

        var _optionHtml = ''
        + '<li><span dropdown="{value}" class="{class}">{label}</span></li>';

        var _appendOptions = function() {
            // Text
            if (_getText().text() == '') {
                _setText(options.defaultText);
            }
            var _html = ''
            // Options
            _getSelect().children('option').each(function(e) {
                _html = _html + _buildOptionHtml($(this));
            });
            // Append
            _getCollapsible().children('ul').append(_html);
            // events            
            _getCollapsible().children('ul').children('li').each(function(e){                
                $(this).children('span')
                    .click(
                        function(e){
                            _changeOption($(this));
                        }
                    )
                    .hover(
                        function(e){
                            if ($(this).text() != _actualText) {
                                _updateText($(this).text());
                            }
                        }
                        ,function(e){
                            if ($(this).text() != _actualText) {
                                _updateText(_actualText);
                            }
                        }
                    );
                
                if ($(this).children('span').hasClass('selected')) {
                    _setText($(this).text());
                }
            
            });
        }
        
        var _changeOption = function(_this) {
            var _value = _this.attr('dropdown');
            _setText(_this.text());
            _close();
            if (_getSelect().val() != _value) {
                _getSelect().val(_value).change();
            }
        }

        var _setText = function(_text)
        {
            _actualText = _text;
            _updateText(_text);
            return this;
        }

        var _updateText = function(_text)
        {
            _getText()
                .stop(true,true)
//                .hide()
                .fadeOut(100)
//                .stop(true,true)
                .empty()
                .append(_text)
                .fadeIn(250);
        }

        var _open = function()
        {
            var trigger = _getTrigger();
            _getCollapsible().stop(true,true).slideDown({
                duration: options.closeTime,
                easing: options.openEasing,
                complete:
                    function() {
                        _openCallback();
                    }
                }
            );
            return;
        }

        var _close = function ()
        {
            var trigger = _getTrigger();
            _getCollapsible().stop(true,true).slideUp({
                duration: options.closeTime,
                easing: options.closeEasing,
                complete:
                    function() {
                        _closeCallback();
                    }
                }
            );
            return;
        }
        
        var _openCallback = function() {
            var trigger = _getTrigger();
            // Classes
            _getDropdown()
                .removeClass(options.collapsedClass)
                .addClass(options.expandedClass)
                .mouseleave(function(e){
                    _getDropdown().unbind('mouseleave');
                    _close();
                });
            // Events Unbind
            trigger.unbind(options.triggerEvent);
            // Rebind by Type
            if (options.triggerEvent == 'click') {
                trigger.click(function(e){
                    _close(trigger);
                });
            }

        }

        var _closeCallback = function() {
            var trigger = _getTrigger();
            // Classes
            _getDropdown()
                .removeClass(options.expandedClass)
                .addClass(options.collapsedClass)
                .unbind('mouseleave');
            // Events Unbind
            trigger.unbind(options.triggerEvent);
            // Rebind by Type
            if (options.triggerEvent == 'click') {
                trigger.click(function(e){
                    _open(trigger);
                });
            }
        }


        return this.each(function() {
            var _this = $(this);
            // Ids
            if (options.mode == 'select') {
                var _id     = _this.attr("id");
                _dropdownId = _id + "-dropdown";
                _selectId   = _id;
                // Select Building
                _getSelect().after(_buildDropdownHtml());
                _appendOptions();

            } else {
                _dropdownId = _this.attr("id");
            }

            // Trigger
            var _trigger = _getTrigger();

            // Cursor 
            if (options.triggerType == 'all') {
                _getPersistent().css("cursor", "pointer");
            } 
            
            if (options.triggerEvent == 'click') {
                _trigger.click(function(e){
                   _open(_trigger);
                });
            }

        });

    }
})(jQuery);
