/**
 * @Datei text-track-settings.js
 * /
import window from 'global/window';
importiere Komponente von '../komponente';
import ModalDialog from '../modal-dialog';
importiere {createEl} von '../utils/dom';
import * as Obj from '../utils/obj';
import log from '../utils/log';

const LOCAL_STORAGE_KEY = 'vjs-text-track-settings';

const COLOR_BLACK = ['#000', 'Schwarz'];
const COLOR_BLUE = ['#00F', 'Blau'];
const COLOR_CYAN = ['#0FF', 'Cyan'];
const COLOR_GREEN = ['#0F0', 'Grün'];
const COLOR_MAGENTA = ['#F0F', 'Magenta'];
const COLOR_RED = ['#F00', 'Rot'];
const COLOR_WHITE = ['#FFF', 'Weiß'];
const COLOR_YELLOW = ['#FF0', 'Gelb'];

const OPACITY_OPAQUE = ['1', 'Opaque'];
const OPACITY_SEMI = ['0.5', 'Semi-Transparent'];
const OPACITY_TRANS = ['0', 'Transparent'];

// Konfiguration für die verschiedenen <select> Elemente im DOM dieser Komponente.
// //
// Mögliche Schlüssel sind:
// //
// `default`:
// Der Standardindex der Option. Muss nur angegeben werden, wenn er nicht Null ist.
// `Parser`:
// Eine Funktion, die verwendet wird, um den Wert der ausgewählten Option in
// eine angepasste Weise.
// `Selektor`:
// Der Selektor, der verwendet wird, um das zugehörige Element <select> zu finden.
const selectConfigs = {
  backgroundColor: {
    selector: '.vjs-bg-color > select',
    id: 'Bildunterschriften-Hintergrundfarbe-%s',
    etikett: farbe",
    optionen: [
      COLOR_BLACK,
      COLOR_WHITE,
      FARBE_ROT,
      COLOR_GREEN,
      COLOR_BLUE,
      COLOR_YELLOW,
      COLOR_MAGENTA,
      FARBE_CYAN
    ]
  },

  backgroundOpacity: {
    selector: '.vjs-bg-opacity > select',
    id: 'Bildunterschriften-Hintergrund-Oppazität-%s',
    etikett: transparenz",
    optionen: [
      DECKKRAFT_OPAK,
      OPACITY_SEMI,
      OPACITY_TRANS
    ]
  },

  farbe: {
    selector: '.vjs-fg-color > select',
    id: 'beschriftung-vorgrund-farbe-%s',
    etikett: farbe",
    optionen: [
      COLOR_WHITE,
      COLOR_BLACK,
      FARBE_ROT,
      COLOR_GREEN,
      COLOR_BLUE,
      COLOR_YELLOW,
      COLOR_MAGENTA,
      FARBE_CYAN
    ]
  },

  edgeStyle: {
    selector: '.vjs-edge-style > select',
    id: '%s',
    etikett: textkantenstil",
    optionen: [
      ['keine', 'keine'],
      ['angehoben', 'angehoben'],
      ['deprimiert', 'Deprimiert'],
      ['Uniform', 'Uniform'],
      ['dropshadow', 'Dropshadow']
    ]
  },

  fontFamily: {
    selector: '.vjs-font-family > select',
    id: 'beschriftung-font-familie-%s',
    etikett: schriftfamilie",
    optionen: [
      ['proportionalSansSerif', 'Proportional Sans-Serif'],
      ['monospaceSansSerif', 'Monospace Sans-Serif'],
      ['proportionalSerif', 'Proportional Serif'],
      ['monospaceSerif', 'Monospace Serif'],
      ['lässig', 'lässig'],
      ['Skript', 'Skript'],
      ['small-caps', 'Small Caps']
    ]
  },

  fontPercent: {
    selector: '.vjs-font-percent > select',
    id: 'bildunterschriften-schriftgröße-%s',
    etikett: schriftgröße",
    optionen: [
      ['0.50', '50%'],
      ['0.75', '75%'],
      ['1.00', '100%'],
      ['1.25', '125%'],
      ['1.50', '150%'],
      ['1.75', '175%'],
      ['2.00', '200%'],
      ['3.00', '300%'],
      ['4.00', '400%']
    ],
    standard: 2,
    parser: (v) => v === '1.00' ? null : Zahl(v)
  },

  textOpacity: {
    selector: '.vjs-text-opacity > select',
    id: 'beschriftung-vor-grund-opazität-%s',
    etikett: transparenz",
    optionen: [
      DECKKRAFT_OPAK,
      OPACITY_SEMI
    ]
  },

  // Die Optionen für dieses Objekt sind unten definiert.
  windowColor: {
    selector: '.vjs-window-color > select',
    id: 'Untertitel-Fenster-Farbe-%s',
    etikett: farbe
  },

  // Die Optionen für dieses Objekt sind unten definiert.
  windowOpacity: {
    selector: '.vjs-window-opacity > select',
    id: 'Untertitel-Fenster-Öffnung-%s',
    etikett: transparenz",
    optionen: [
      OPACITY_TRANS,
      OPACITY_SEMI,
      OPACITY_OPAQUE
    ]
  }
};

selectConfigs.windowColor.options = selectConfigs.backgroundColor.options;

/**
 * Ermittelt den aktuellen Wert einer Option.
 *
 * @param {string} Wert
 *         Der zu erhaltende Wert
 *
 * @param {Funktion} [Parser]
 *         Optionale Funktion zur Anpassung des Wertes.
 *
 * @return {Mixed}
 *         - Wird "undefiniert" sein, wenn kein Wert existiert
 *         - Wird "undefiniert" sein, wenn der angegebene Wert "none" ist.
 *         - Andernfalls wird der aktuelle Wert angezeigt.
 *
 * @privat
 * /
function parseOptionValue(value, parser) {
  if (Parser) {
    wert = Parser(Wert);
  }

  if (value && value !== 'none') {
    rückgabewert;
  }
}

/**
 * Ermittelt den Wert des ausgewählten Elements <option> innerhalb eines Elements <select> .
 *
 * @param {Element} el
 *         das zu untersuchende Element
 *
 * @param {Funktion} [Parser]
 *         Optionale Funktion zur Anpassung des Wertes.
 *
 * @return {Mixed}
 *         - Wird "undefiniert" sein, wenn kein Wert existiert
 *         - Wird "undefiniert" sein, wenn der angegebene Wert "none" ist.
 *         - Andernfalls wird der aktuelle Wert angezeigt.
 *
 * @privat
 * /
function getSelectedOptionValue(el, parser) {
  const value = el.options[el.options.selectedIndex].value;

  return parseOptionValue(Wert, Parser);
}

/**
 * Setzt das ausgewählte <option> Element innerhalb eines <select> Elements basierend auf einem
 * gegebenen Wert.
 *
 * @param {Element} el
 *        Das Element, in dem man suchen muss.
 *
 * @param {string} Wert
 *        das Grundstück zu besichtigen.
 *
 * @param {Funktion} [Parser]
 *        Optionale Funktion zur Anpassung des Wertes vor dem Vergleich.
 *
 * @privat
 * /
function setSelectedOption(el, value, parser) {
  if (!Wert) {
    rückkehr;
  }

  for (let i = 0; i < el.options.length; i++) {
    if (parseOptionValue(el.options[i].value, parser) === value) {
      el.selectedIndex = i;
      pause;
    }
  }
}

/**
 * Manipulieren Sie die Einstellungen für Textspuren.
 *
 * @extends ModalDialog
 * /
class TextTrackSettings extends ModalDialog {

  /**
   * Erzeugt eine Instanz dieser Klasse.
   *
   * @param {Player} Spieler
   *         Der `Player`, dem diese Klasse zugeordnet werden soll.
   *
   * @param {Object} [Optionen]
   *         Der Schlüssel/Wertspeicher der Playeroptionen.
   * /
  constructor(spieler, optionen) {
    options.temporary = false;

    super(Spieler, Optionen);
    this.updateDisplay = this.updateDisplay.bind(this);

    // das Modal ausfüllen und so tun, als ob wir es geöffnet hätten
    this.fill();
    this.hasBeenOpened_ = this.hasBeenFilled_ = true;

    this.endDialog = createEl('p', {
      className: 'vjs-control-text',
      textContent: this.localize('Ende des Dialogfensters.')
    });
    this.el().appendChild(this.endDialog);

    this.setDefaults();

    // Entnimmt `persistTextTrackSettings` aus den Player-Optionen, wenn nicht in den Child-Optionen übergeben
    if (options.persistTextTrackSettings === undefined) {
      this.options_.persistTextTrackSettings = this.options_.playerOptions.persistTextTrackSettings;
    }

    this.on(this.$('.vjs-done-button'), 'click', () => {
      this.saveSettings();
      this.close();
    });

    this.on(this.$('.vjs-default-button'), 'click', () => {
      this.setDefaults();
      this.updateDisplay();
    });

    Obj.each(selectConfigs, config => {
      this.on(this.$(config.selector), 'change', this.updateDisplay);
    });

    if (this.options_.persistTextTrackSettings) {
      this.restoreSettings();
    }
  }

  dispose() {
    this.endDialog = null;

    super.dispose();
  }

  /**
   * Erstellen Sie ein <select> Element mit konfigurierten Optionen.
   *
   * @param {string} key
   *        Konfigurationsschlüssel, der bei der Erstellung zu verwenden ist.
   *
   * @return {string}
   *         Eine HTML-Zeichenkette.
   *
   * @privat
   * /
  createElSelect_(key, legendId = '', type = 'label') {
    const config = selectConfigs[key];
    const id = config.id.replace('%s', this.id_);
    const selectLabelledbyIds = [legendId, id].join(' ').trim();

    zurückkehren [
      `<${type} id="${id}" class="${type === 'label' ? 'vjs-label' : ''}">`,
      this.localize(config.label),
      `</${Typ}>`,
      `<select aria-labelledby="${selectLabelledbyIds}">`
    ].
      concat(config.options.map(o => {
        const optionId = id + '-' + o[1].replace(/\W+/g, '');

        zurückkehren [
          `<option id="${optionId}" value="${o[0]}" `,
          `aria-labelledby="${selectLabelledbyIds} ${optionId}">`,
          this.localize(o[1]),
          '</option>'
        ].join('');
      })).
      concat('</select>').join('');
  }

  /**
   * Element für die Vordergrundfarbe der Komponente erstellen
   *
   * @return {string}
   *         Eine HTML-Zeichenkette.
   *
   * @privat
   * /
  createElFgColor_() {
    const legendId = `captions-text-legend-${this.id_}`;

    zurückkehren [
      '<fieldset class="vjs-fg-color vjs-track-setting">',
      `<legend id="${legendId}">`,
      this.localize('Text'),
      '</legend>',
      this.createElSelect_('Farbe', legendId),
      '<span class="vjs-text-opacity vjs-opacity">',
      this.createElSelect_('textOpacity', legendId),
      '</span>',
      '</fieldset>'
    ].join('');
  }

  /**
   * Erstellen Sie ein Element mit Hintergrundfarbe für die Komponente
   *
   * @return {string}
   *         Eine HTML-Zeichenkette.
   *
   * @privat
   * /
  createElBgColor_() {
    const legendId = `captions-background-${this.id_}`;

    zurückkehren [
      '<fieldset class="vjs-bg-color vjs-track-setting">',
      `<legend id="${legendId}">`,
      this.localize('Hintergrund'),
      '</legend>',
      this.createElSelect_('backgroundColor', legendId),
      '<span class="vjs-bg-opacity vjs-opacity">',
      this.createElSelect_('backgroundOpacity', legendId),
      '</span>',
      '</fieldset>'
    ].join('');
  }

  /**
   * Fensterfarbelement für die Komponente erstellen
   *
   * @return {string}
   *         Eine HTML-Zeichenkette.
   *
   * @privat
   * /
  createElWinColor_() {
    const legendId = `captions-window-${this.id_}`;

    zurückkehren [
      '<fieldset class="vjs-window-color vjs-track-setting">',
      `<legend id="${legendId}">`,
      this.localize('Fenster'),
      '</legend>',
      this.createElSelect_('windowColor', legendId),
      '<span class="vjs-window-opacity vjs-opacity">',
      this.createElSelect_('windowOpacity', legendId),
      '</span>',
      '</fieldset>'
    ].join('');
  }

  /**
   * Erstellen Sie Farbelemente für die Komponente
   *
   * @return {Element}
   *         Das Element, das erstellt wurde
   *
   * @privat
   * /
  createElColors_() {
    return createEl('div', {
      className: 'vjs-track-settings-colors',
      innerHTML: [
        this.createElFgColor_(),
        this.createElBgColor_(),
        this.createElWinColor_()
      ].join('')
    });
  }

  /**
   * Erstellen Sie Schriftelemente für die Komponente
   *
   * @return {Element}
   *         Das Element, das erstellt wurde.
   *
   * @privat
   * /
  createElFont_() {
    return createEl('div', {
      className: 'vjs-track-settings-font',
      innerHTML: [
        '<fieldset class="vjs-font-percent vjs-track-setting">',
        this.createElSelect_('fontPercent', '', 'legend'),
        '</fieldset>',
        '<fieldset class="vjs-edge-style vjs-track-setting">',
        this.createElSelect_('edgeStyle', '', 'legend'),
        '</fieldset>',
        '<fieldset class="vjs-font-family vjs-track-setting">',
        this.createElSelect_('fontFamily', '', 'legend'),
        '</fieldset>'
      ].join('')
    });
  }

  /**
   * Erstellen Sie Steuerelemente für die Komponente
   *
   * @return {Element}
   *         Das Element, das erstellt wurde.
   *
   * @privat
   * /
  createElControls_() {
    const defaultsDescription = this.localize('alle Einstellungen auf die Standardwerte zurücksetzen');

    return createEl('div', {
      className: 'vjs-track-settings-controls',
      innerHTML: [
        `<button type="button" class="vjs-default-button" title="${defaultsDescription}">`,
        this.localize('Reset'),
        `<span class="vjs-control-text"> ${defaultsDescription}</span>`,
        '</button>',
        `<button type="button" class="vjs-done-button">${this.localize('Done')}</button>`
      ].join('')
    });
  }

  inhalt() {
    zurückkehren [
      this.createElColors_(),
      this.createElFont_(),
      this.createElControls_()
    ];
  }

  label() {
    return this.localize('Unterschriftseinstellungen Dialog');
  }

  description() {
    return this.localize('Beginn des Dialogfensters. Escape bricht ab und schließt das Fenster.');
  }

  buildCSSClass() {
    return super.buildCSSClass() + ' vjs-text-track-settings';
  }

  /**
   * Ruft ein Objekt mit Textspureinstellungen ab (oder null).
   *
   * @return {Object}
   *         Ein Objekt mit Konfigurationswerten, die aus dem DOM oder localStorage geparst wurden.
   * /
  getValues() {
    return Obj.reduce(selectConfigs, (accum, config, key) => {
      const value = getSelectedOptionValue(this.$(config.selector), config.parser);

      if (Wert !== undefiniert) {
        accum[Schlüssel] = Wert;
      }

      return accum;
    }, {});
  }

  /**
   * Legt die Einstellungen für die Textspur aus einem Objekt mit Werten fest.
   *
   * @param {Object} Werte
   *        Ein Objekt mit Konfigurationswerten, die aus dem DOM oder localStorage geparst wurden.
   * /
  setValues(values) {
    Obj.each(selectConfigs, (config, key) => {
      setSelectedOption(this.$(config.selector), values[key], config.parser);
    });
  }

  /**
   * Setzt alle "<select>"-Elemente auf ihre Standardwerte zurück.
   * /
  setDefaults() {
    Obj.each(selectConfigs, (config) => {
      const index = config.hasOwnProperty('default') ? config.default : 0;

      this.$(config.selector).selectedIndex = index;
    });
  }

  /**
   * Wiederherstellung der Textspureinstellungen aus localStorage
   * /
  restoreSettings() {
    werte zulassen;

    Versuchen {
      werte = JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_KEY));
    } catch (err) {
      log.warn(err);
    }

    if (Werte) {
      this.setValues(values);
    }
  }

  /**
   * Speichern der Einstellungen für die Textspur in localStorage
   * /
  saveSettings() {
    if (!this.options_.persistTextTrackSettings) {
      rückkehr;
    }

    const values = this.getValues();

    Versuchen {
      if (Object.keys(values).length) {
        window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values));
      } else {
        window.localStorage.removeItem(LOCAL_STORAGE_KEY);
      }
    } catch (err) {
      log.warn(err);
    }
  }

  /**
   * Anzeige der Einstellungen für die Textspur aktualisieren
   * /
  updateDisplay() {
    const ttDisplay = this.player_.getChild('textTrackDisplay');

    wenn (ttDisplay) {
      ttDisplay.updateDisplay();
    }
  }

  /**
   * das Element bedingt unscharf machen und die Beschriftungsschaltfläche neu fokussieren
   *
   * @privat
   * /
  conditionalBlur_() {
    this.previouslyActiveEl_ = null;

    const cb = this.player_.controlBar;
    const subsCapsBtn = cb && cb.subsCapsButton;
    const ccBtn = cb && cb.captionsButton;

    wenn (subsCapsBtn) {
      subsCapsBtn.focus();
    } else if (ccBtn) {
      ccBtn.focus();
    }
  }

}

Component.registerComponent('TextTrackSettings', TextTrackSettings);

standard-TextTrackSettings exportieren;