theme.StickyHeader = function() {

    function StickyHeader() {

    };

    StickyHeader.prototype = $.extend({}, StickyHeader.prototype, {
        init: function($sticky, params) {
            var effect = $sticky.attr('data-sticky-effect') || 1;

            if ($sticky.length) {
                var stickyHeader = {
                    _create: function() {
                        var _ = this,
                            $elem = this.bindings,
                            $sticky_m = $elem.find(this.options.mobile && this.options.mobile.sticky ? this.options.mobile.sticky : ''),
                            $sticky_d = $elem.find(this.options.desktop && this.options.desktop.sticky ? this.options.desktop.sticky : ''),
                            $spacer_m = $('<div>').addClass('header__spacer header__spacer--m').insertBefore($sticky_m),
                            $spacer_d = $('<div>').addClass('header__spacer header__spacer--d').insertBefore($sticky_d);

                        this.sticky_class = 'header__content--sticky';

                        function fix() {
                            _._fix(_.$sticky, _.$spacer);
                            _._move(_.options[_.bp]);
                        };

                        function unfix() {
                            _._unfix(_.$sticky, _.$spacer);
                            _._return(_.options[_.bp]);
                        };

                        function on_resize() {
                            var is_desktop = theme.current.is_desktop;

                            _.bp = is_desktop ? 'desktop' : 'mobile';
                            _.$sticky = is_desktop ? $sticky_d : $sticky_m;
                            _.$spacer = is_desktop ? $spacer_d : $spacer_m;

                            if(!_.$sticky.length) return;

                            if (is_desktop) {
                                $spacer_m.removeClass('header__spacer--visible');
                                $spacer_d.addClass('header__spacer--visible');

                                if ($sticky_m.hasClass(_.sticky_class)) {
                                    _._unfix($sticky_m, $spacer_m);
                                    _._return(_.options.mobile);
                                }
                            } else {
                                $spacer_d.removeClass('header__spacer--visible');
                                $spacer_m.addClass('header__spacer--visible');

                                if ($sticky_d.hasClass(_.sticky_class)) {
                                    _._unfix($sticky_d, $spacer_d);
                                    _._return(_.options.desktop);
                                }
                            }
                        };

                        function on_scroll() {
                            if(!_.$sticky.length) return;

                            var limit = _.options[_.bp].limit ? _.options[_.bp].limit : 0,
                                spacer_pos = _.$spacer[0].getBoundingClientRect();

                            if (limit === 'bottom') {
                                limit = _.$sticky.hasClass(_.sticky_class) ? _.$spacer.innerHeight() : _.$sticky.innerHeight();
                            }

                            limit *= -1;

                            if (spacer_pos.top < limit) {
                                if (!_.$sticky.hasClass(_.sticky_class)) {
                                    fix();
                                }

                                if(!ie) {
                                    _._check_height(_.$sticky, _.options[_.bp]);
                                }
                            } else {
                                if (_.$sticky.hasClass(_.sticky_class)) {
                                    unfix();
                                }
                            }
                        };

                        on_resize();
                        on_scroll();

                        $window.on({
                            'theme.resize.stickyHeader': function() {
                                on_resize();
                                on_scroll();
                            },
                            'scroll.stickyHeader': on_scroll
                        });
                    },
                    _fix: function($sticky, $spacer) {
                        var height = $sticky.innerHeight();

                        $spacer.height(height);

                        if(this.options[this.bp].fade) {
                            $sticky.css({ 'opacity': 0 }).velocity({ 'opacity': theme.animations.sticky_header.opacity }, this.options[this.bp].duration());
                        }

                        $sticky.addClass(this.sticky_class);
                    },
                    _unfix: function($sticky, $spacer) {
                        $spacer.removeAttr('style');

                        if(this.options[this.bp].fade) {
                            $sticky.velocity('stop', true);
                        }

                        $sticky.removeAttr('style').removeClass(this.sticky_class);
                    },
                    _move: function(obj) {
                        if (!obj.move) return;

                        $.each(obj.move, function() {
                            var $elem = $(this.elem),
                                $to = $(this.to),
                                method = this.method || 'append';

                            this.$elem = $elem;
                            this.$parent = $elem.parent();

                            $to[method]($elem);
                        });
                    },
                    _return: function(obj) {
                        if (!obj.move) return;

                        $.each(obj.move, function() {
                            var method = this.method || 'append';

                            this.$parent[method](this.$elem);
                            this.$elem = null;
                            this.$parent = null;
                        });
                    },
                    _check_height: function($sticky, obj) {
                        if(!obj.height) return;

                        var spacer_pos = this.$spacer[0].getBoundingClientRect(),
                            height = spacer_pos.bottom <= obj.height ? obj.height : spacer_pos.bottom;

                        $sticky.css({ 'min-height': height });
                    },
                    getStickyHeight: function() {
                        return this.options[this.bp] ? (this.options[this.bp].height || $(this.options[this.bp].sticky).innerHeight()) : 0;
                    },
                    destroy: function() {
                        $(window).unbind('resize.stickyHeader scroll.stickyHeader');

                        $.Widget.prototype.destroy.call(this);
                    }
                };

                $.widget('ui.stickyHeader', stickyHeader);

                $sticky.stickyHeader(params);

                this.$sticky = $sticky;

                return {
                    destroy: function() {
                        $sticky.stickyHeader('destroy');
                    }
                };
            }
        }
    });

    theme.StickyHeader = new StickyHeader;
};

$(function() {
    theme.StickyHeader();
});

/*DOCUMENTATION*/

//params example
/*
 {
 bp: 1024,
 mobile: {
 sticky: '.tt-header__nav',
 limit: 400,
 fade: true,
 duration: 400
 },
 desktop: {
 sticky: '.tt-header__menu',
 height: 60,
 move: [
 {
 elem: '.tt-header__sidebar',
 to: '.tt-header__menu',
 method: 'append'
 }
 ]
 }
 }

 //params info
 bp - responsive breakpoint (number)
 mobile, desktop - breakpoint params (object)
 bp.sticky - sticky element (selector)
 bp.limit - breakpoint to start sticky (number, 'bottom')
 bp.height - change sticky element height (number)
 bp.fade - fade effect (bool)
 bp.duration - effects duration (number)
 bp.move - move elements inside sticky (array of objects)
 bp.move.elem - items that are moved (selector)
 bp.move.to - element to which to move (selector)
 bp.move.method - jquery method move (string)
 */