/**
 * @file text-track-settings.js
 */
從“全局/窗口”導入窗口;
從 '../component' 導入組件;
從 '../modal-dialog' 導入 ModalDialog;
從'../utils/dom'導入{createEl};
從 '../utils/obj' 導入 * 作為 Obj;
從 '../utils/log' 導入日誌;

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

const COLOR_BLACK = ['#000', '黑色'];
const COLOR_BLUE = ['#00F', '藍色'];
const COLOR_CYAN = ['#0FF', '青色'];
const COLOR_GREEN = ['#0F0', '綠色'];
const COLOR_MAGENTA = ['#F0F', '洋紅色'];
const COLOR_RED = ['#F00', '紅色'];
const COLOR_WHITE = ['#FFF', '白色'];
const COLOR_YELLOW = ['#FF0', '黃色'];

const OPACITY_OPAQUE = ['1', '不透明'];
const OPACITY_SEMI = ['0.5', '半透明'];
const OPACITY_TRANS = ['0', '透明'];

// 該組件 DOM 中各種 <select> 元素的配置。
//
// 可能的鍵包括:
//
// `默認`:
// 默認選項索引。如果不為零,則只需要提供。
// `解析器`:
// 一個函數,用於解析所選選項中的值
// 自定義方式。
// `選擇器`:
// 用於查找關聯的 <select> 元素的選擇器。
const selectConfigs = {
  背景顏色: {
    選擇器:'.vjs-bg-color > 選擇',
    id: '字幕-背景顏色-%s',
    標籤:'顏色',
    選項: [
      顏色:黑色,
      白顏色,
      紅色,
      顏色_綠色,
      顏色_藍色,
      顏色_黃色,
      COLOR_MAGENTA,
      顏色_青色
    ]
  },

  背景不透明度:{
    選擇器:'.vjs-bg-opacity > 選擇',
    id: '字幕-背景-不透明度-%s',
    標籤:'透明度',
    選項: [
      不透明不透明,
      OPACITY_SEMI,
      OPACITY_TRANS
    ]
  },

  顏色: {
    選擇器:'.vjs-fg-color > 選擇',
    id: '字幕-前景色-%s',
    標籤:'顏色',
    選項: [
      白顏色,
      顏色:黑色,
      紅色,
      顏色_綠色,
      顏色_藍色,
      顏色_黃色,
      COLOR_MAGENTA,
      顏色_青色
    ]
  },

  邊緣樣式:{
    選擇器:'.vjs-edge-style > 選擇',
    編號:“%s”,
    標籤:'文本邊緣樣式',
    選項: [
      ['無', '無'],
      ['提高', '提高'],
      ['沮喪', '沮喪'],
      ['制服', '制服'],
      ['陰影', '陰影']
    ]
  },

  字體系列: {
    選擇器:'.vjs-font-family > 選擇',
    id: '字幕-字體系列-%s',
    標籤:'字體系列',
    選項: [
      ['proportionalSansSerif', 'Proportional Sans-Serif'],
      ['monospaceSansSerif', 'Monospace Sans-Serif'],
      ['proportionalSerif', 'Proportional Serif'],
      ['monospaceSerif', 'Monospace Serif'],
      ['休閒', '休閒'],
      ['腳本', '腳本'],
      ['小型大寫字母','小型大寫字母']
    ]
  },

  字體百分比:{
    選擇器:'.vjs-font-percent > 選擇',
    id: '字幕-字體大小-%s',
    標籤:'字體大小',
    選項: [
      ['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%']
    ]、
    默認:2、
    解析器:(v)=> v === '1.00'?空:數(v)
  },

  文本不透明度:{
    選擇器:'.vjs-text-opacity > 選擇',
    id: '字幕-前景-不透明度-%s',
    標籤:'透明度',
    選項: [
      不透明不透明,
      OPACITY_SEMI
    ]
  },

  // 此對象的選項定義如下。
  窗口顏色:{
    選擇器:'.vjs-window-color > 選擇',
    id: '字幕窗口顏色-%s',
    標籤:'顏色'
  },

  // 此對象的選項定義如下。
  窗口透明度:{
    選擇器:'.vjs-window-opacity > 選擇',
    id: '字幕-窗口-不透明度-%s',
    標籤:'透明度',
    選項: [
      OPACITY_TRANS,
      OPACITY_SEMI,
      不透明_不透明
    ]
  }
};

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

/**
 * 獲取期權的實際價值。
 *
 * @param {string} 值
 * 獲得的價值
 *
 * @param {函數} [解析器]
 * 調整值的可選功能。
 *
 * @return {混合}
 * - 如果不存在任何值,則為 `undefined`
 * - 如果給定值為“無”,則為“未定義”。
 * - 否則將是實際值。
 *
 * @私人的
 */
函數 parseOptionValue(值,解析器){
  如果(解析器){
    值=解析器(值);
  }

  如果(價值&&價值!=='無'){
    返回值;
  }
}

