# Source: media-groups.js

    import videojs from 'video.js';
    import PlaylistLoader from './playlist-loader';

    /**
     * Convert the properties of an HLS track into an audioTrackKind.
     *
     * @private
     */
    const audioTrackKind_ = (properties) => {
      let kind = properties.default ? 'main' : 'alternative';

      if (properties.characteristics &&
          properties.characteristics.indexOf('public.accessibility.describes-video') >= 0) {
        kind = 'main-desc';
      }

      return kind;
    };

    const setupListeners = {
      /**
       * Setup event listeners for audio playlist loader
       */
      AUDIO: (playlistLoader, masterPlaylistController) => {
        if (!playlistLoader) {
          // no playlist loader means audio will be muxed with the video
          return;
        }

        const segmentLoader = masterPlaylistController.audioSegmentLoader_;
        const tech = masterPlaylistController.tech_;
        const options = masterPlaylistController.requestOptions_;

        playlistLoader.on('loadedmetadata', () => {
          const media = playlistLoader.media();

          segmentLoader.playlist(media, options);

          // if the video is already playing, or if this isn't a live video and preload
          // permits, start downloading segments
          if (!tech.paused() || (media.endList && tech.preload() !== 'none')) {
            segmentLoader.load();
          }
        });

        playlistLoader.on('loadedplaylist', () => {
          segmentLoader.playlist(playlistLoader.media(), options);
        });

        playlistLoader.on('error', () => {
          videojs.log.warn('Problem encountered loading the alternate audio track' +
                             '. Switching back to default.');
          segmentLoader.abort();
        });
      },
      /**
       * Setup event listeners for subtitle playlist loader
       */
      SUBTITLES: (playlistLoader, masterPlaylistController) => {
        const segmentLoader = masterPlaylistController.subtitleSegmentLoader_;
        const tech = masterPlaylistController.tech_;
        const options = masterPlaylistController.requestOptions_;

        playlistLoader.on('loadedmetadata', () => {
          const media = playlistLoader.media();

          segmentLoader.playlist(media, options);
          segmentLoader.track(masterPlaylistController.activeSubtitleTrack_());

          // if the video is already playing, or if this isn't a live video and preload
          // permits, start downloading segments
          if (!tech.paused() || (media.endList && tech.preload() !== 'none')) {
            segmentLoader.load();
          }
        });

        playlistLoader.on('loadedplaylist', () => {
          segmentLoader.playlist(playlistLoader.media(), options);
        });

        playlistLoader.on('error', () => {
          masterPlaylistController.handleSubtitleError_();
        });
      }
    };

    const initialize = {
      /**
       * Setup playlist loaders and tracks for audio groups
       */
      AUDIO: (masterGroups, groups, tracks, masterPlaylistController) => {
        // force a default if we have none or we are not
        // in html5 mode (the only mode to support more than one
        // audio track)
        if (!masterGroups.AUDIO ||
            Object.keys(masterGroups.AUDIO).length === 0 ||
            masterPlaylistController.mode_ !== 'html5') {
          masterGroups.AUDIO = { main: { default: { defualt: true } } };
        }

        for (let masterGroup in masterGroups.AUDIO) {
          if (!groups[masterGroup]) {
            groups[masterGroup] = [];
          }

          for (let label in masterGroups.AUDIO[masterGroup]) {
            let properties = masterGroups.AUDIO[masterGroup][label];
            let playlistLoader;

            if (properties.resolvedUri) {
              playlistLoader = new PlaylistLoader(properties.resolvedUri,
                                                  masterPlaylistController.hls_,
                                                  masterPlaylistController.withCredentials);
            } else {
              // no resolvedUri means the audio is muxed with the video when using this
              // audio track
              playlistLoader = null;
            }

            properties = videojs.mergeOptions({ id: label, playlistLoader }, properties);

            setupListeners.AUDIO(properties.playlistLoader, masterPlaylistController);

            groups[masterGroup].push(properties);

            if (typeof tracks[label] === 'undefined') {
              const track = new videojs.AudioTrack({
                id: label,
                kind: audioTrackKind_(properties),
                enabled: false,
                language: properties.language,
                default: properties.default,
                label
              });

              tracks[label] = track;
            }
          }
        }
      },
      /**
       * Setup playlist loaders and tracks for subtitle groups
       */
      SUBTITLES: (masterGroups, groups, tracks, masterPlaylistController) => {
        for (let masterGroup in masterGroups.SUBTITLES) {
          if (!groups[masterGroup]) {
            groups[masterGroup] = [];
          }

          for (let label in masterGroups.SUBTITLES[masterGroup]) {
            if (masterGroups.SUBTITLES[masterGroup][label].forced) {
              continue;
            }

            let properties = masterGroups.SUBTITLES[masterGroup][label];

            properties = videojs.mergeOptions({
              id: label,
              playlistLoader: new PlaylistLoader(properties.resolvedUri,
                                                 masterPlaylistController.hls_,
                                                 masterPlaylistController.withCredentials)
            }, properties);

            setupListeners.SUBTITLES(properties.playlistLoader, masterPlaylistController);

            groups[masterGroup].push(properties);

            if (typeof tracks[label] === 'undefined') {
              const track = masterPlaylistController.tech_.addRemoteTextTrack({
                id: label,
                kind: 'subtitles',
                enabled: false,
                language: properties.language,
                label
              }, false).track;

              tracks[label] = track;
            }
          }
        }
      },
      /**
       * Setup tracks for closed-caption groups
       */
      'CLOSED-CAPTIONS': (masterGroups, groups, tracks, masterPlaylistController) => {
        for (let masterGroup in masterGroups['CLOSED-CAPTIONS']) {
          if (!groups[masterGroup]) {
            groups[masterGroup] = [];
          }

          for (let label in masterGroups['CLOSED-CAPTIONS'][masterGroup]) {
            let properties = masterGroups['CLOSED-CAPTIONS'][masterGroup][label];

            // We only support CEA608 captions for now, so ignore anything that
            // doesn't use a CCx INSTREAM-ID
            if (properties.instreamId.match(/CC\d/)) {
              continue;
            }

            groups[masterGroup].push(videojs.mergeOptions({ id: label }, properties));

            if (typeof tracks[label] === 'undefined') {
              const track = masterPlaylistController.tech_.addRemoteTextTrack({
                id: properties.instreamId,
                kind: 'captions',
                enabled: false,
                language: properties.language,
                label
              }, false).track;

              tracks[label] = track;
            }
          }
        }
      }
    };

    const initializeMediaGroup = (
      type,
      master,
      mediaGroup,
      masterPlaylistController
    ) => {
      const masterGroups = master.mediaGroups || {};

      return initialize[type](masterGroups,
                              mediaGroup.groups,
                              mediaGroup.tracks,
                              masterPlaylistController);
    };

    export default initializeMediaGroup;