text: 'use strict';
  
  exports.__esModule = true;
  
  var _textTrackCueList = require('./text-track-cue-list');
  
  var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);
  
  var _fn = require('../utils/fn.js');
  
  var Fn = _interopRequireWildcard(_fn);
  
  var _trackEnums = require('./track-enums');
  
  var _log = require('../utils/log.js');
  
  var _log2 = _interopRequireDefault(_log);
  
  var _window = require('global/window');
  
  var _window2 = _interopRequireDefault(_window);
  
  var _track = require('./track.js');
  
  var _track2 = _interopRequireDefault(_track);
  
  var _url = require('../utils/url.js');
  
  var _xhr = require('xhr');
  
  var _xhr2 = _interopRequireDefault(_xhr);
  
  var _mergeOptions = require('../utils/merge-options');
  
  var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  
  var _browser = require('../utils/browser.js');
  
  var browser = _interopRequireWildcard(_browser);
  
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  
  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  * @file text-track.js
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  */
  
  
  /**
   * Takes a webvtt file contents and parses it into cues
   *
   * @param {string} srcContent
   *        webVTT file contents
   *
   * @param {TextTrack} track
   *        TextTrack to add cues to. Cues come from the srcContent.
   *
   * @private
   */
  var parseCues = function parseCues(srcContent, track) {
    var parser = new _window2['default'].WebVTT.Parser(_window2['default'], _window2['default'].vttjs, _window2['default'].WebVTT.StringDecoder());
    var errors = [];
  
    parser.oncue = function (cue) {
      track.addCue(cue);
    };
  
    parser.onparsingerror = function (error) {
      errors.push(error);
    };
  
    parser.onflush = function () {
      track.trigger({
        type: 'loadeddata',
        target: track
      });
    };
  
    parser.parse(srcContent);
    if (errors.length > 0) {
      if (_window2['default'].console && _window2['default'].console.groupCollapsed) {
        _window2['default'].console.groupCollapsed('Text Track parsing errors for ' + track.src);
      }
      errors.forEach(function (error) {
        return _log2['default'].error(error);
      });
      if (_window2['default'].console && _window2['default'].console.groupEnd) {
        _window2['default'].console.groupEnd();
      }
    }
  
    parser.flush();
  };
  
  /**
   * Load a `TextTrack` from a specifed url.
   *
   * @param {string} src
   *        Url to load track from.
   *
   * @param {TextTrack} track
   *        Track to add cues to. Comes from the content at the end of `url`.
   *
   * @private
   */
  var loadTrack = function loadTrack(src, track) {
    var opts = {
      uri: src
    };
    var crossOrigin = (0, _url.isCrossOrigin)(src);
  
    if (crossOrigin) {
      opts.cors = crossOrigin;
    }
  
    (0, _xhr2['default'])(opts, Fn.bind(this, function (err, response, responseBody) {
      if (err) {
        return _log2['default'].error(err, response);
      }
  
      track.loaded_ = true;
  
      // Make sure that vttjs has loaded, otherwise, wait till it finished loading
      // NOTE: this is only used for the alt/video.novtt.js build
      if (typeof _window2['default'].WebVTT !== 'function') {
        if (track.tech_) {
          var loadHandler = function loadHandler() {
            return parseCues(responseBody, track);
          };
  
          track.tech_.on('vttjsloaded', loadHandler);
          track.tech_.on('vttjserror', function () {
            _log2['default'].error('vttjs failed to load, stopping trying to process ' + track.src);
            track.tech_.off('vttjsloaded', loadHandler);
          });
        }
      } else {
        parseCues(responseBody, track);
      }
    }));
  };
  
  /**
   * A representation of a single `TextTrack`.
   *
   * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack}
   * @extends Track
   */
  
  var TextTrack = function (_Track) {
    _inherits(TextTrack, _Track);
  
    /**
     * Create an instance of this class.
     *
     * @param {Object} options={}
     *        Object of option names and values
     *
     * @param {Tech} options.tech
     *        A reference to the tech that owns this TextTrack.
     *
     * @param {TextTrack~Kind} [options.kind='subtitles']
     *        A valid text track kind.
     *
     * @param {TextTrack~Mode} [options.mode='disabled']
     *        A valid text track mode.
     *
     * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
     *        A unique id for this TextTrack.
     *
     * @param {string} [options.label='']
     *        The menu label for this track.
     *
     * @param {string} [options.language='']
     *        A valid two character language code.
     *
     * @param {string} [options.srclang='']
     *        A valid two character language code. An alternative, but deprioritized
     *        vesion of `options.language`
     *
     * @param {string} [options.src]
     *        A url to TextTrack cues.
     *
     * @param {boolean} [options.default]
     *        If this track should default to on or off.
     */
    function TextTrack() {
      var _this, _ret;
  
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  
      _classCallCheck(this, TextTrack);
  
      if (!options.tech) {
        throw new Error('A tech was not provided.');
      }
  
      var settings = (0, _mergeOptions2['default'])(options, {
        kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles',
        language: options.language || options.srclang || ''
      });
      var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled';
      var default_ = settings['default'];
  
      if (settings.kind === 'metadata' || settings.kind === 'chapters') {
        mode = 'hidden';
      }
      // on IE8 this will be a document element
      // for every other browser this will be a normal object
      var tt = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
  
      tt.tech_ = settings.tech;
  
      if (browser.IS_IE8) {
        for (var prop in TextTrack.prototype) {
          if (prop !== 'constructor') {
            tt[prop] = TextTrack.prototype[prop];
          }
        }
      }
  
      tt.cues_ = [];
      tt.activeCues_ = [];
  
      var cues = new _textTrackCueList2['default'](tt.cues_);
      var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
      var changed = false;
      var timeupdateHandler = Fn.bind(tt, function () {
  
        // Accessing this.activeCues for the side-effects of updating itself
        // due to it's nature as a getter function. Do not remove or cues will
        // stop updating!
        /* eslint-disable no-unused-expressions */
        this.activeCues;
        /* eslint-enable no-unused-expressions */
        if (changed) {
          this.trigger('cuechange');
          changed = false;
        }
      });
  
      if (mode !== 'disabled') {
        tt.tech_.ready(function () {
          tt.tech_.on('timeupdate', timeupdateHandler);
        }, true);
      }
  
      /**
       * @memberof TextTrack
       * @member {boolean} default
       *         If this track was set to be on or off by default. Cannot be changed after
       *         creation.
       * @instance
       *
       * @readonly
       */
      Object.defineProperty(tt, 'default', {
        get: function get() {
          return default_;
        },
        set: function set() {}
      });
  
      /**
       * @memberof TextTrack
       * @member {string} mode
       *         Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will
       *         not be set if setting to an invalid mode.
       * @instance
       *
       * @fires TextTrack#modechange
       */
      Object.defineProperty(tt, 'mode', {
        get: function get() {
          return mode;
        },
        set: function set(newMode) {
          var _this2 = this;
  
          if (!_trackEnums.TextTrackMode[newMode]) {
            return;
          }
          mode = newMode;
          if (mode === 'showing') {
  
            this.tech_.ready(function () {
              _this2.tech_.on('timeupdate', timeupdateHandler);
            }, true);
          }
          /**
           * An event that fires when mode changes on this track. This allows
           * the TextTrackList that holds this track to act accordingly.
           *
           * > Note: This is not part of the spec!
           *
           * @event TextTrack#modechange
           * @type {EventTarget~Event}
           */
          this.trigger('modechange');
        }
      });
  
      /**
       * @memberof TextTrack
       * @member {TextTrackCueList} cues
       *         The text track cue list for this TextTrack.
       * @instance
       */
      Object.defineProperty(tt, 'cues', {
        get: function get() {
          if (!this.loaded_) {
            return null;
          }
  
          return cues;
        },
        set: function set() {}
      });
  
      /**
       * @memberof TextTrack
       * @member {TextTrackCueList} activeCues
       *         The list text track cues that are currently active for this TextTrack.
       * @instance
       */
      Object.defineProperty(tt, 'activeCues', {
        get: function get() {
          if (!this.loaded_) {
            return null;
          }
  
          // nothing to do
          if (this.cues.length === 0) {
            return activeCues;
          }
  
          var ct = this.tech_.currentTime();
          var active = [];
  
          for (var i = 0, l = this.cues.length; i < l; i++) {
            var cue = this.cues[i];
  
            if (cue.startTime <= ct && cue.endTime >= ct) {
              active.push(cue);
            } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) {
              active.push(cue);
            }
          }
  
          changed = false;
  
          if (active.length !== this.activeCues_.length) {
            changed = true;
          } else {
            for (var _i = 0; _i < active.length; _i++) {
              if (this.activeCues_.indexOf(active[_i]) === -1) {
                changed = true;
              }
            }
          }
  
          this.activeCues_ = active;
          activeCues.setCues_(this.activeCues_);
  
          return activeCues;
        },
        set: function set() {}
      });
  
      if (settings.src) {
        tt.src = settings.src;
        loadTrack(settings.src, tt);
      } else {
        tt.loaded_ = true;
      }
  
      return _ret = tt, _possibleConstructorReturn(_this, _ret);
    }
  
    /**
     * Add a cue to the internal list of cues.
     *
     * @param {TextTrack~Cue} cue
     *        The cue to add to our internal list
     */
  
  
    TextTrack.prototype.addCue = function addCue(originalCue) {
      var cue = originalCue;
  
      if (_window2['default'].vttjs && !(originalCue instanceof _window2['default'].vttjs.VTTCue)) {
        cue = new _window2['default'].vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text);
  
        for (var prop in originalCue) {
          if (!(prop in cue)) {
            cue[prop] = originalCue[prop];
          }
        }
  
        // make sure that `id` is copied over
        cue.id = originalCue.id;
        cue.originalCue_ = originalCue;
      }
  
      var tracks = this.tech_.textTracks();
  
      for (var i = 0; i < tracks.length; i++) {
        if (tracks[i] !== this) {
          tracks[i].removeCue(cue);
        }
      }
  
      this.cues_.push(cue);
      this.cues.setCues_(this.cues_);
    };
  
    /**
     * Remove a cue from our internal list
     *
     * @param {TextTrack~Cue} removeCue
     *        The cue to remove from our internal list
     */
  
  
    TextTrack.prototype.removeCue = function removeCue(_removeCue) {
      var i = this.cues_.length;
  
      while (i--) {
        var cue = this.cues_[i];
  
        if (cue === _removeCue || cue.originalCue_ && cue.originalCue_ === _removeCue) {
          this.cues_.splice(i, 1);
          this.cues.setCues_(this.cues_);
          break;
        }
      }
    };
  
    return TextTrack;
  }(_track2['default']);
  
  /**
   * cuechange - One or more cues in the track have become active or stopped being active.
   */
  
  
  TextTrack.prototype.allowedEvents_ = {
    cuechange: 'cuechange'
  };
  
  exports['default'] = TextTrack;
  