/**
 * 獲取 <select> 元素中選定的 <option> 元素的值。
 *
 * @param {元素} el
 * 要查看的元素
 *
 * @param {函數} [解析器]
 * 調整值的可選功能。
 *
 * @return {混合}
 * - 如果不存在任何值,則為 `undefined`
 * - 如果給定值為“無”,則為“未定義”。
 * - 否則將是實際值。
 *
 * @私人的
 */
函數 getSelectedOptionValue(el,解析器){
  const value = el.options[el.options.selectedIndex].value;

  返回 parseOptionValue(值,解析器);
}

/**
 * 在一個基於 <select> 元素的 <option> 元素中設置被選擇的 <option> 元素
 * 給定值。
 *
 * @param {元素} el
 * 要查看的元素。
 *
 * @param {string} 值
 * 要查看的屬性。
 *
 * @param {函數} [解析器]
 * 比較前調整值的可選功能。
 *
 * @私人的
 */
函數 setSelectedOption(el,值,解析器){
  如果(!值){
    返回;
  }

  對於(讓我 = 0; 我是 < 選項。長度; 我 ++){
    如果 (parseOptionValue(el.options[i].value, parser) === value) {
      el.selectedIndex = i;
      休息;
    }
  }
}

/**
 * 操縱文本軌道設置。
 *
 * @extends 模態對話框
 */
