"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = exports.MediaPlayerDecorator = exports.MediaPlayerBase = exports.MediaPlayer = void 0;
var _handle = require("@enact/core/handle");
var _hoc = _interopRequireDefault(require("@enact/core/hoc"));
var _propTypes = _interopRequireDefault(require("@enact/core/internal/prop-types"));
var _kind = _interopRequireDefault(require("@enact/core/kind"));
var _util = require("@enact/core/util");
var _I18nDecorator = require("@enact/i18n/I18nDecorator");
var _SpotlightContainerDecorator = require("@enact/spotlight/SpotlightContainerDecorator");
var _AnnounceDecorator = require("@enact/ui/AnnounceDecorator");
var _Pure = _interopRequireDefault(require("@enact/ui/internal/Pure"));
var _Media = _interopRequireDefault(require("@enact/ui/Media"));
var _Slottable = _interopRequireDefault(require("@enact/ui/Slottable"));
var _DurationFmt = _interopRequireDefault(require("ilib/lib/DurationFmt"));
var _propTypes2 = _interopRequireDefault(require("prop-types"));
var _compose = _interopRequireDefault(require("ramda/src/compose"));
var _react = require("react");
var _$L = _interopRequireDefault(require("../internal/$L"));
var _MediaControls = _interopRequireDefault(require("./MediaControls"));
var _MediaSlider = _interopRequireDefault(require("./MediaSlider"));
var _Skinnable = _interopRequireDefault(require("../Skinnable"));
var _Times = _interopRequireDefault(require("./Times"));
var _util2 = require("./util");
var _MediaPlayerModule = _interopRequireDefault(require("./MediaPlayer.module.css"));
var _jsxRuntime = require("react/jsx-runtime");
var _excluded = ["currentTime", "disabled", "durFmt", "loop", "mediaComponent", "mediaRef", "onChange", "onEnded", "onNext", "onPause", "onPlay", "onPrevious", "onRepeat", "onShuffle", "onUpdate", "paused", "playlist", "proportionPlayed", "repeat", "shuffle", "sourceIndex", "total", "type"];
/**
 * An Agate-styled `MediaPlayer` component.
 *
 * @module agate/MediaPlayer
 * @exports MediaPlayer
 * @exports MediaPlayerBase
 * @exports MediaPlayerDecorator
 */
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _objectDestructuringEmpty(t) { if (null == t) throw new TypeError("Cannot destructure " + t); }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _possibleConstructorReturn(t, e) { if (e && ("object" == typeof e || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var s = Object.getOwnPropertySymbols(e); for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
var Container = (0, _SpotlightContainerDecorator.SpotlightContainerDecorator)({
  enterTo: 'default-element'
}, 'div');
var forwardWithState = function forwardWithState(type) {
  return (0, _handle.adaptEvent)((0, _handle.call)('addStateToEvent'), (0, _handle.forwardWithPrevent)(type));
};

// provide forwarding of events on media controls
var forwardPlay = forwardWithState('onPlay');
var forwardPause = forwardWithState('onPause');
var memoGetDurFmt = (0, _util.memoize)(function /* locale */
() {
  return new _DurationFmt["default"]({
    length: 'medium',
    style: 'clock',
    useNative: false
  });
});
var getDurFmt = function getDurFmt(locale) {
  if (typeof window === 'undefined') return null;
  return memoGetDurFmt(locale);
};

/**
 * A player for media {@link agate/MediaPlayer.MediaPlayer|MediaPlayer}.
 *
 * @class MediaPlayerBase
 * @memberof agate/MediaPlayer
 * @ui
 * @public
 */
var MediaPlayerBase = exports.MediaPlayerBase = (0, _kind["default"])({
  name: 'MediaPlayer',
  propTypes: /** @lends agate/MediaPlayer.MediaPlayerBase.prototype */{
    /**
     * Any children `<source>` tag elements will be sent directly to the media element as
     * sources.
     *
     * @type {Node}
     * @required
     * @public
     */
    source: _propTypes2["default"].node.isRequired,
    /**
     * The current time in seconds of the media source.
     *
     * @type {Number}
     * @public
     */
    currentTime: _propTypes2["default"].number,
    /**
     * Removes interactive capability from this component.
     *
     * @type {Boolean}
     * @public
     */
    disabled: _propTypes2["default"].bool,
    /**
     * The current locale as a
     * {@link https://tools.ietf.org/html/rfc5646|BCP 47 language tag}.
     *
     * @type {String}
     * @public
     */
    locale: _propTypes2["default"].string,
    /**
     * `true` when the media loops.
     *
     * @type {Boolean}
     * @public
     */
    loop: _propTypes2["default"].bool,
    /**
     * Media component to use.
     *
     * The default (`'audio'`) renders an `HTMLMediaElement`. Custom media components must have
     * a similar API structure, exposing the following APIs:
     *
     * Properties:
     * * `currentTime` {Number} - Playback index of the media in seconds
     * * `duration` {Number} - Media's entire duration in seconds
     * * `loop` {Boolean} - Indicates whether the media element should start over when it reaches the end
     * * `paused` {Boolean} - Playing vs paused state. `true` means the media is paused
     * * `proportionPlayed` {Number} - A value between `0` and `1` representing the
     *	proportion of the media that has already been played
     *
     * Methods:
     * * `play()` - play media
     * * `pause()` - pause media
     * * `load()` - load media
     *
     * The [`source`] property is passed to the media component as a child node.
     *
     * @type {String|Component}
     * @default 'audio'
     * @public
     */
    mediaComponent: _propTypes["default"].renderable,
    /**
     * Function that generates a reference to the current loaded media
     *
     * @type {Function}
     * @public
     */
    mediaRef: _propTypes2["default"].func,
    /**
     * Called when position of media slider is changed.
     *
     * @type {Function}
     * @public
     */
    onChange: _propTypes2["default"].func,
    /**
     * Called when the media file reaches the end of its duration.
     *
     * @type {Function}
     * @public
     */
    onEnded: _propTypes2["default"].func,
    /**
     * Called when jumping to next media
     *
     * @type {Function}
     * @public
     */
    onNext: _propTypes2["default"].func,
    /**
     * Called when media is paused
     *
     * @type {Function}
     * @public
     */
    onPause: _propTypes2["default"].func,
    /**
     * Called when media is played
     *
     * @type {Function}
     * @public
     */
    onPlay: _propTypes2["default"].func,
    /**
     * Called when jumping to previous media
     *
     * @type {Function}
     * @public
     */
    onPrevious: _propTypes2["default"].func,
    /**
     * Called when media is on repeat.
     *
     * @type {Function}
     * @public
     */
    onRepeat: _propTypes2["default"].func,
    /**
     * Called when jumping to a random media
     *
     * @type {Function}
     * @public
     */
    onShuffle: _propTypes2["default"].func,
    /**
     * Called when media is updating.
     *
     * @type {Function}
     * @public
     */
    onUpdate: _propTypes2["default"].func,
    /**
     * The media pause state.
     *
     * @type {Boolean}
     * @public
     */
    paused: _propTypes2["default"].bool,
    /**
     * The current list of media.
     *
     * @type {Array}
     * @public
     */
    playlist: _propTypes2["default"].arrayOf(_propTypes2["default"].node),
    /**
     * Proportion of media file played.
     *
     * @type {Number}
     * @public
     */
    proportionPlayed: _propTypes2["default"].number,
    /**
     * The repeat mode of the media playlist.
     *
     * @type {('none'|'one'|'all')}
     * @default 'none'
     * @public
     */
    repeat: _propTypes2["default"].oneOf(['none', 'one', 'all']),
    /**
     * `true` when the media playlist is shuffled.
     *
     * @type {Boolean}
     * @public
     */
    shuffle: _propTypes2["default"].bool,
    /**
     * The index of the current played media.
     *
     * @type {Number}
     * @public
     */
    sourceIndex: _propTypes2["default"].number,
    /**
     * Disables 5-way spotlight navigation from navigating into the component.
     *
     * @type {Boolean}
     * @public
     */
    spotlightDisabled: _propTypes2["default"].bool,
    /**
     * The total time (duration) in seconds of the loaded media source.
     *
     * @type {Number}
     * @public
     */
    total: _propTypes2["default"].number,
    /**
     * Specifies what kind of layout the MediaPlayer should have.
     *
     * @type {('full'|'tiny')}
     * @default 'full'
     * @public
     */
    type: _propTypes2["default"].oneOf(['full', 'tiny'])
  },
  defaultProps: {
    mediaComponent: 'audio',
    type: 'full'
  },
  styles: {
    css: _MediaPlayerModule["default"],
    className: 'mediaPlayer'
  },
  computed: {
    className: function className(_ref) {
      var type = _ref.type,
        styler = _ref.styler;
      return styler.append(type);
    },
    durFmt: function durFmt(_ref2) {
      var locale = _ref2.locale;
      return getDurFmt(locale);
    }
  },
  render: function render(_ref3) {
    var currentTime = _ref3.currentTime,
      disabled = _ref3.disabled,
      durFmt = _ref3.durFmt,
      loop = _ref3.loop,
      mediaComponent = _ref3.mediaComponent,
      mediaRef = _ref3.mediaRef,
      onChange = _ref3.onChange,
      onEnded = _ref3.onEnded,
      onNext = _ref3.onNext,
      onPause = _ref3.onPause,
      onPlay = _ref3.onPlay,
      onPrevious = _ref3.onPrevious,
      onRepeat = _ref3.onRepeat,
      onShuffle = _ref3.onShuffle,
      onUpdate = _ref3.onUpdate,
      paused = _ref3.paused,
      playlist = _ref3.playlist,
      proportionPlayed = _ref3.proportionPlayed,
      repeat = _ref3.repeat,
      shuffle = _ref3.shuffle,
      sourceIndex = _ref3.sourceIndex,
      total = _ref3.total,
      type = _ref3.type,
      rest = _objectWithoutProperties(_ref3, _excluded);
    delete rest.source;
    return /*#__PURE__*/(0, _jsxRuntime.jsxs)(Container, _objectSpread(_objectSpread({}, rest), {}, {
      children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Media["default"], {
        loop: loop,
        mediaComponent: mediaComponent,
        onEnded: onEnded,
        onUpdate: onUpdate,
        ref: mediaRef,
        source: playlist ? playlist[sourceIndex] : null
      }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_MediaSlider["default"], {
        disabled: disabled,
        onChange: onChange,
        paused: paused,
        value: proportionPlayed,
        type: type
      }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Times["default"], {
        current: currentTime,
        formatter: durFmt,
        total: total,
        type: type
      }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_MediaControls["default"], {
        disabled: disabled,
        onNext: onNext,
        onPause: onPause,
        onPlay: onPlay,
        onPrevious: onPrevious,
        onRepeat: onRepeat,
        onShuffle: onShuffle,
        paused: paused,
        repeat: repeat,
        shuffle: shuffle,
        type: type
      })]
    }));
  }
});

/**
 * Media player behaviors to apply to {@link agate/MediaPlayer.MediaPlayerBase|MediaPlayerBase}.
 *
 * @class MediaPlayerBehaviorDecorator
 * @hoc
 * @memberof agate/MediaPlayer
 * @private
 */
var MediaPlayerBehaviorDecorator = (0, _hoc["default"])(function (config, Wrapped) {
  var _Class;
  return _Class = /*#__PURE__*/function (_Component) {
    function _Class(_props) {
      var _this;
      _classCallCheck(this, _Class);
      _this = _callSuper(this, _Class, [_props]);

      // Internal State
      _this.handle = _handle.handle.bind(_this);
      _this.handlePlay = _this.handle(forwardPlay, function () {
        return _this.play();
      });
      _this.handlePause = _this.handle(forwardPause, function () {
        return _this.pause();
      });
      //
      // Handled Media events
      //
      _this.addStateToEvent = function (ev) {
        return _objectSpread({
          // More props from `ev` may be added here as needed, but a full copy via `...ev`
          // overloads Storybook's Action Logger and likely has other perf fallout.
          type: ev.type
        }, _this.getMediaState());
      };
      /**
       * Returns an object with the current state of the media including `currentTime`, `duration`,
       * `paused` and `loop`
       *
       * @function
       * @memberof agate/MediaPlayer.MediaPlayerBase.prototype
       * @returns {Object}
       * @public
       */
      _this.getMediaState = function () {
        return {
          currentTime: _this.state.currentTime,
          duration: _this.state.duration,
          loop: _this.state.loop,
          paused: _this.state.paused,
          proportionPlayed: _this.state.proportionPlayed
        };
      };
      /**
       * The primary means of interacting with the media element.
       *
       * @param  {String} action The method to preform.
       * @param  {Multiple} props  The arguments, in the format that the action method requires.
       *
       * @private
       */
      _this.send = function (action, props) {
        return _this.media[action](props);
      };
      _this.handleEvent = function () {
        var el = _this.media;
        var updatedState = {
          currentTime: el.currentTime,
          duration: el.duration,
          loop: el.loop,
          paused: el.paused,
          proportionPlayed: el.proportionPlayed || 0
        };

        // If there's an error, we're obviously not loading, no matter what the readyState is.
        if (updatedState.error) updatedState.loading = false;
        _this.setState(updatedState);
      };
      /**
       * Programmatically plays the current media.
       *
       * @function
       * @memberof agate/MediaPlayer.MediaPlayerBase.prototype
       * @public
       */
      _this.play = function () {
        var playPromise = _this.send('play');
        if (playPromise) {
          playPromise.then(function () {
            // Automatic playback started!
          })["catch"](function () {
            // Auto-play was prevented
          });
        }
      };
      /**
       * Programmatically plays the current media.
       *
       * @function
       * @memberof agate/MediaPlayer.MediaPlayerBase.prototype
       * @public
       */
      _this.pause = function () {
        _this.send('pause');
      };
      /**
       * Programmatically sets the loop property of the media.
       *
       * @function
       * @memberof agate/MediaPlayer.MediaPlayerBase.prototype
       * @public
       */
      _this.handleOnRepeat = function () {
        // Handling the 3 states of repeat: repeat none, repeat one and repeat all
        var loop = false;
        _this.setState(function (_ref4) {
          var repeat = _ref4.repeat;
          switch (repeat) {
            case 'none':
              loop = !repeat.loop;
              return {
                loop: loop,
                repeat: 'one'
              };
            case 'one':
              return {
                repeat: 'all'
              };
            case 'all':
              return {
                repeat: 'none'
              };
          }
        }, function () {
          _this.media.loop = loop;
        });
      };
      _this.handleOnEnded = function () {
        // Play next media only if current media is not last or, if it is last, only if repeat='all'
        if (_this.state.sourceIndex !== _this.state.playlist.length - 1 || _this.state.sourceIndex === _this.state.playlist.length - 1 && _this.state.repeat === 'all') {
          _this.handleNext();
        }
      };
      _this.handleNext = function () {
        var currentIndex = _this.state.sourceIndex;
        if (_this.state.repeat !== 'one') {
          if (currentIndex < _this.state.playlist.length - 1) {
            ++currentIndex;
          } else if (_this.state.repeat === 'all') {
            // When shuffle is true, the playback of the list restarts and the media list is reshuffled.
            currentIndex = 0;
            if (_this.state.shuffle) {
              _this.shufflePlaylist();
            }
          }
          _this.setState(function () {
            return {
              sourceIndex: currentIndex
            };
          }, function () {
            _this.play();
          });
        } else {
          _this.media.currentTime = 0;
          _this.play();
        }
      };
      _this.handlePrevious = function () {
        var currentIndex = _this.state.sourceIndex;
        if (_this.state.repeat !== 'one' && (_this.media.paused || _this.media.currentTime < 2)) {
          if (currentIndex > 0) {
            --currentIndex;
          } else if (!_this.state.shuffle && _this.state.repeat === 'all') {
            currentIndex = _this.state.playlist.length - 1;
          }
          _this.setState(function () {
            return {
              sourceIndex: currentIndex
            };
          }, function () {
            _this.media.currentTime = 0;
            _this.play();
          });
        } else {
          _this.media.currentTime = 0;
          _this.play();
        }
      };
      _this.shufflePlaylist = function (currentMedia) {
        var remainingSize = _this.props.children.length;
        var playlist = _toConsumableArray(_this.props.children);
        var currentMediaIndex;

        // While there are elements in the array
        while (remainingSize > 0) {
          // Pick a random index
          var randomIndex = Math.floor(Math.random() * remainingSize);

          // Decrease size by 1
          remainingSize--;

          // And swap the last element with it
          var _ref5 = [playlist[randomIndex], playlist[remainingSize]];
          playlist[remainingSize] = _ref5[0];
          playlist[randomIndex] = _ref5[1];
          if (playlist[remainingSize] === currentMedia) {
            currentMediaIndex = remainingSize;
          }
        }

        // Keep the current media active and set it as the first element in the shuffled array
        if (currentMediaIndex) {
          var _ref6 = [playlist[currentMediaIndex], playlist[0]];
          playlist[0] = _ref6[0];
          playlist[currentMediaIndex] = _ref6[1];
        }
        _this.setState({
          playlist: playlist,
          sourceIndex: 0
        });
      };
      _this.handleShuffle = function () {
        var currentMedia = _this.state.playlist[_this.state.sourceIndex];
        _this.setState(function (_ref7) {
          var shuffle = _ref7.shuffle;
          if (!shuffle) {
            return {
              shuffle: true
            };
          } else {
            // When resetting shuffle to false, the initial playlist is set with the last played media kept active.
            return {
              shuffle: false,
              playlist: _this.props.children,
              sourceIndex: parseInt(currentMedia.key)
            };
          }
        }, function () {
          if (_this.state.shuffle) {
            _this.shufflePlaylist(currentMedia);
          }
        });
      };
      _this.onSliderChange = function (_ref8) {
        var value = _ref8.value;
        var currentTime = value * _this.state.duration;
        var seconds = Math.floor(currentTime);
        _this.media.currentTime = currentTime;
        if (!isNaN(seconds)) {
          var knobTime = (0, _util2.secondsToTime)(seconds, getDurFmt(_this.props.locale), {
            includeHour: true
          });
          _this.props.announce("".concat((0, _$L["default"])('jump to'), " ").concat(knobTime), true);
        }
      };
      _this.setMediaRef = function (node) {
        _this.media = node;
      };
      _this.media = null;
      _this.state = {
        currentTime: 0,
        duration: 0,
        loop: false,
        paused: true,
        playlist: _this.props.children,
        proportionPlayed: 0,
        repeat: 'none',
        shuffle: false,
        sourceIndex: 0
      };
      return _this;
    }
    _inherits(_Class, _Component);
    return _createClass(_Class, [{
      key: "render",
      value: function render() {
        var rest = Object.assign({}, (_objectDestructuringEmpty(this.props), this.props));
        delete rest.announce;
        return /*#__PURE__*/(0, _jsxRuntime.jsx)(Wrapped, _objectSpread(_objectSpread({}, rest), {}, {
          currentTime: this.state.currentTime,
          loop: this.state.loop,
          mediaRef: this.setMediaRef,
          onChange: this.onSliderChange,
          onEnded: this.handleOnEnded,
          onNext: this.handleNext,
          onPause: this.handlePause,
          onPlay: this.handlePlay,
          onPrevious: this.handlePrevious,
          onRepeat: this.handleOnRepeat,
          onShuffle: this.handleShuffle,
          onUpdate: this.handleEvent,
          paused: this.state.paused,
          playlist: this.state.playlist,
          proportionPlayed: this.state.proportionPlayed,
          repeat: this.state.repeat,
          shuffle: this.state.shuffle,
          sourceIndex: this.state.sourceIndex,
          total: this.state.duration
        }));
      }
    }]);
  }(_react.Component), _Class.displayName = 'MediaPlayerBehaviorDecorator', _Class.propTypes = /** @lends agate/MediaPlayer.MediaPlayerBehaviorDecorator.prototype */{
    /**
     * Passed by AnnounceDecorator for accessibility.
     *
     * @type {Object}
     * @public
     */
    announce: _propTypes2["default"].func,
    /**
     * The current locale as a
     * {@link https://tools.ietf.org/html/rfc5646|BCP 47 language tag}.
     *
     * @type {String}
     * @public
     */
    locale: _propTypes2["default"].string,
    /**
     * Media component to use.
     *
     * The default (`'video'`) renders an `HTMLVideoElement`. Custom media components must have
     * a similar API structure, exposing the following APIs:
     *
     * Methods:
     * * `load()` - load media
     *
     * @type {String|Component}
     * @default 'audio'
     * @public
     */
    mediaComponent: _propTypes["default"].renderable,
    /**
     * Called when jumping to next media
     *
     * @type {Function}
     * @public
     */
    onNext: _propTypes2["default"].func,
    /**
     * Called when media is paused
     *
     * @type {Function}
     * @public
     */
    onPause: _propTypes2["default"].func,
    /**
     * Called when media is played
     *
     * @type {Function}
     * @public
     */
    onPlay: _propTypes2["default"].func,
    /**
     * Called when jumping to previous media
     *
     * @type {Function}
     * @public
     */
    onPrevious: _propTypes2["default"].func,
    /**
     * Called when media is on repeat mode.
     *
     * @type {Function}
     * @public
     */
    onRepeat: _propTypes2["default"].func,
    /**
     * Called when jumping to a random media
     *
     * @type {Function}
     * @public
     */
    onShuffle: _propTypes2["default"].func
  }, _Class;
});

// eslint-disable-next-line no-shadow
var AnnounceDecorator = function AnnounceDecorator(Wrapped) {
  return function AnnounceDecorator(props) {
    var _useAnnounce = (0, _AnnounceDecorator.useAnnounce)(),
      announce = _useAnnounce.announce,
      children = _useAnnounce.children;
    return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.Fragment, {
      children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Wrapped, _objectSpread(_objectSpread({}, props), {}, {
        announce: announce
      })), children]
    });
  };
};

