const util = require('util');
const EventEmitter = require('events').EventEmitter;
require('linqjs');
let Player = require('./clsPlayer').clsPlayer;
let _ = require('lodash');
let rootPath = process.cwd();
let path = require('path');
let moment = require('moment');
const masterMixer = class masterMixer {
  constructor({ moment, utils, config } = {}) {

    this.moment = moment;
    this.utils = utils;
    this.config = config;

    this.playerEvents = {
      stateChanged: 'stateChanged',
      positionChange: 'positionChange',
      fileChanged: 'fileChanged',
      playlistFinished: 'playlistFinished',
      fadeInStarted: 'fadeInStarted',
      fadeOutStarted: 'fadeOutStarted',
      vumeter: 'vumeter',
      Error: 'error'
    };

    let mMixer = new Player();

    this._mMixer = mMixer;

    console.log('------------------------------------------------');
    console.log('         sound cards:');
    this._mMixer.getDevices().forEach((c) => {
      if (c != null) console.log(`${c.index}-${c.name} ${c.IsDefault ? '(default)' : ''}, active:${c.enabled}`);
    });
    console.log('------------------------------------------------');

    mMixer.initSoundCard(this.config.Settings.soundCard, mMixer.basslib.BASS_DEVICE_SPEAKERS);

    //get multi output settings from config

    //default settings
    let mixerFlags = mMixer.bassAttributes.BASS_SAMPLE_FLOAT;
    let speaker = mMixer.bassAttributes.BASS_SAMPLE_DEFAULT;
    let channelCount = 2;
    this.addChannelFlags = mMixer.bassAttributes.BASS_STREAM_DECODE;
    //check config  mono out and which channel
    if (this.config.MultiOutput.isEnabled) {
      switch(parseInt(this.config.MultiOutput.Channel)) {
        case 1:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_FRONT;
          break;
        case 2:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_REAR;
          break;
        case 3:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_CENLFE;
          channelCount = 1;
          break;
        case 4:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_REAR2;
          break;
        case 5:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_LEFT;
          channelCount = 1;
          this.addChannelFlags = mMixer.mixerAttributes.BASS_MIXER_DOWNMIX | mMixer.bassAttributes.BASS_STREAM_DECODE;
          break;
        case 6:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_RIGHT;
          channelCount = 1;
          this.addChannelFlags = mMixer.mixerAttributes.BASS_MIXER_DOWNMIX | mMixer.bassAttributes.BASS_STREAM_DECODE;
          break;
        case 7:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_FRONTLEFT;
          channelCount = 1;
          this.addChannelFlags = mMixer.mixerAttributes.BASS_MIXER_DOWNMIX | mMixer.bassAttributes.BASS_STREAM_DECODE;
          break;
        case 8:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_FRONTRIGHT;
          channelCount = 1;
          this.addChannelFlags = mMixer.mixerAttributes.BASS_MIXER_DOWNMIX | mMixer.bassAttributes.BASS_STREAM_DECODE;
          break;
        case 9:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_REARLEFT;
          channelCount = 1;
          this.addChannelFlags = mMixer.mixerAttributes.BASS_MIXER_DOWNMIX | mMixer.bassAttributes.BASS_STREAM_DECODE;
          break;
        case 10:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_REARRIGHT;
          channelCount = 1;
          this.addChannelFlags = mMixer.mixerAttributes.BASS_MIXER_DOWNMIX | mMixer.bassAttributes.BASS_STREAM_DECODE;
          break;
        case 11:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_CENTER;
          channelCount = 1;
          this.addChannelFlags = mMixer.mixerAttributes.BASS_MIXER_DOWNMIX | mMixer.bassAttributes.BASS_STREAM_DECODE;
          break;
        case 12:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_LFE;
          channelCount = 1;
          this.addChannelFlags = mMixer.mixerAttributes.BASS_MIXER_DOWNMIX | mMixer.bassAttributes.BASS_STREAM_DECODE;
          break;
        case 13:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_REAR2LEFT;
          channelCount = 1;
          this.addChannelFlags = mMixer.mixerAttributes.BASS_MIXER_DOWNMIX | mMixer.bassAttributes.BASS_STREAM_DECODE;
          break;
        case 14:
          speaker = mMixer.speakerAttributes.BASS_SPEAKER_REAR2RIGHT;
          channelCount = 1;
          this.addChannelFlags = mMixer.mixerAttributes.BASS_MIXER_DOWNMIX | mMixer.bassAttributes.BASS_STREAM_DECODE;
          break;
        default:
          channelCount = 2;
          break;
      }
    }

    //create the mixer
    let mixer = mMixer.createMixer(channelCount, speaker);
    this.mixer = mixer;
    mMixer.setVolume(mixer, 100);
    mMixer.PlayMixer();
    setInterval(() => {
      let vu = mMixer.getVumeter(mixer);
      //console.log(`vumeter left:${vu.left} right:${vu.right}`)
      this.emit(this.playerEvents.vumeter, vu.left, vu.right);
    }, 250);
  }

  addChannelToMixer(channelToAdd) {
    let result = this._mMixer.addChannelToMixer(channelToAdd, this.addChannelFlags);
    let err = this._mMixer.getError();
    return result;
  }

  setVolume(channel, newVolume) {
    this._mMixer.setVolume(channel, newVolume);
  }

  setFadeOutForAnnounces(channel, fadeDur) {
    this._mMixer.setFadeOutForAnnounce(channel, fadeDur);
  }

  setFadeInForAnnounces(channel, fadeDur) {
    this._mMixer.setFadeInForAnnounce(channel, fadeDur);
  }
};

util.inherits(masterMixer, EventEmitter);
module.exports = masterMixer;