const Player = require('./clsPlayer').clsPlayer;

const pushPlayer = class pushPlayer {
  constructor({ db, utils, config, musicVolume = 100, decodeOnly = false, logger } = {}) {
    this.db = db;
    this.utils = utils;
    this.config = config;
    this.musicVolume = musicVolume;
    this.mixerVolume = musicVolume;
    this.decodeOnly = decodeOnly;
    this.logger = logger;
    this.isPlaying = false;

    this.pushAudioEvents = {
      pushAudioStarted: 'pushAudioStarted',
      pushAudioStopped: 'pushAudioStopped',
    };
    

    let pushPlayer = new Player();
    this._pushPlayer = pushPlayer;
    this.pushUrl = '';
    pushPlayer.initSoundCard(this.config.Settings.soundCard, pushPlayer.basslib.BASS_DEVICE_SPEAKERS);
    let pushFlags = pushPlayer.bassAttributes.BASS_SAMPLE_FLOAT;
    let speaker = pushPlayer.bassAttributes.BASS_SAMPLE_DEFAULT;
    let chanCount = 2;
    this.addChannelFlags = pushPlayer.mixerAttributes.BASS_MIXER_BUFFER;
    //check config mono out and what channel to play

    if (this.config.MultiOutput.isEnabled) {
      switch(parseInt(this.config.MultiOutput.Channel)) {
        case 1:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_FRONT;
          break;
        case 2:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_REAR;
          break;
        case 3:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_CENLFE;
          chanCount = 1;
          break;
        case 4:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_REAR2;
          break;
        case 5:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_LEFT;
          chanCount = 1;
          this.addChannelFlags = pushPlayer.mixerAttributes.BASS_MIXER_DOWNMIX | pushPlayer.mixerAttributes.BASS_MIXER_BUFFER;
          break;
        case 6:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_RIGHT;
          chanCount = 1;
          this.addChannelFlags = pushPlayer.mixerAttributes.BASS_MIXER_DOWNMIX | pushPlayer.mixerAttributes.BASS_MIXER_BUFFER;
          break;
        case 7:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_FRONTLEFT;
          chanCount = 1;
          this.addChannelFlags = pushPlayer.mixerAttributes.BASS_MIXER_DOWNMIX | pushPlayer.mixerAttributes.BASS_MIXER_BUFFER;
          break;
        case 8:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_FRONTRIGHT;
          chanCount = 1;
          this.addChannelFlags = pushPlayer.mixerAttributes.BASS_MIXER_DOWNMIX | pushPlayer.mixerAttributes.BASS_MIXER_BUFFER;
          break;
        case 9:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_REARLEFT;
          chanCount = 1;
          this.addChannelFlags = pushPlayer.mixerAttributes.BASS_MIXER_DOWNMIX | pushPlayer.mixerAttributes.BASS_MIXER_BUFFER;
          break;
        case 10:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_REARRIGHT;
          chanCount = 1;
          this.addChannelFlags = pushPlayer.mixerAttributes.BASS_MIXER_DOWNMIX | pushPlayer.mixerAttributes.BASS_MIXER_BUFFER;
          break;
        case 11:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_CENTER;
          chanCount = 1;
          this.addChannelFlags = pushPlayer.mixerAttributes.BASS_MIXER_DOWNMIX | pushPlayer.mixerAttributes.BASS_MIXER_BUFFER;
          break;
        case 12:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_LFE;
          chanCount = 1;
          this.addChannelFlags = pushPlayer.mixerAttributes.BASS_MIXER_DOWNMIX | pushPlayer.mixerAttributes.BASS_MIXER_BUFFER;
          break;
        case 13:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_REAR2LEFT;
          chanCount = 1;
          this.addChannelFlags = pushPlayer.mixerAttributes.BASS_MIXER_DOWNMIX | pushPlayer.mixerAttributes.BASS_MIXER_BUFFER;
          break;
        case 14:
          speaker = pushPlayer.speakerAttributes.BASS_SPEAKER_REAR2RIGHT;
          chanCount = 1;
          this.addChannelFlags = pushPlayer.mixerAttributes.BASS_MIXER_DOWNMIX | pushPlayer.mixerAttributes.BASS_MIXER_BUFFER;
          break;
        default:
          chanCount = 2;
          break;
      }
    }

    if(this.decodeOnly) {
      speaker = pushPlayer.bassAttributes.BASS_STREAM_DECODE;
    }

    //create mixer
    let mixer = pushPlayer.createMixer(chanCount, speaker);
    this.mixer = mixer;
    pushPlayer.setVolume(mixer, 100);
  }

  async playPush(pushUrl) {
    this.pushUrl = pushUrl;
    if(this.pushUrl == '' || !this.pushUrl) {
      this.logger.PushAudio(`push url is empty or undefined, url: ${this.pushUrl}`);
      return;
    }

    let p = new Player();
    let chan = p.openUrl(this.pushUrl, this._pushPlayer.bassAttributes.BASS_STREAM_DECODE);
    let err = parseInt(p.getError());
    if(chan == 0 || err != 0) {
      this.logger.PushAudio(`Error opening push url, err: ${err}, push url: ${this.pushUrl}`);
      this.isPlaying = false;
    }
    this.isPlaying = true;
    this.emit(this.pushAudioEvents.pushAudioStarted);
    let result = this._pushPlayer.addChannelToMixer(chan, this.addChannelFlags);
    let sync = p.basslib.BASS_ChannelSetSync(chan, p.basslib.BASS_SYNC_END, 0, (handle, channel, data, user) => {
      if(handle == sync) {
        p.basslib.BASS_ChannelRemoveSync(chan, sync);
        let streamFree = p.basslib.BASS_StreamFree(chan);
          this.isPlaying = false;
        this.emit(this.pushAudioEvents.pushAudioStopped);
      }
    });
  }
};

const util = require('util');
const EventEmitter = require('events').EventEmitter;
util.inherits(pushPlayer, EventEmitter);
module.exports = pushPlayer;