'use strict';

var _getIterator2 = require('babel-runtime/core-js/get-iterator');

var _getIterator3 = _interopRequireDefault(_getIterator2);

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

var _intervalFunction = require('./interval-function');

var _intervalFunction2 = _interopRequireDefault(_intervalFunction);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

(function (window, document) {
  'use strict';

  if (typeof window.ResizeObserver !== 'undefined') {
    return;
  }

  document.resizeObservers = [];

  /**
   * The content rect is defined in section 2.3 ResizeObserverEntry of the spec
   * @param target the element to calculate the content rect for
   * @return {{top: (Number|number), left: (Number|number), width: number, height: number}}
   *
   * Note:
   * Avoid using margins on the observed element. The calculation can return incorrect values when margins are involved.
   *
   * The following CSS will report incorrect width (Chrome OSX):
   *
   * <div id="outer" style="width: 300px; height:300px; background-color: green;overflow:auto;">
   *   <div id="observed" style="width: 400px; height:400px; background-color: yellow; margin:30px; border: 20px solid red; padding:10px;">
   *   </div>
   * </div>
   *
   * The calculated width is 280. The actual (correct) width is 340 since Chrome clips the margin.
   *
   * Use an outer container if you really need a "margin":
   *
   * <div id="outer" style="width: 300px; height:300px; background-color: green;overflow:auto; padding:30px;">
   *   <div id="observed" style="width: 400px; height:400px; background-color: yellow; margin: 0; border: 20px solid red; padding:10px;">
   *   </div>
   * </div>
   *
   * A more detailed explanation can be fund here:
   * http://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
   */
  var getContentRect = function getContentRect(target) {
    var cs = window.getComputedStyle(target);
    var r = target.getBoundingClientRect();
    var top = parseFloat(cs.paddingTop) || 0;
    var left = parseFloat(cs.paddingLeft) || 0;
    var width = r.width - ((parseFloat(cs.marginLeft) || 0) + (parseFloat(cs.marginRight) || 0) + (parseFloat(cs.borderLeftWidth) || 0) + (parseFloat(cs.borderRightWidth) || 0) + left + (parseFloat(cs.paddingRight) || 0));
    var height = r.height - ((parseFloat(cs.marginTop) || 0) + (parseFloat(cs.marginBottom) || 0) + (parseFloat(cs.borderTopWidth) || 0) + (parseFloat(cs.borderBottomWidth) || 0) + top + (parseFloat(cs.paddingBottom) || 0));
    return { width: width, height: height, top: top, left: left };
  };

  var dimensionHasChanged = function dimensionHasChanged(target, lastWidth, lastHeight) {
    var _getContentRect = getContentRect(target),
        width = _getContentRect.width,
        height = _getContentRect.height;

    return width !== lastWidth || height !== lastHeight;
  };

  /**
   * ResizeObservation holds observation information for a single Element.
   * @param target
   * @return {{target: *, broadcastWidth, broadcastHeight, isOrphan: (function()), isActive: (function())}}
   * @constructor
   */
  var ResizeObservation = function ResizeObservation(target) {
    var _getContentRect2 = getContentRect(target),
        width = _getContentRect2.width,
        height = _getContentRect2.height;

    return {
      target: target,
      broadcastWidth: width,
      broadcastHeight: height,

      isOrphan: function isOrphan() {
        return !this.target || !this.target.parentNode;
      },
      isActive: function isActive() {
        return dimensionHasChanged(this.target, this.broadcastWidth, this.broadcastHeight);
      }
    };
  };

  /**
   * A snapshot of the observed element
   * @param target
   * @param rect
   * @return {{target: *, contentRect: *}}
   * @constructor
   */
  var ResizeObserverEntry = function ResizeObserverEntry(target, rect) {
    return {
      target: target,
      contentRect: rect
    };
  };

  /**
   * The ResizeObserver is used to observe changes to Element's content rect.
   */

  var ResizeObserver = function () {

    /**
     * Constructor for instantiating new Resize observers.
     * @param callback void (sequence<ResizeObserverEntry> entries). The function which will be called on each resize.
     * @throws {TypeError}
     */
    function ResizeObserver(callback) {
      (0, _classCallCheck3.default)(this, ResizeObserver);


      if (typeof callback !== 'function') {
        throw new TypeError('callback parameter must be a function');
      }

      this.callback_ = callback;
      this.observationTargets_ = [];
      this.activeTargets_ = [];

      document.resizeObservers.push(this);
    }

    /**
     * A list of ResizeObservations. It represents all Elements being observed.
     *
     * @return {Array}
     */


    (0, _createClass3.default)(ResizeObserver, [{
      key: 'observe',


      /**
       * Adds target to the list of observed elements.
       * @param {HTMLElement} target The target to observe
       */
      value: function observe(target) {
        if (target) {
          if (!(target instanceof HTMLElement)) {
            throw new TypeError('target parameter must be an HTMLElement');
          }
          if (!this.observationTargets_.find(function (t) {
            return t.target === target;
          })) {
            this.observationTargets_.push(ResizeObservation(target));
            resizeController.start();
          }
        }
      }

      /**
       * Removes target from the list of observed elements.
       * @param target The target to remove
       */

    }, {
      key: 'unobserve',
      value: function unobserve(target) {
        var i = this.observationTargets_.findIndex(function (t) {
          return t.target === target;
        });
        if (i > -1) {
          this.observationTargets_.splice(i, 1);
        }
      }

      /**
       * Stops the ResizeObserver instance from receiving notifications of resize changes.
       * Until the observe() method is used again, observer's callback will not be invoked.
       */

    }, {
      key: 'disconnect',
      value: function disconnect() {
        this.observationTargets_ = [];
        this.activeTargets_ = [];
      }

      /**
       * Removes the ResizeObserver from the list of observers
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        var _this = this;

        this.disconnect();
        var i = document.resizeObservers.findIndex(function (o) {
          return o === _this;
        });
        if (i > -1) {
          document.resizeObservers.splice(i, 1);
        }
      }
    }, {
      key: 'deleteOrphansAndPopulateActiveTargets_',
      value: function deleteOrphansAndPopulateActiveTargets_() {

        // Works, but two iterations
        //this.observationTargets_ = this.observationTargets_.filter( resizeObervation => !resizeObervation.isOrphan());
        //this.activeTargets_ = this.observationTargets_.filter( resizeObervation => resizeObervation.isActive());

        // Same result as above, one iteration
        /*
        this.activeTargets_ = [];
        let n = this.observationTargets_.length-1;
        while(n >= 0) {
          if(this.observationTargets_[n].isOrphan()) {
            this.observationTargets_.splice(n, 1);
          }
          else if(this.observationTargets_[n].isActive()) {
            this.activeTargets_.push(this.observationTargets_[n]);
          }
          n -= 1;
        }
        */

        // Same result as above - but reduce is cooler :-)
        this.activeTargets_ = this.observationTargets_.reduceRight(function (prev, resizeObservation, index, arr) {
          if (resizeObservation.isOrphan()) {
            arr.splice(index, 1);
          } else if (resizeObservation.isActive()) {
            prev.push(resizeObservation);
          }
          return prev;
        }, []);
      }
    }, {
      key: 'broadcast_',
      value: function broadcast_() {
        this.deleteOrphansAndPopulateActiveTargets_();
        if (this.activeTargets_.length > 0) {
          var entries = [];
          var _iteratorNormalCompletion = true;
          var _didIteratorError = false;
          var _iteratorError = undefined;

          try {
            for (var _iterator = (0, _getIterator3.default)(this.activeTargets_), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
              var resizeObservation = _step.value;

              var rect = getContentRect(resizeObservation.target);
              resizeObservation.broadcastWidth = rect.width;
              resizeObservation.broadcastHeight = rect.height;
              entries.push(ResizeObserverEntry(resizeObservation.target, rect));
            }
          } catch (err) {
            _didIteratorError = true;
            _iteratorError = err;
          } finally {
            try {
              if (!_iteratorNormalCompletion && _iterator.return) {
                _iterator.return();
              }
            } finally {
              if (_didIteratorError) {
                throw _iteratorError;
              }
            }
          }

          this.callback_(entries);
          this.activeTargets_ = [];
        }
      }
    }, {
      key: 'observationTargets',
      get: function get() {
        return this.observationTargets_;
      }

      /**
       *  A list of ResizeObservations. It represents all Elements whose size has
       *  changed since last observation broadcast that are eligible for broadcast.
       *
       * @return {Array}
       */

    }, {
      key: 'activeTargets',
      get: function get() {
        return this.activeTargets_;
      }
    }]);
    return ResizeObserver;
  }();

  //let interval = require('./interval-function');

  /**
   * Broadcasts Element.resize events
   * @return {{start: (function()), stop: (function())}}
   * @constructor
   */


  var ResizeController = function ResizeController() {

    var shouldStop = function shouldStop() {
      return document.resizeObservers.findIndex(function (resizeObserver) {
        return resizeObserver.observationTargets.length > 0;
      }) > -1;
    };

    var execute = function execute() {
      //console.log('***** Execute');
      var _iteratorNormalCompletion2 = true;
      var _didIteratorError2 = false;
      var _iteratorError2 = undefined;

      try {
        for (var _iterator2 = (0, _getIterator3.default)(document.resizeObservers), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
          var resizeObserver = _step2.value;

          resizeObserver.broadcast_();
        }
      } catch (err) {
        _didIteratorError2 = true;
        _iteratorError2 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion2 && _iterator2.return) {
            _iterator2.return();
          }
        } finally {
          if (_didIteratorError2) {
            throw _iteratorError2;
          }
        }
      }

      return shouldStop();
    };

    var interval = (0, _intervalFunction2.default)(200);

    return {
      start: function start() {
        if (!interval.started) {
          //console.log('***** Start poll');
          interval.start(execute);
        }
      }
    };
  };

  window.ResizeObserver = ResizeObserver;

  var resizeController = ResizeController();
  //console.log('***** ResizeObserver ready');
})(window, document);
/**
 * An API for observing changes to Element’s size.
 *
 * @See https://wicg.github.io/ResizeObserver/
 * @ee https://github.com/pelotoncycle/resize-observer
 *
 */