/**
 * @Datei time-ranges.js
 * @Modul Zeitspannen
 * /
import window from 'global/window';

/**
 * Gibt die Zeit für den angegebenen Index am Anfang oder Ende zurück
 * eines TimeRange-Objekts.
 *
 * @typedef {Funktion} ZeitBereichIndex
 *
 * @param {Nummer} [index=0]
 *             Die Nummer des Bereichs, für den die Zeit zurückgegeben werden soll.
 *
 * @return {number}
 *             Der Zeitversatz am angegebenen Index.
 *
 * @deprecated Das Argument index muss angegeben werden.
 *             In Zukunft wird das Weglassen dieser Angabe zu einem Fehler führen.
 * /

/**
 * Ein Objekt, das Zeitspannen enthält.
 *
 * @typedef {Object} TimeRange
 *
 * @Eigenschaft {Zahl} Länge
 *           Die Anzahl der Zeitbereiche, die durch dieses Objekt dargestellt werden.
 *
 * @property {module:time-ranges~TimeRangeIndex} start
 *           Gibt den Zeitversatz zurück, mit dem ein bestimmter Zeitbereich beginnt.
 *
 * @property {module:time-ranges~TimeRangeIndex} end
 *           Gibt den Zeitversatz zurück, an dem ein bestimmter Zeitbereich endet.
 *
 * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges
 * /

/**
 * Prüfen Sie, ob einer der Zeitbereiche über dem maximalen Index liegt.
 *
 * @privat
 * @param {string} fnName
 *          Der Name der Funktion, die für die Protokollierung verwendet werden soll
 *
 * @param {Nummer} index
 *          Der zu prüfende Index
 *
 * @param {Zahl} maxIndex
 *          Der maximal mögliche Index
 *
 * @Wirft {Fehler}, wenn die angegebenen Zeitspannen über dem maxIndex liegen
 * /
function rangeCheck(fnName, index, maxIndex) {
  if (typeof index !== 'Zahl' || index < 0 || index > maxIndex) {
    throw new Error(`Failed to execute '${fnName}' on 'TimeRanges': Der angegebene Index (${index}) ist nicht numerisch oder außerhalb des zulässigen Bereichs (0-${maxIndex}).`);
  }
}

/**
 * Abrufen der Zeit für den angegebenen Index am Anfang oder Ende
 * eines TimeRange-Objekts.
 *
 * @privat
 * @param {string} fnName
 *             Der Name der Funktion, die für die Protokollierung verwendet werden soll
 *
 * @param {string} valueIndex
 *             Die Eigenschaft, die verwendet werden sollte, um die Zeit zu erhalten. sollte sein
 *             anfang" oder "Ende
 *
 * @param {Array} ranges
 *             Eine Reihe von Zeitbereichen
 *
 * @param {Array} [rangeIndex=0]
 *             Der Index, bei dem die Suche beginnen soll
 *
 * @return {number}
 *             Die Zeit, die bei dem angegebenen Index verschoben wurde.
 *
 * @deprecated rangeIndex muss auf einen Wert gesetzt werden, in Zukunft wird dies einen Fehler auslösen.
 * @Wirft {Fehler}, wenn rangeIndex größer ist als die Länge der Bereiche
 * /
function getRange(fnName, valueIndex, ranges, rangeIndex) {
  rangeCheck(fnName, rangeIndex, ranges.length - 1);
  return ranges[rangeIndex][valueIndex];
}

/**
 * Erstellen Sie ein Zeitbereichsobjekt mit bestimmten Zeitbereichen.
 *
 * @privat
 * @param {Array} [Bereiche]
 *          Ein Array von Zeitbereichen.
 * /
function createTimeRangesObj(ranges) {
  let timeRangesObj;

  if (ranges === undefined || ranges.length === 0) {
    timeRangesObj = {
      länge: 0,
      start() {
        throw new Error('Dieses TimeRanges-Objekt ist leer');
      },
      end() {
        throw new Error('Dieses TimeRanges-Objekt ist leer');
      }
    };
  } else {
    timeRangesObj = {
      länge: ranges.length,
      start: getRange.bind(null, 'start', 0, ranges),
      ende: getRange.bind(null, 'Ende', 1, Bereiche)
    };
  }

  if (window.Symbol && window.Symbol.iterator) {
    timeRangesObj[window.Symbol.iterator] = () => (ranges || []).values();
  }

  return timeRangesObj;
}

/**
 * Erstellen Sie ein "TimeRange"-Objekt, das ein "TimeRange"-Objekt imitiert
 * {@link https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges|HTML5 TimeRanges instance}.
 *
 * @param {Zahl|Array[]} start
 *        Der Beginn eines einzelnen Bereichs (eine Zahl) oder einer Reihe von Bereichen (eine
 *        array von Arrays mit jeweils zwei Zahlen).
 *
 * @param {Nummer} end
 *        Das Ende eines einzelnen Bereichs. Kann nicht mit der Array-Form von
 *        das Argument "Start".
 * /
export function createTimeRanges(start, end) {
  if (Array.isArray(start)) {
    return createTimeRangesObj(start);
  } else if (start === undefined || end === undefined) {
    return createTimeRangesObj();
  }
  return createTimeRangesObj([[start, end]]);
}

exportieren { createTimeRanges as createTimeRange };