/**
 * @file 텍스트-트랙-settings.js
 */
'글로벌/창'에서 창 가져오기;
'../component'에서 컴포넌트 가져오기;
'../modal-dialog'에서 ModalDialog 가져오기;
'../utils/dom'에서 {createEl} 가져오기;
import * as Obj from '../utils/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에 있는 요소입니다.
//
// 가능한 키는 다음과 같습니다.
//
// `기본`:
// 기본 옵션 인덱스. 0이 아닌 경우에만 제공해야 합니다.
// `파서`:
// 선택한 옵션의 값을 구문 분석하는 데 사용되는 함수
// 맞춤형 방식.
// `선택기`:
// 관련 항목을 찾는 데 사용되는 선택기 < 선택하다> 요소.
const 선택 구성 = {
  배경색: {
    선택자: '.vjs-bg-색상 > 선택하다',
    id: '캡션-배경-색상-%s',
    상표: '색상',
    옵션: [
      검정색,
      COLOR_WHITE,
      COLOR_RED,
      색상_녹색,
      파란색,
      COLOR_YELLOW,
      COLOR_MAGENTA,
      COLOR_CYAN
    ]
  },

  배경 불투명도: {
    선택기: '.vjs-bg-opacity > 선택하다',
    id: '캡션-배경-불투명도-%s',
    상표: '투명도',
    옵션: [
      불투명도_불투명,
      불투명도_SEMI,
      불투명도_트랜스
    ]
  },

  색상: {
    선택기: '.vjs-fg-color > 선택하다',
    id: '캡션-전경-색상-%s',
    상표: '색상',
    옵션: [
      COLOR_WHITE,
      검정색,
      COLOR_RED,
      색상_녹색,
      파란색,
      COLOR_YELLOW,
      COLOR_MAGENTA,
      COLOR_CYAN
    ]
  },

  에지 스타일: {
    선택기: '.vjs-edge-style > 선택하다',
    아이디: '%s',
    상표: '텍스트 가장자리 스타일',
    옵션: [
      ['없음', '없음'],
      ['제기', '제기'],
      ['우울하다', '우울하다'],
      ['유니폼', '유니폼'],
      ['그림자', '그림자']
    ]
  },

  글꼴 패밀리: {
    선택기: '.vjs-글꼴-가족 > 선택하다',
    id: 'captions-font-family-%s',
    상표: '폰트 패밀리',
    옵션: [
      ['비례 산세리프', '비례 산세리프'],
      ['모노스페이스 산세리프', '모노스페이스 산세리프'],
      ['비례 세리프', '비례 세리프'],
      ['모노스페이스 세리프', '고정스페이스 세리프'],
      ['캐주얼', '캐주얼'],
      ['스크립트', '스크립트'],
      ['작은 대문자', '작은 대문자']
    ]
  },

  글꼴 퍼센트: {
    선택기: '.vjs-글꼴-퍼센트 > 선택하다',
    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-텍스트-불투명도 > 선택하다',
    id: '캡션-전경-불투명도-%s',
    상표: '투명도',
    옵션: [
      불투명도_불투명,
      불투명도_SEMI
    ]
  },

  // 이 객체에 대한 옵션은 아래에 정의되어 있습니다.
  창색: {
    선택기: '.vjs-window-color > 선택하다',
    id: '캡션-창-색상-%s',
    상표: '색상'
  },

  // 이 객체에 대한 옵션은 아래에 정의되어 있습니다.
  창 불투명도: {
    선택기: '.vjs-window-opacity > 선택하다',
    id: '캡션-창-불투명도-%s',
    상표: '투명도',
    옵션: [
      불투명도_트랜스,
      불투명도_SEMI,
      불투명도_불투명
    ]
  }
};

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

/**
 * 옵션의 실제 가치를 얻으십시오.
 *
 * @param {문자열} 값
 * 얻을 값
 *
 * @param {함수} [파서]
 * 값을 조정하는 옵션 기능.
 *
 * @return {혼합}
 * - 값이 존재하지 않으면 `정의되지 않음`이 됩니다.
 * - 주어진 값이 "없음"이면 `정의되지 않음`이 됩니다.
 * - 그렇지 않으면 실제 값이 됩니다.
 *
 * @사적인
 */
함수 parseOptionValue(값, 파서) {
  if (파서) {
    값 = 파서(값);
  }

  만약 (가치 && 값 !== '없음') {
    반환 값;
  }
}

/**
 * 선택한 항목의 값을 가져옵니다. < 옵션> 내의 요소 < 선택하다> 요소.
 *
 * @param {요소} 엘
 * 살펴볼 요소
 *
 * @param {함수} [파서]
 * 값을 조정하는 옵션 기능.
 *
 * @return {혼합}
 * - 값이 존재하지 않으면 `정의되지 않음`이 됩니다.
 * - 주어진 값이 "없음"이면 `정의되지 않음`이 됩니다.
 * - 그렇지 않으면 실제 값이 됩니다.
 *
 * @사적인
 */
