/**
 * @Datei track-list.js
 * /
import EventTarget from '../event-target';
import {isEvented} from '../mixins/evented';

/**
 * Gemeinsame Funktionalitäten zwischen {@link TextTrackList}, {@link AudioTrackList}, und
 * {@link VideoTrackList}
 *
 * @extends EventTarget
 * /
class TrackList extends EventTarget {
  /**
   * Eine Instanz dieser Klasse erstellen
   *
   * @param {Track[]} tracks
   *        Eine Liste von Titeln, mit denen die Liste initialisiert wird.
   *
   * @Abstrakt
   * /
  constructor(tracks = []) {
    super();

    this.tracks_ = [];

    /**
     * @Mitglied von TrackList
     * @Mitglied {Anzahl} Länge
     *         Die aktuelle Anzahl der "Tracks" in dieser Trackliste.
     * @Instanz
     * /
    Object.defineProperty(this, 'length', {
      get() {
        return this.tracks_.length;
      }
    });

    for (let i = 0; i < tracks.length; i++) {
      this.addTrack(tracks[i]);
    }
  }

  /**
   * Hinzufügen eines {@link Track} zur `TrackList`
   *
   * @param {Track} track
   *        Die Audio-, Video- oder Textspur, die der Liste hinzugefügt werden soll.
   *
   * @fires TrackList#addtrack
   * /
  addTrack(track) {
    const index = this.tracks_.length;

    if (!('' + index in this)) {
      Object.defineProperty(this, index, {
        get() {
          return this.tracks_[index];
        }
      });
    }

    // Keine doppelten Spuren hinzufügen
    if (this.tracks_.indexOf(track) === -1) {
      this.tracks_.push(track);
      /**
       * Wird ausgelöst, wenn ein Titel zu einer Titelliste hinzugefügt wird.
       *
       * @event TrackList#addtrack
       * @Typ {EventTarget~Event}
       * @property {Track} track
       *           Ein Verweis auf den Track wurde hinzugefügt.
       * /
      this.trigger({
        titel,
        typ: 'addtrack',
        ziel: dies
      });
    }

    /**
     * Wird ausgelöst, wenn eine Spurbezeichnung geändert wird.
     *
     * @event TrackList#addtrack
     * @Typ {EventTarget~Event}
     * @property {Track} track
     *           Ein Verweis auf den Track wurde hinzugefügt.
     * /
    track.labelchange_ = () => {
      this.trigger({
        titel,
        typ: 'Etikettenwechsel',
        ziel: dies
      });
    };

    if (isEvented(track)) {
      track.addEventListener('labelchange', track.labelchange_);
    }
  }

  /**
   * Entfernen eines {@link Track} aus der `TrackList`
   *
   * @param {Spur} rSpur
   *        Die Audio-, Video- oder Textspur, die aus der Liste entfernt werden soll.
   *
   * @feuer trackList#removetrack
   * /
  removeTrack(rtrack) {
    spuren hinterlassen;

    for (let i = 0, l = this.length; i < l; i++) {
      if (this[i] === rtrack) {
        track = this[i];
        if (track.off) {
          track.off();
        }

        this.tracks_.splice(i, 1);

        pause;
      }
    }

    if (!track) {
      rückkehr;
    }

    /**
     * Wird ausgelöst, wenn ein Titel aus der Titelliste entfernt wird.
     *
     * @event TrackList#removetrack
     * @Typ {EventTarget~Event}
     * @property {Track} track
     *           Ein Verweis auf eine Strecke, die entfernt wurde.
     * /
    this.trigger({
      titel,
      typ: 'removetrack',
      ziel: dies
    });
  }

  /**
   * Abrufen eines Tracks aus der TrackList anhand einer Track-ID
   *
   * @param {string} id - die ID des zu ermittelnden Tracks
   * @Methode getTrackById
   * @return {Track}
   * @privat
   * /
  getTrackById(id) {
    let result = null;

    for (let i = 0, l = this.length; i < l; i++) {
      const track = this[i];

      if (track.id === id) {
        ergebnis = Track;
        pause;
      }
    }

    ergebnis zurückgeben;
  }
}

/**
 * Wird ausgelöst, wenn ein anderer Titel ausgewählt/aktiviert wird.
 *
 * @event TrackList#change
 * @Typ {EventTarget~Event}
 * /

/**
 * Ereignisse, die mit on + eventName aufgerufen werden können. Siehe {@link EventHandler}.
 *
 * @property {Object} TrackList#allowedEvents_
 * @privat
 * /
TrackList.prototype.allowedEvents_ = {
  ändern: 'ändern',
  addtrack: 'addtrack',
  removetrack: 'removetrack',
  labelchange: 'labelchange'
};

// Emulation der Unterstützung für Attribute EventHandler, um die Erkennung von Merkmalen zu ermöglichen
for (const event in TrackList.prototype.allowedEvents_) {
  TrackList.prototype['on' + event] = null;
}

standard TrackList exportieren;