類 TextTrackSettings 擴展 ModalDialog {

  /**
   * 創建此類的一個實例。
   *
   * @param {Player} 播放器
   * 此類應附加到的 `Player`。
   *
   * @param {對象} [選項]
   * 播放器選項的鍵/值存儲。
   */
  構造函數(播放器,選項){
    options.temporary = false;

    超級(播放器,選項);
    this.updateDisplay = this.updateDisplay.bind(this);

    // 填充模式並假裝我們已經打開它
    這個.填充();
    this.hasBeenOpened_ = this.hasBeenFilled_ = true;

    this.endDialog = createEl('p', {
      className: 'vjs-control-text',
      textContent: this.localize('對話框窗口結束。')
    });
    this.el().appendChild(this.endDialog);

    this.setDefaults();

    // 如果沒有傳入子選項,則從播放器選項中獲取 `persistTextTrackSettings`
    如果(選項。persistTextTrackSettings ===未定義){
      this.options_.persistTextTrackSettings = this.options_.playerOptions.persistTextTrackSettings;
    }

    this.on(this.$('.vjs-done-button'), 'click', () => {
      這個.saveSettings();
      這個。關閉();
    });

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

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

    如果(this.options_.persistTextTrackSettings){
      這個.restoreSettings();
    }
  }

  處置(){
    this.endDialog = null;

    super.dispose();
  }

  /**
   * 創建一個帶有配置選項的 <select> 元素。
   *
   * @param {string} 鍵
   * 創建期間使用的配置密鑰。
   *
   * @return {字符串}
   * 一個 HTML 字符串。
   *
   * @私人的
   */
  createElSelect_(key, legendId = '', type = 'label') {
    const config = selectConfigs[key];
    const id = config.id.replace('%s', this.id_);
    const selectLabelledbyIds = [legendId, id].join(' ').trim();

    返回 [
      `  <  $ {類型} ID =「$ {ID}」類 =「$ {類型 === '標籤'?'vj-標籤 ':「}" >`,
      this.localize(config.label),
      `</${type}>`,
      `<select aria-labelledby="${selectLabelledbyIds}">`
    ].
      連接(config.options.map(o => {
        const optionId = id + '-' + o[1].replace(/\\W+/g, '');

        返回 [
          `<option id="${optionId}" value="${o[0]}" `,
          `aria-labelledby="${selectLabelledbyIds} ${optionId}">`,
          this.localize(o[1]),
          '</選項>'
        ]。加入('');
      })).
      concat('</select>').join('');
  }

  /**
   * 為組件創建前景色元素
   *
   * @return {字符串}
   * 一個 HTML 字符串。
   *
   * @私人的
   */
  createElFgColor_() {
    const legendId = `captions-text-legend-${this.id_}`;

    返回 [
      '<fieldset class="vjs-fg-color vjs-track-setting">',
      `<legend id="${legendId}">`,
      this.localize('文本'),
      '</圖例>',
      this.createElSelect_('color', legendId),
      '<span class="vjs-text-opacity vjs-opacity">',
      this.createElSelect_('textOpacity', legendId),
      '</span>',
      '</fieldset>'
    ]。加入('');
  }

  /**
   * 為組件創建背景色元素
   *
   * @return {字符串}
   * 一個 HTML 字符串。
   *
   * @私人的
   */
  createElBgColor_() {
    const legendId = `captions-background-${this.id_}`;

    返回 [
      '<fieldset class="vjs-bg-color vjs-track-setting">',
      `<legend id="${legendId}">`,
      this.localize('背景'),
      '</圖例>',
      this.createElSelect_('backgroundColor', legendId),
      '<span class="vjs-bg-opacity vjs-opacity">',
      this.createElSelect_('backgroundOpacity', legendId),
      '</span>',
      '</fieldset>'
    ]。加入('');
  }

  /**
   * 為組件創建窗口顏色元素
   *
   * @return {字符串}
   * 一個 HTML 字符串。
   *
   * @私人的
   */
  createElWinColor_() {
    const legendId = `captions-window-${this.id_}`;

    返回 [
      '<fieldset class="vjs-window-color vjs-track-setting">',
      `<legend id="${legendId}">`,
      this.localize('窗口'),
      '</圖例>',
      this.createElSelect_('windowColor', legendId),
      '<span class="vjs-window-opacity vjs-opacity">',
      this.createElSelect_('windowOpacity', legendId),
      '</span>',
      '</fieldset>'
    ]。加入('');
  }

  /**
   * 為組件創建顏色元素
   *
   * @return {元素}
   * 創建的元素
   *
   * @私人的
   */
  createElColors_() {
    返回 createEl('div', {
      className: 'vjs-track-settings-colors',
      內部HTML:[
        這個.createElFgColor_(),
        這個.createElBgColor_(),
        this.createElWinColor_()
      ]。加入('')
    });
  }

  /**
   * 為組件創建字體元素
   *
   * @return {元素}
   * 創建的元素。
   *
   * @私人的
   */
  createElFont_() {
    返回 createEl('div', {
      className: 'vjs-track-settings-font',
      內部HTML:[
        '<fieldset class="vjs-font-percent vjs-track-setting">',
        this.createElSelect_('fontPercent', '', 'legend'),
        '</fieldset>',
        '<fieldset class="vjs-edge-style vjs-track-setting">',
        this.createElSelect_('edgeStyle', '', '圖例'),
        '</fieldset>',
        '<fieldset class="vjs-font-family vjs-track-setting">',
        this.createElSelect_('fontFamily', '', '圖例'),
        '</fieldset>'
      ]。加入('')
    });
  }

  /**
   * 為組件創建控件
   *
   * @return {元素}
   * 創建的元素。
   *
   * @私人的
   */
  createElControls_() {
    const defaultsDescription = this.localize('恢復所有設置為默認值');

    返回 createEl('div', {
      className: 'vjs-track-settings-controls',
      內部HTML:[
        `<button type="button" class="vjs-default-button" title="${defaultsDescription}">`,
        this.localize('重置'),
        `<span class="vjs-control-text"> ${defaultsDescription}</span>`,
        '</button>',
        `<button type="button" class="vjs-done-button">${this.localize('Done')}</button>`
      ]。加入('')
    });
  }

  內容() {
    返回 [
      這個.createElColors_(),
      這個.createElFont_(),
      this.createElControls_()
    ];
  }

  標籤() {
    return this.localize('字幕設置對話框');
  }

  描述() {
    return this.localize('對話窗口的開始。Escape 將取消並關閉窗口。');
  }

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

  /**
   * 獲取文本軌道設置對象(或空值)。
   *
   * @return {對象}
   * 具有從 DOM 或 localStorage 解析的配置值的對象。
   */
  getValues() {
    返回 Obj.reduce(selectConfigs, (accum, config, key) => {
      const value = getSelectedOptionValue(this.$(config.selector), config.parser);

      如果(值!==未定義){
        累積 [鍵] = 值;
      }

      返回累積;
    }, {});
  }

  /**
   * 從值對象設置文本軌道設置。
   *
   * @param {Object} 值
   * 具有從 DOM 或 localStorage 解析的配置值的對象。
   */
  設置值(值){
    Obj.each(selectConfigs, (config, key) => {
      setSelectedOption(this.$(config.selector), values[key], config.parser);
    });
  }

  /**
   * 將所有 `<select>` 元素設置為其默認值。
   */
  設置默認值(){
    Obj.each(selectConfigs, (config) => {
      常量索引 = 配置。擁有屬性('默認')?配置. 默認值:0;

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

  /**
   * 從 localStorage 恢復 texttrack 設置
   */
  恢復設置(){
    讓價值觀;

    嘗試{
      values = JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_KEY));
    } 抓住(錯誤){
      日誌警告(錯誤);
    }

    如果(值){
      this.setValues(值);
    }
  }

  /**
   * 將文本軌道設置保存到 localStorage
   */
  保存設置() {
    如果(!this.options_.persistTextTrackSettings){
      返回;
    }

    常量值 = this.getValues();

    嘗試{
      如果(對象.keys(值).length){
        window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values));
      }其他{
        window.localStorage.removeItem(LOCAL_STORAGE_KEY);
      }
    } 抓住(錯誤){
      日誌警告(錯誤);
    }
  }

  /**
   *更新文本軌道設置的顯示
   */
  更新顯示(){
    const ttDisplay = this.player_.getChild('textTrackDisplay');

    如果(ttDisplay){
      ttDisplay.updateDisplay();
    }
  }

  /**
   * 有條件地模糊元素並重新聚焦字幕按鈕
   *
   * @私人的
   */
  條件模糊_() {
    this.previouslyActiveEl_ = null;

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

    如果(subsCapsBtn){
      subsCapsBtn.focus();
    } 否則如果(ccBtn){
      ccBtn.focus();
    }
  }

}

Component.registerComponent('TextTrackSettings', TextTrackSettings);

導出默認的 TextTrackSettings;