//  Track visible elemnts on the screen.
const Eyeline = function Eyeline(selector) {
  this.selector = selector;
};

Eyeline.prototype.update = function() {
  if (Ember.testing) { return; }

  const docViewTop = $(window).scrollTop(),
        windowHeight = $(window).height(),
        docViewBottom = docViewTop + windowHeight,
        $elements = $(this.selector),
        bottomOffset = $elements.last().offset(),
        self = this;

  let atBottom = false;
  if (bottomOffset) {
    atBottom = (bottomOffset.top <= docViewBottom) && (bottomOffset.top >= docViewTop);
  }

  return $elements.each(function(i, elem) {
    const $elem = $(elem),
          elemTop = $elem.offset().top,
          elemBottom = elemTop + $elem.height();

    let markSeen = false;

    // Make sure the element is visible
    if (!$elem.is(':visible')) return true;

    // It's seen if...
    // ...the element is vertically within the top and botom
    if ((elemTop <= docViewBottom) && (elemTop >= docViewTop)) markSeen = true;

    // ...the element top is above the top and the bottom is below the bottom (large elements)
    if ((elemTop <= docViewTop) && (elemBottom >= docViewBottom)) markSeen = true;

    // ...we're at the bottom and the bottom of the element is visible (large bottom elements)
    if (atBottom && (elemBottom >= docViewTop)) markSeen = true;

    if (!markSeen) return true;

    // If you hit the bottom we mark all the elements as seen. Otherwise, just the first one
    if (!atBottom) {
      self.trigger('saw', { detail: $elem });
      if (i === 0) {
        self.trigger('sawTop', { detail: $elem });
      }
      return false;
    }
    if (i === 0) {
      self.trigger('sawTop', { detail: $elem });
    }
    if (i === ($elements.length - 1)) {
      return self.trigger('sawBottom', { detail: $elem });
    }
  });
};


//  Call this when we know aren't loading any more elements. Mark the rest as seen
Eyeline.prototype.flushRest = function() {
  if (Ember.testing) { return; }
  const self = this;
  $(this.selector).each(function(i, elem) {
    return self.trigger('saw', { detail: $(elem) });
  });
};

RSVP.EventTarget.mixin(Eyeline.prototype);

export default Eyeline;