/**
 * A higher-order component that adds Agate specific behaviors to `MediaPlayer`.
 *
 * @hoc
 * @memberof agate/MediaPlayer
 * @mixes ui/Slottable.Slottable
 * @mixes agate/Skinnable.Skinnable
 * @public
 */
var MediaPlayerDecorator = exports.MediaPlayerDecorator = (0, _compose["default"])(AnnounceDecorator, MediaPlayerBehaviorDecorator, _Pure["default"], (0, _Slottable["default"])({
  slots: ['source']
}), _Skinnable["default"], (0, _I18nDecorator.I18nContextDecorator)({
  localeProp: 'locale'
}));

/**
 * An Agate-styled `MediaPlayer` component.
 *
 * Usage:
 * ```
 * <MediaPlayer>
 *   <source src={['https://sampleswap.org/mp3/artist/254731/BossPlayer_Your-Right-Here-160.mp3']} type='audio/mp3' />
 * </MediaPlayer>
 * ```
 *
 * @class MediaPlayer
 * @memberof agate/MediaPlayer
 * @extends agate/MediaPlayer.MediaPlayerBase
 * @mixes agate/MediaPlayer.MediaPlayerDecorator
 * @ui
 * @public
 */
var MediaPlayer = exports.MediaPlayer = MediaPlayerDecorator(MediaPlayerBase);
var _default = exports["default"] = MediaPlayer;