/**
 * VueLayers
 * Web map Vue components with the power of OpenLayers
 *
 * @package vuelayers
 * @author Vladimir Vershinin <ghettovoice@gmail.com>
 * @version 0.12.0-rc.27
 * @license MIT
 * @copyright (c) 2017-2021, Vladimir Vershinin <ghettovoice@gmail.com>
 */
import _typeof from '@babel/runtime/helpers/esm/typeof';
import _toConsumableArray from '@babel/runtime/helpers/esm/toConsumableArray';
import { merge, fromEventPattern, Observable } from 'rxjs';
import { map, distinctUntilChanged, tap, debounceTime } from 'rxjs/operators';
import { isFunction, isEqual, identity } from './utils';

/**
 * Creates an Observable using OpenLayers event pattern that emits events coming from the given event target.
 *
 * @example **Subscribe on view center change events**
 * const map = ol.Map({ ... })
 * const changes = Observable.fromOlEvent(map.getView(), 'change:center')
 *
 * changes.subscribe(({ coordinate }) => console.log(coordinate))
 *
 * @param {module:ol/Observable~Observable} target OpenLayers event target.
 * @param {string|Object[]} eventName The event name of interest, being emitted by the `target`
 *                          or an array of events/selectors like `[{ event: 'event1', selector?: x => x }, ...]`.
 * @param {function(...*): *} [selector] An optional function to post-process results. It takes the arguments
 *    from the event handler and should return a single value.
 * @param {Observable[]} [pipeEach]
 * @return {Observable<T>}
 * @memberOf {Observable}
 */

function fromOlEvent(target, eventName, selector) {
  var pipeEach = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];

  if (Array.isArray(eventName)) {
    return merge.apply(void 0, _toConsumableArray(eventName.map(function (elem) {
      var _fromOlEvent;

      var eventName, selector;

      if (_typeof(elem) === 'object') {
        eventName = elem.event;
        selector = elem.selector;
      } else {
        eventName = elem;
      }

      return (_fromOlEvent = fromOlEvent(target, eventName, selector)).pipe.apply(_fromOlEvent, _toConsumableArray(pipeEach));
    })));
  }

  selector || (selector = identity);
  return fromEventPattern(function (handler) {
    return target.on(eventName, handler);
  }, function (handler) {
    return target.un(eventName, handler);
  }).pipe(map(selector));
}
/**
 * Creates Observable from OpenLayers change:* event
 * @param {module:ol/Observable~Observable} target
 * @param {string|string[]} [prop]
 * @param {boolean|function(a, b):boolean|undefined} [distinct] Distinct values by isEqual fn or by custom comparator
 * @param {function|undefined} [selector] Custom selector
 * @param {Observable[]} [pipeEach]
 * @return {Observable<{prop: string, value: *}>}
 */

function fromOlChangeEvent(target, prop, distinct, selector) {
  var pipeEach = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];

  if (Array.isArray(prop)) {
    return merge.apply(void 0, _toConsumableArray(prop.map(function (p) {
      var _fromOlChangeEvent;

      return (_fromOlChangeEvent = fromOlChangeEvent(target, p, distinct, selector)).pipe.apply(_fromOlChangeEvent, _toConsumableArray(pipeEach));
    })));
  }

  selector || (selector = identity);
  var event = "change:".concat(prop);
  var observable = fromOlEvent(target, event, function () {
    return target.get(prop);
  });
  var operations = [];

  if (distinct) {
    isFunction(distinct) || (distinct = isEqual);
    operations.push(distinctUntilChanged(distinct));
  }

  operations.push(map(function (value) {
    return selector({
      prop: prop,
      value: value
    });
  }));
  return observable.pipe.apply(observable, operations);
}
function fromVueEvent(target, eventName, selector) {
  if (Array.isArray(eventName)) {
    return merge.apply(void 0, _toConsumableArray(eventName.map(function (elem) {
      var eventName, selector;

      if (_typeof(elem) === 'object') {
        eventName = elem.event;
        selector = elem.selector;
      } else {
        eventName = elem;
      }

      return fromVueEvent(target, eventName, selector);
    })));
  }

  selector || (selector = identity);
  return fromEventPattern(function (handler) {
    return target.$on(eventName, handler);
  }, function (handler) {
    return target.$off(eventName, handler);
  }).pipe(map(selector));
}
function fromVueWatcher(target, exprOrFn) {
  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  return new Observable(function (s) {
    return target.$watch(exprOrFn, function (value, previous) {
      return s.next({
        value: value,
        previous: previous
      });
    }, options);
  });
}

function bufferDebounceTime() {
  var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
  return function (source) {
    var bufferedValues = [];
    return source.pipe(tap(function (value) {
      return bufferedValues.push(value);
    }), debounceTime(time), map(function () {
      return bufferedValues;
    }), tap(function () {
      bufferedValues = [];
    }));
  };
}

export { bufferDebounceTime, fromOlChangeEvent, fromOlEvent, fromVueEvent, fromVueWatcher };
//# sourceMappingURL=rx-ext.js.map
