/**
     * SelectForm
     * Plugin odpowiedzialny za generowanie niestandardowych-stylowanych list wyboru select
     * @author: K2
     * @version: 2.1
     * modified @18.12.2014
     **/

    (function ($, window, document, undefined) {
        "use strict";

        var defaults = {
            removeId: '',
            animationSpeed: 300,
            additionalWidth: 150,
            autoWidth: true,
            effect: 'swing'
        };

        function SelectForm(element, options) {
            this.options = $.extend({}, defaults, options);
            this.$el = $(element);
            this.$item = this.$el.find(this.options.item);

            this.init();
        }

        SelectForm.prototype.init = function () {
            var self = this,
                id = self.$el.attr('id'),
                o = self.options;

            $('.selectLabel[data-id = ' + id + '], .scrollPaneSelect[data-id = ' + id + ']').remove();

            var tmpW = 100,
                scrollPaneSelect = $('ul[data-id=' + self.$el.attr('id') + ']'),
                moreThan10 = false;

            if (self.$el.find('option, optgroup').length > 10) {
                moreThan10 = true;
            }

            if (scrollPaneSelect.length)
                scrollPaneSelect.remove();

            if (!self.$el.hasClass('scrollPaneSelect')) {
                var tmpid = self.$el.attr('id'),
                    tmpSClass = self.$el.attr('class'),
                    tmpSCSI = tmpSClass !== undefined ? tmpSClass.search(/width[0-9]+/) : -1;

                if (tmpSCSI > -1) {
                    var tmpSCEI = tmpSClass.searchFrom(/\ /, tmpSCSI),
                        tmpSCEI = tmpSCEI == -1 ? tmpSClass.length : tmpSCEI,
                        tmpWC = tmpSClass.substring(tmpSCSI, tmpSCEI),
                        tmpW = tmpWC.replace(/width/, '');

                    tmpW = parseInt(tmpW) + (tmpW.substr(tmpW.length - 1, 1) === 'p' ? '%' : 'px');
                }

                var selectLabel = self.generateLabel(self.$el, id, tmpW),
                    scrollPaneSelect = self.generateOptions(self.$el, id);

                selectLabel.on('click', function (e) {
                    if (!$(this).hasClass('disabled')) {
                        var cDOffset = $(this).offset(),
                            id = $(this).data('id'),
                            cDO = $('.scrollPaneSelect[data-id=' + $(this).data('id') + ']');

                        cDOffset.top += $(this).innerHeight();

                        $('#' + $(this).data('id')).focus();

                        $('.selectLabel').removeClass('expanded');
                        $(this).addClass('expanded');

                        cDO.css({
                            'top': cDOffset.top + 'px',
                            'left': Math.round(cDOffset.left) - o.additionalWidth + 'px',
                            width: $(this).outerWidth()
                        });

                        if ($('.scrollPaneSelect[data-id=' + id + ']').is(':visible')) {
                            $('.selectLabel').removeClass('expanded');
                            self.removeSelectOptions(e);

                            return false;
                        } else {
                            cDO.slideDown({
                                'duration': o.animationSpeed,
                                'easing': o.effect,
                                'complete': function () {
                                    if (moreThan10) {
                                        if (!$('html').hasClass('lt-ie10') && !$('.scrollPaneSelect[data-id=' + $(this).data('id') + ']').find('.mCustomScrollBox').length) {
                                            jQuery('.scrollPaneSelect[data-id=' + jQuery(this).data('id') + ']').jScrollPane({
                                                showArrows: true,
                                                verticalDragMinHeight: 23,
                                                verticalDragMaxHeight: 23
                                            });
                                        }
                                    }
                                }
                            });
                        }
                    }
                });

                scrollPaneSelect.on('mouseup', 'li', function () {
                    var tmpid = $(this).parent().parent().parent().data('id');

                    self.$el.val($(this).data('value'));

                    $(this).siblings('li').removeClass('selected').end().addClass('selected');
                    $('.selectLabel[data-id=' + tmpid + '] span').text($(':selected', self.$el).text());

                    $('.selectLabel').removeClass('expanded');

                    self.$el.trigger('change');
                });

                $(document).on('mouseup', function (e) {
                    self.removeSelectOptions(e, false);
                });

                self.$el.on('change', function (e) {
                    self.selectOption($(this));
                });

                self.$el.on('focus', function (e) {
                    $(this).prev('.selectLabel').addClass('focus');
                });

                self.$el.on('blur', function (e) {
                    //if (!$.browser.msie) self.removeSelectOptions(e, true);

                    $(this).prev('.selectLabel').removeClass('focus');
                });

                self.$el.on('keyup', function (e) {
                    switch (e.keyCode) {
                        case 13:

                            self.removeSelectOptions(e, true);

                            break;

                        case 32:

                            $(this).prev('.selectLabel').trigger('click');

                            break;

                        default:

                            self.selectOption($(this));

                            break;
                    }
                });

                self.$el.before(selectLabel);
                $('body').append(scrollPaneSelect);
                $('.customDropdown').show();
            }
        };

        SelectForm.prototype.selectOption = function ($this) {
            var self = this,
                o = self.options,
                id = $this.attr('id'),
                selected = $this.find('option:selected').val(),
                text = $this.find('option:selected').text();


            $('.selectOptions[data-id=' + id + '] li').removeClass('selected');
            $('.selectOptions[data-id=' + id + '] li[data-value="' + selected + '"]').addClass('selected');

            $('.selectLabel[data-id=' + id + '] span').text(text);
        };

        SelectForm.prototype.removeSelectOptions = function (e, stopPropagation) {
            var self = this,
                o = self.options;

            if (stopPropagation) {
                e.stopImmediatePropagation();
            }

            if (!$(e.target).is('div.mCSB_dragger_bar') &&
                !$(e.target).is('div.mCSB_dragger') &&
                !$(e.target).is('.jspDrag') &&
                !$(e.target).is('.jspArrow'))
            {
                $('.selectLabel').removeClass('expanded');
                $('.scrollPaneSelect').slideUp({
                    'duration': o.animationSpeed,
                    'easing': o.effect,
                    'complete': function () {

                    }
                });
            }
        };

        SelectForm.prototype.generateLabel = function ($this, id, tmpW) {
            var self = this,
                o = self.options,
                attrClass = (typeof $this.attr('class') != 'undefined') ? $this.attr('class') : '',
                attrDisabled = (typeof $this.attr('disabled') != 'undefined') ? $this.attr('disabled') : '';

            var selectLabel = $('<div data-id="' + id + '" class="selectLabel ' + attrClass + ' ' + attrDisabled + '"><span>' + $this.find(':selected').text() + '</span><em></em></div>');
            selectLabel.css('width', tmpW);

            return selectLabel;
        };

        SelectForm.prototype.generateOptions = function ($this, id, tmpW) {
            var self = this,
                o = self.options,
                moreThan10 = false;

            if ($this.find('option, optgroup').length > 10) {
                moreThan10 = true;
            }

            var tmpHtml = [];
            $this.children().each(function (i) {
                var tmpOnclick = '';

                if (this.nodeName.toLowerCase() == 'optgroup') {
                    tmpHtml.push('<li class="selectOptGroup" ' + (tmpOnclick != '' ? ' onclick="' + tmpOnclick + '"' : '') + '><span class="option-item">' + $(this).attr('label') + '</span></li>');

                    $(this).children('option').each(function () {
                        tmpHtml.push('<li class="selectOptGroupElement' + ($(this).attr('selected') ? ' selected' : '') + ' ' + $(this).attr('class') + '" data-value="' + $(this).val() + '" ' + (tmpOnclick != '' ? ' onclick="' + tmpOnclick + '"' : '') + '><span class="option-group-item">&nbsp;&nbsp;&nbsp;' + $(this).text() + '</span></li>');
                    });

                } else {
                    tmpHtml.push('<li class="' + ($(this).attr('selected') ? 'selected' : '') + '" data-value="' + $(this).val() + '"' + (tmpOnclick != '' ? ' onclick="' + tmpOnclick + '"' : '') + '><span class="option-item">' + $(this).text() + '</span></li>');
                }
            });

            var scrollPaneSelect = $('.scrollPaneSelect.' + $this.attr('id'));

            if (scrollPaneSelect && scrollPaneSelect.length) {
                scrollPaneSelect.html(tmpHtml.join(''));
                if (moreThan10)
                    scrollPaneSelect.css({'width': (tmpW + 34) + 'px', 'height': '203px', 'overflow-y': 'scroll'});
                else
                    scrollPaneSelect.css({'width': (tmpW + 34) + 'px'});
            } else {
                scrollPaneSelect = $('<ul data-id="' + id + '" class="scrollPaneSelect selectOptions ' + (moreThan10 ? 'mt10' : '') + ' ' + $this.attr('name') + ' ' + $this.attr('class') + '" style="width:' + (tmpW + o.additionalWidth) + 'px;' + (moreThan10 ? 'height:230px;overflow-y:scroll' : '') + '"></ul>').html(tmpHtml.join(''));
            }
            return scrollPaneSelect;
        };

        String.prototype.searchFrom = function (s, f) { /* s-search regexp, f-from index */
            var tmpI = this.substr(f).search(s);

            return tmpI == -1 ? -1 : f + tmpI;
        };

        $.fn.selectForm = function (options) {
            return $(this).each(function () {
                new SelectForm(this, options);
            });
        };

    })($, window, document);
