/**
 * Sticky blocks wrapper.
 *
 * @author Htmlstream
 * @version 1.0
 * @requires
 *
 */
;(function ($) {
  'use strict';

  $.HSCore.components.HSStickyBlock = {
    /**
     *
     *
     * @var Object _baseConfig
     */
    _baseConfig: {},

    /**
     *
     *
     * @var jQuery pageCollection
     */
    pageCollection: $(),

    /**
     * Initialization of Sticky blocks wrapper.
     *
     * @param String selector (optional)
     * @param Object config (optional)
     *
     * @return jQuery pageCollection - collection of initialized items.
     */

    init: function (selector, config) {
      this.collection = selector && $(selector).length ? $(selector) : $();
      if (!$(selector).length) return;

      this.config = config && $.isPlainObject(config) ?
        $.extend({}, this._baseConfig, config) : this._baseConfig;

      this.config.itemSelector = selector;

      this.initStickyBlock();

      return this.pageCollection;
    },

    initStickyBlock: function () {
      //Variables
      var $self = this,
        config = $self.config,
        collection = $self.pageCollection,
        windW = $(window).width();

      this.collection.each(function (i, el) {
        //Variables
        var $stickyBlock = $(el),
          type = $stickyBlock.data('type'),
          stickyBlockClasses = $stickyBlock.attr('class').replace($self.config.itemSelector.substring(1), ''),
          stickyBlockH = $stickyBlock.outerHeight(),
          stickyBlockW = $stickyBlock.outerWidth(),
          stickyBlockParentW = $stickyBlock.parent().width(),
          stickyBlockOffsetTop = $stickyBlock.offset().top,
          stickyBlockOffsetLeft = $stickyBlock.offset().left,
          startPoint = $.isNumeric($stickyBlock.data('start-point')) ? $stickyBlock.data('start-point') : $($stickyBlock.data('start-point')).offset().top,
          endPoint = $.isNumeric($stickyBlock.data('end-point')) ? $stickyBlock.data('end-point') : $($stickyBlock.data('end-point')).offset().top,
          hasStickyHeader = $stickyBlock.data('has-sticky-header');

        //Break function if there are no target element
        if (!$stickyBlock.length) return;

        $self.resolutionCheck($stickyBlock);

        if ($stickyBlock.hasClass('g-sticky-block--sm') && windW <= 576) {
          $stickyBlock.addClass('die-sticky');
          $self.resolutionCheck($stickyBlock);
        } else if ($stickyBlock.hasClass('g-sticky-block--md') && windW <= 768) {
          $stickyBlock.addClass('die-sticky');
          $self.resolutionCheck($stickyBlock);
        } else if ($stickyBlock.hasClass('g-sticky-block--lg') && windW <= 992) {
          $stickyBlock.addClass('die-sticky');
          $self.resolutionCheck($stickyBlock);
        } else if ($stickyBlock.hasClass('g-sticky-block--xl') && windW <= 1200) {
          $stickyBlock.addClass('die-sticky');
          $self.resolutionCheck($stickyBlock);
        } else {
          $stickyBlock.removeClass('die-sticky');
        }

        $(window).on('resize', function () {
          var windW = $(window).width();

          if ($stickyBlock.hasClass('g-sticky-block--sm') && windW <= 576) {
            $stickyBlock.addClass('die-sticky');
            $self.resolutionCheck($stickyBlock);
          } else if ($stickyBlock.hasClass('g-sticky-block--md') && windW <= 768) {
            $stickyBlock.addClass('die-sticky');
            $self.resolutionCheck($stickyBlock);
          } else if ($stickyBlock.hasClass('g-sticky-block--lg') && windW <= 992) {
            $stickyBlock.addClass('die-sticky');
            $self.resolutionCheck($stickyBlock);
          } else if ($stickyBlock.hasClass('g-sticky-block--xl') && windW <= 1200) {
            $stickyBlock.addClass('die-sticky');
            $self.resolutionCheck($stickyBlock);
          } else {
            $stickyBlock
              .removeClass('die-sticky')
              .css({
                'top': '',
                'left': ''
              });
          }

          if (type == 'responsive') {
            setTimeout(function () {
              var offsetTop = $(this).scrollTop(),
                headerH = $('header').outerHeight();
              stickyBlockH = $stickyBlock.outerHeight(),
                stickyBlockParentW = $stickyBlock.parent().width(),
                stickyBlockOffsetTop = $stickyBlock.parent().offset().top,
                stickyBlockOffsetLeft = $stickyBlock.parent().offset().left + parseInt($stickyBlock.parent().css('padding-left')),
                startPoint = $.isNumeric($stickyBlock.data('start-point')) ? $stickyBlock.data('start-point') : $($stickyBlock.data('start-point')).offset().top,
                endPoint = $.isNumeric($stickyBlock.data('end-point')) ? $stickyBlock.data('end-point') : $($stickyBlock.data('end-point')).offset().top;

              if (hasStickyHeader === true) {
                $stickyBlock
                  .not('.die-sticky')
                  .css({
                    'top': offsetTop + headerH >= (endPoint - stickyBlockH) ? endPoint - stickyBlockH - stickyBlockOffsetTop : headerH,
                    'left': stickyBlockOffsetLeft,
                    'width': stickyBlockParentW
                  });

                // if (offsetTop + headerH <= (endPoint - stickyBlockH)) {
                //   $stickyBlock
                //     .not('.die-sticky')
                //     .addClass('g-pos-fix g-m-reset');
                // }
              } else {
                $stickyBlock
                  .not('.die-sticky')
                  .css({
                    'top': offsetTop >= (endPoint - stickyBlockH) ? endPoint - stickyBlockH - stickyBlockOffsetTop : 0,
                    'left': stickyBlockOffsetLeft,
                    'width': stickyBlockParentW
                  });

                // if (offsetTop <= (endPoint - stickyBlockH)) {
                //   $stickyBlock
                //     .not('.die-sticky')
                //     .addClass('g-pos-fix g-m-reset');
                // }
              }
            }, 400);
          }
        });

        if (type != 'responsive') {
          //Add "shadow" element
          var offsetTop = $(this).scrollTop();

          /* Args:
           * [1: target element]
           * [2: window offset top]
           * [3: target element height]
           * [4: target element width]
           * [5: target element index]
           * [6: target element classes (exclude init class)]
           * [7: start point]
           * [8: end point]
           */
          $self.addShadow($stickyBlock, offsetTop, stickyBlockH, stickyBlockW, i, stickyBlockClasses, startPoint, endPoint, hasStickyHeader);

          //Add sticky state
          /* Args:
           * [1: target element]
           * [2: window offset top]
           * [3: target element height]
           * [4: target element width]
           * [5: target offset left]
           * [6: start point]
           * [7: end point]
           */
          $self.addSticky($stickyBlock, offsetTop, stickyBlockH, stickyBlockW, stickyBlockOffsetLeft, startPoint, endPoint, hasStickyHeader);
        } else {
          //Add responsive sticky state
          var offsetTop = $(this).scrollTop();

          /* Args:
           * [1: target element]
           * [2: window offset top]
           * [3: parent element height]
           * [4: parent element width]
           * [5: target offset left]
           * [6: start point]
           * [7: end point]
           */
          $self.addSticky($stickyBlock, offsetTop, 'auto', stickyBlockParentW, stickyBlockOffsetLeft, startPoint, endPoint, hasStickyHeader);
        }

        $(window).on('scroll', function () {
          var offsetTop = $(this).scrollTop();

          if (type != 'responsive') {
            //Add "shadow" element
            /* Args:
             * [1: target element]
             * [2: window offset top]
             * [3: target element height]
             * [4: target element width]
             * [5: target element index]
             * [6: target element classes (exclude init class)]
             * [7: start point]
             * [8: end point]
             */
            $self.addShadow($stickyBlock, offsetTop, stickyBlockH, stickyBlockW, i, stickyBlockClasses, startPoint, endPoint, hasStickyHeader);

            //Add sticky state
            /* Args:
             * [1: target element]
             * [2: window offset top]
             * [3: target element height]
             * [4: target element width]
             * [5: target offset left]
             * [6: start point]
             * [7: end point]
             */
            $self.addSticky($stickyBlock, offsetTop, stickyBlockH, stickyBlockW, stickyBlockOffsetLeft, startPoint, endPoint, hasStickyHeader);
          } else {
            //Add responsive sticky state
            /* Args:
             * [1: target element]
             * [2: window offset top]
             * [3: parent element height]
             * [4: parent element width]
             * [5: target offset left]
             * [6: start point]
             * [7: end point]
             */
            $self.addSticky($stickyBlock, offsetTop, 'auto', stickyBlockParentW, stickyBlockOffsetLeft, startPoint, endPoint, hasStickyHeader);
          }

          //Remove sticky state
          /* Args:
           * [1: target element]
           * [2: window offset top]
           * [3: start point]
           */
          $self.removeSticky($stickyBlock, offsetTop, startPoint, hasStickyHeader);

          if (endPoint) {
            //Add absolute state
            /* Args:
             * [1: target element]
             * [2: target element height]
             * [3: target element index]
             * [4: target offset top]
             * [5: window offset top]
             * [6: end point]
             */

            $self.addAbsolute($stickyBlock, stickyBlockH, i, stickyBlockOffsetTop, offsetTop, endPoint, hasStickyHeader);
          }
        });

        $(window).trigger('scroll');

        //Add object to collection
        collection = collection.add($stickyBlock);
      });
    },

    addSticky: function (target, offsetTop, targetH, targetW, offsetLeft, startPoint, endPoint, hasStickyHeader) {
      if (hasStickyHeader === true) {
        var headerH = $('header').outerHeight();

        if (offsetTop + headerH >= startPoint && offsetTop + headerH < endPoint) {
          target
            .not('.die-sticky')
            .removeClass('g-pos-rel')
            .css({
              'top': '',
              'left': '',
              'width': '',
              'height': ''
            })
            .addClass('g-pos-fix g-m-reset')
            .css({
              'top': headerH,
              'left': offsetLeft,
              'width': targetW,
              'height': targetH
            });
        }
      } else {
        if (offsetTop >= startPoint && offsetTop < endPoint) {
          target
            .not('.die-sticky')
            .removeClass('g-pos-rel')
            .css({
              'top': '',
              'left': '',
              'width': '',
              'height': ''
            })
            .addClass('g-pos-fix g-m-reset')
            .css({
              'top': 0,
              'left': offsetLeft,
              'width': targetW,
              'height': targetH
            });
        }
      }
    },

    removeSticky: function (target, offsetTop, startPoint, hasStickyHeader) {
      if (hasStickyHeader === true) {
        var headerH = $('header').outerHeight();

        if (offsetTop + headerH <= startPoint) {
          target
            .not('.die-sticky')
            .removeClass('g-pos-fix g-m-reset')
            .css({
              'left': ''
            });
        }
      } else {
        if (offsetTop <= startPoint) {
          target
            .not('.die-sticky')
            .removeClass('g-pos-fix g-m-reset')
            .css({
              'left': ''
            });
        }
      }
    },

    addAbsolute: function (target, targetH, targetI, targetOffsetTop, offsetTop, endPoint, hasStickyHeader) {
      if (target.hasClass('g-pos-rel')) return;

      if (hasStickyHeader === true) {
        var headerH = $('header').outerHeight();

        if (offsetTop + headerH >= endPoint - targetH) {
          target
            .not('.die-sticky')
            .removeClass('g-pos-fix g-m-reset')
            .addClass('g-pos-rel')
            .css({
              'top': endPoint - targetH - targetOffsetTop,
              'left': ''
            });
        }
      } else {
        if (offsetTop >= endPoint - targetH) {
          target
            .not('.die-sticky')
            .removeClass('g-pos-fix g-m-reset')
            .addClass('g-pos-rel')
            .css({
              'top': endPoint - targetH - targetOffsetTop,
              'left': ''
            });
        }
      }
    },

    addShadow: function (target, offsetTop, targetH, targetW, targetI, targetClasses, startPoint, endPoint, hasStickyHeader) {
      if (hasStickyHeader === true) {
        var headerH = $('header').outerHeight();

        if (offsetTop + headerH > startPoint && offsetTop + headerH < (endPoint - targetH)) {
          if ($('#shadow' + targetI).length) return;

          //Add shadow block
          target
            .not('.die-sticky')
            .before('<div id="shadow' + targetI + '" class="' + targetClasses + '" style="height: ' + targetH + 'px; width: ' + targetW + 'px"></div>');
        } else {
          if (!$('#shadow' + targetI).length) return;

          //Remove shadow block
          $('#shadow' + targetI).remove();
        }
      } else {
        if (offsetTop > startPoint && offsetTop < (endPoint - targetH)) {
          if ($('#shadow' + targetI).length) return;

          //Add shadow block
          target
            .not('.die-sticky')
            .before('<div id="shadow' + targetI + '" class="' + targetClasses + '" style="height: ' + targetH + 'px; width: ' + targetW + 'px"></div>');
        } else {
          if (!$('#shadow' + targetI).length) return;

          //Remove shadow block
          $('#shadow' + targetI).remove();
        }
      }
    },

    resolutionCheck: function (target) {
      target
        .removeClass('g-pos-fix g-m-reset')
        .css({
          'top': '',
          'left': '',
          'width': '',
          'height': ''
        });
    }
  }
})(jQuery);