function getSelectedOptionValue(엘, 파서) {
  const 값 = el.options[el.options.selectedIndex].value;

  return parseOptionValue(값, 파서);
}

/**
 * 선택한 설정 < 옵션> 내의 요소 < 선택하다> 를 기반으로 하는 요소
 * 주어진 값.
 *
 * @param {요소} 엘
 * 조회할 요소입니다.
 *
 * @param {문자열} 값
 * 살펴볼 속성.
 *
 * @param {함수} [파서]
 * 비교하기 전에 값을 조정하는 옵션 기능.
 *
 * @사적인
 */
함수 setSelectedOption(el, 값, 파서) {
  if(!값) {
    반품;
  }

  에 대한 (하자 i = 0; i < el.options.length; i++) {
    if (parseOptionValue(el.options[i].value, parser) === 값) {
      el.selectedIndex = i;
      부서지다;
    }
  }
}

/**
 * 텍스트 트랙 설정을 조작합니다.
 *
 * @extends ModalDialog
 */
클래스 TextTrackSettings 확장 ModalDialog {

  /**
   * 이 클래스의 인스턴스를 만듭니다.
   *
   * @param {플레이어} 플레이어
   * 이 클래스가 연결되어야 하는 `Player`.
   *
   * @param {객체} [옵션]
   * 플레이어 옵션의 키/값 저장소.
   */
  생성자(플레이어, 옵션) {
    options.temporary = 거짓;

    super(플레이어, 옵션);
    this.updateDisplay = this.updateDisplay.bind(이);

    // 모달을 채우고 연 척
    this.fill();
    this.hasBeenOpened_ = this.hasBeenFilled_ = 참;

    this.endDialog = createEl('p', {
      className: 'vjs-control-text',
      textContent: this.localize('대화창 종료.')
    });
    this.el().appendChild(this.endDialog);

    this.setDefaults();

    // 하위 옵션에 전달되지 않은 경우 플레이어 옵션에서 `persistTextTrackSettings`를 가져옵니다.
    if (options.persistTextTrackSettings === 정의되지 않음) {
      this.options_.persistTextTrackSettings = this.options_.playerOptions.persistTextTrackSettings;
    }

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

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

    Obj.each(selectConfigs, 구성 => {
      this.on(this.$(config.selector), '변경', this.updateDisplay);
    });

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

  폐기() {
    this.endDialog = null;

    super.dispose();
  }

  /**
   * 만들기 < 선택하다> 구성된 옵션이 있는 요소.
   *
   * @param {문자열} 키
   * 생성 중에 사용할 구성 키입니다.
   *
   * @return {문자열}
   * HTML 문자열.
   *
   * @사적인
   */
  createElSelect_(key, legendId = '', type = 'label') {
    const config = selectConfigs[키];
    const id = config.id.replace('%s', this.id_);
    const selectLabeledbyIds = [legendId, id].join(' ').trim();

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

        반품 [
          `< 옵션 id="${optionId}" 값="${o[0]}" `,
          `aria-labelledby="${selectLabbelledbyIds} ${optionId}"> `,
          this.localize(o[1]),
          '< /옵션> '
        ].가입하다('');
      })).
      연결('< /선택하다> ').가입하다('');
  }

  /**
   * 컴포넌트의 전경색 요소 생성
   *
   * @return {문자열}
   * HTML 문자열.
   *
   * @사적인
   */
  createElFgColor_() {
    const legendId = `captions-text-legend-${this.id_}`;

    반품 [
      '< 필드셋 클래스="vjs-fg-color vjs-track-setting"> ',
      `< 범례 id="${legendId}"> `,
      this.localize('텍스트'),
      '< /전설> ',
      this.createElSelect_('색상', legendId),
      '< 스팬 클래스="vjs-텍스트-불투명도 vjs-불투명도"> ',
      this.createElSelect_('textOpacity', legendId),
      '< /기간> ',
      '< /fieldset> '
    ].가입하다('');
  }

  /**
   * 컴포넌트의 배경색 요소 생성
   *
   * @return {문자열}
   * HTML 문자열.
   *
   * @사적인
   */
  createElBgColor_() {
    const legendId = `captions-background-${this.id_}`;

    반품 [
      '< fieldset class="vjs-bg-color vjs-track-setting"> ',
      `< 범례 id="${legendId}"> `,
      this.localize('배경'),
      '< /전설> ',
      this.createElSelect_('backgroundColor', legendId),
      '< 스팬 클래스="vjs-bg-불투명도 vjs-불투명도"> ',
      this.createElSelect_('backgroundOpacity', legendId),
      '< /기간> ',
      '< /fieldset> '
    ].가입하다('');
  }

  /**
   * 구성 요소에 대한 창 색상 요소 만들기
   *
   * @return {문자열}
   * HTML 문자열.
   *
   * @사적인
   */
  createElWinColor_() {
    const legendId = `captions-window-${this.id_}`;

    반품 [
      '< fieldset 클래스="vjs-window-color vjs-track-setting"> ',
      `< 범례 id="${legendId}"> `,
      this.localize('창'),
      '< /전설> ',
      this.createElSelect_('windowColor', legendId),
      '< 스팬 클래스="vjs-window-opacity vjs-opacity"> ',
      this.createElSelect_('windowOpacity', legendId),
      '< /기간> ',
      '< /fieldset> '
    ].가입하다('');
  }

  /**
   * 컴포넌트의 색상 요소 생성
   *
   * @return {요소}
   * 생성된 요소
   *
   * @사적인
   */
  createElColors_() {
    return createEl('div', {
      className: 'vjs-track-settings-colors',
      innerHTML: [
        this.createElFgColor_(),
        this.createElBgColor_(),
        this.createElWinColor_()
      ].가입하다('')
    });
  }

  /**
   * 구성 요소의 글꼴 요소 만들기
   *
   * @return {요소}
   * 생성된 요소입니다.
   *
   * @사적인
   */
  createElFont_() {
    return createEl('div', {
      className: 'vjs-track-settings-font',
      innerHTML: [
        '< fieldset 클래스="vjs-글꼴-퍼센트 vjs-트랙-설정"> ',
        this.createElSelect_('fontPercent', '', '범례'),
        '< /fieldset> ',
        '< 필드셋 클래스="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('모든 설정을 기본값으로 복원');

    return createEl('div', {
      className: 'vjs-track-settings-controls',
      innerHTML: [
        `< 버튼 유형="버튼" class="vjs-default-button" 제목="${defaultsDescription}"> `,
        this.localize('재설정'),
        `< 스팬 클래스="vjs-제어-텍스트"> ${defaults설명}< /기간> `,
        '< /단추> ',
        `< 버튼 유형="버튼" 클래스="vjs-완료-버튼"> ${this.localize('완료')}< /단추> `
      ].가입하다('')
    });
  }

  콘텐츠() {
    반품 [
      this.createElColors_(),
      this.createElFont_(),
      this.createElControls_()
    ];
  }

  라벨() {
    return this.localize('캡션 설정 대화 상자');
  }

  설명() {
    return this.localize('대화창 시작. 탈출은 취소하고 창을 닫습니다.');
  }

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

  /**
   * 텍스트 트랙 설정(또는 null)의 개체를 가져옵니다.
   *
   * @return {객체}
   * DOM 또는 localStorage에서 구문 분석된 구성 값이 있는 개체입니다.
   */
  getValues() {
    반환 Obj.reduce(selectConfigs, (accum, config, key) => {
      const 값 = getSelectedOptionValue(this.$(config.selector), config.parser);

      if (값 !== 정의되지 않음) {
        누적[키] = 값;
      }

      누적 반환;
    }, {});
  }

  /**
   * 값의 개체에서 텍스트 트랙 설정을 설정합니다.
   *
   * @param {객체} 값
   * DOM 또는 localStorage에서 구문 분석된 구성 값이 있는 개체입니다.
   */
  setValues(값) {
    Obj.each(selectConfigs, (구성, 키) => {
      setSelectedOption(this.$(config.selector), values[key], config.parser);
    });
  }

  /**
   * 모두 설정 `< 선택하다> ` 요소를 기본값으로 설정합니다.
   */
  setDefaults() {
    Obj.each(selectConfigs, (구성) => {
      const 인덱스 = config.hasOwnProperty('default') ? config.default : 0;

      this.$(config.selector).selectedIndex = 인덱스;
    });
  }

  /**
   * localStorage에서 텍스트 트랙 설정 복원
   */
  복원 설정() {
    let 값;

    {
      values = JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_KEY));
    } 잡기(오류) {
      log.warn(err);
    }

    if (값) {
      this.setValues(값);
    }
  }

  /**
   * 텍스트 트랙 설정을 localStorage에 저장
   */
  saveSettings() {
    if (!this.options_.persistTextTrackSettings) {
      반품;
    }

    const values = this.getValues();

    {
      if (객체.키(값).길이) {
        window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(값));
      } else {
        window.localStorage.removeItem(LOCAL_STORAGE_KEY);
      }
    } 잡기(오류) {
      log.warn(err);
    }
  }

  /**
   * 텍스트 트랙 설정 표시 업데이트
   */
  업데이트디스플레이() {
    const ttDisplay = this.player_.getChild('textTrackDisplay');

    경우 (tt디스플레이) {
      ttDisplay.updateDisplay();
    }
  }

  /**
   * 조건부로 요소를 흐리게 처리하고 캡션 버튼의 초점을 다시 맞춥니다.
   *
   * @사적인
   */
  conditionalBlur_() {
    this.previousActiveEl_ = 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 내보내기;