# src/Media.js

    import Context from './Context';
    import Config from './Configure';
    import l from './Logger';
    import util from './Util';
    import RemonRecorder from './RemonRecorder';

    class Media{
      constructor(ctx){
        this.context = ctx;
      }

      bindLocalStreamToPeerConnection(peerConnection) {
        // FIXME: Chrome, adapter does not support addTrack
        if (this.context.hasAddTrack) {
          Config.rtc.localStream.getTracks()
            .forEach(track => peerConnection.addTrack(track, Config.rtc.localStream));
          l.d('Local stream added:', peerConnection.getSenders());
        } else {
          peerConnection.addStream(Config.rtc.localStream);
          l.i('Local stream added:', peerConnection.getLocalStreams());
        }

        if (this.context.eventManager.hasEventListener('onAddLocalStream')) {
          this.context.eventManager.dispatchEvent('onAddLocalStream', Config.rtc.localStream);
        }
      }

      gotDevicesInfo(devices) {
        this.context.devices = devices;
      }

      createLocalStream(ctx,constraints) {

        navigator.mediaDevices.getUserMedia(constraints)
          .then(function(stream){
            if (Config.rtc.localVideo !== null){
              Config.rtc.localVideo.srcObject = stream;
            }

            Config.rtc.localStream = stream;
            ctx.eventManager.dispatchEvent('onDisplayUserMedia', Config.rtc.localStream);
            //Config.rtc.localStream = stream;
            l.i("config stream"+ Config.rtc.localStream);
            if (ctx.useRecord){
              ctx.localRecorder = new RemonRecorder(ctx, stream, "LL");
            }
            return navigator.mediaDevices.enumerateDevices();
          })
          .then(function(devices){
            ctx.devices = devices;
            ctx.currentVideoDeviceId = devices[0].deviceId;
          })
          .catch((error) => {
            if (ctx.eventManager.hasEventListener('onError')) { ctx.eventManager.dispatchEvent('onError', 'UserMediaDeviceFailedError'); }
            l.e(error);
          });

      }

      // gotDevices(deviceInfos) {
      //   // Handles being called several times to update labels. Preserve values.
      //   var values = selectors.map(function(select) {
      //     return select.value;
      //   });
      //   selectors.forEach(function(select) {
      //     while (select.firstChild) {
      //       select.removeChild(select.firstChild);
      //     }
      //   });
      //   for (var i = 0; i !== deviceInfos.length; ++i) {
      //     var deviceInfo = deviceInfos[i];
      //     var option = document.createElement('option');
      //     option.value = deviceInfo.deviceId;
      //     if (deviceInfo.kind === 'audioinput') {
      //       option.text = deviceInfo.label ||
      //           'microphone ' + (audioInputSelect.length + 1);
      //       audioInputSelect.appendChild(option);
      //     } else if (deviceInfo.kind === 'audiooutput') {
      //       option.text = deviceInfo.label || 'speaker ' +
      //           (audioOutputSelect.length + 1);
      //       audioOutputSelect.appendChild(option);
      //     } else if (deviceInfo.kind === 'videoinput') {
      //       option.text = deviceInfo.label || 'camera ' + (videoSelect.length + 1);
      //       videoSelect.appendChild(option);
      //     } else {
      //       console.log('Some other kind of source/device: ', deviceInfo);
      //     }
      //   }
      //   selectors.forEach(function(select, selectorIndex) {
      //     if (Array.prototype.slice.call(select.childNodes).some(function(n) {
      //       return n.value === values[selectorIndex];
      //     })) {
      //       select.value = values[selectorIndex];
      //     }
      //   });
      // }

      bindRemoteStreamToView(event) {
        l.g('Media: Bind remote stream: Bind remote media to video element and regist to context');
        l.d('event:', event);

        let stream;
        // FIXME: Chrome, adapter does not support addTrack
        if (this.context.hasAddTrack) {
          stream = event.streams[0];
        } else {
          stream = event.stream;
        }
        l.d('Stream:', stream);
        this.context.remoteVideo.srcObject = stream;
        this.context.remoteStream = stream;

        l.gEnd();
      }

      mediaStreamTrackSwitch(stream) {
        let getMatchedMediaTypeTracks;

        function type(mediaType) {
          if (mediaType === 'Video' || mediaType === 'Audio') {
            getMatchedMediaTypeTracks = `get${mediaType}Tracks`;
          } else {
            throw new Error('MediaStreamSwitcher:InvailedMediaType');
          }
          return this;
        }

        function enabled(bool) {
          switch (bool) {
            case true: {
              /* eslint-disable no-param-reassign */
              stream[getMatchedMediaTypeTracks]().forEach((track) => { track.enabled = true; });
              /* eslint-disable no-param-reassign */
              break;
            }
            case false: {
              /* eslint-disable no-param-reassign */
              stream[getMatchedMediaTypeTracks]().forEach((track) => { track.enabled = false; });
              /* eslint-disable no-param-reassign */
              break;
            }
            default: {
              throw new Error('MediaStreamSwitcher:InvalidCommand');
            }
          }
        }

        return Object.freeze({
          type,
          enabled,
        });
      }

      setAudioOutput(sinkId) {
        if (!Config.rtc.localVideo){
          Config.rtc.localVideo.setSinkId(sinkId)
            .then(() => {
              l.d('Devices: Audio output device attached success:', sinkId);
            })
            .catch(() => {
              l.e('Devices: Audio output device attached failed:', sinkId);
            });
        }
      }

      setUserDevices({ audioSource, videoSource }) {
        if (window.stream) {
          window.stream.getTracks().forEach(function(track) {
            track.stop();
          });
        }

        const constraints = {
          audio: {deviceId: audioSource ? {exact: audioSource} : undefined},
          video: {deviceId: videoSource ? {exact: videoSource} : undefined}
        };

        createLocalStream(constraints);
      }

    }

    export default Media;