(function(context,$) {

  "use strict";

  context.JK = context.JK || {};

  // Class to intercept and delegate out all backend alerts as necessary
  // better if modules that needed certain events would just register for them.
  context.JK.BackendAlerts = function(app) {

    var $document = $(document);
    var logger = context.JK.logger;

    var ALERT_TYPES = context.JK.ALERT_TYPES;
    var ALERT_NAMES = context.JK.ALERT_NAMES;

    function onNoValidAudioConfig(type, text) {
      app.notify({
        "title": ALERT_TYPES[type].title,
        "text": text,
        "icon_url": "/assets/content/icon_alert_big.png"
      });
      context.location = "/client#"; // leaveSession will be called in beforeHide below
    }

    function onStunEvent() {
      var testResults = context.jamClient.NetworkTestResult();

      $.each(testResults, function (index, val) {
        if (val.bStunFailed) {
          // if true we could not reach a stun server
        }
        else if (val.bRemoteUdpBocked) {
          // if true the user cannot communicate with peer via UDP, although they could do LAN based session
        }
      });
    }

    function onGenericEvent(type, text) {

      var alert = ALERT_TYPES[type];

      if(alert && alert.title) {
        context.NotificationActions.backendNotification({msg: alert.title, detail: alert.message, backend_detail:text, help: alert.help})
      }
      else {
        logger.debug("Unhandled Backend Event type %o, data %o", type, text)
      }

    }

    function alertCallback(type, text) {

      function timeCallback() {
        var start = new Date();
        setTimeout(function() {
          var timed = new Date().getTime() - start.getTime();
          if(timed > 250) {
            logger.warn("SLOW AlERT_CALLBACK. type: %o text: %o time: %o", type, text, timed);
          }
        }, 1);
      }

      timeCallback();

      logger.debug("alert callback", type, text);

      var alertData = $.extend({}, ALERT_TYPES[type]);
      
      alertData.text = text;
      if(alertData && alertData.name) {
        $document.triggerHandler(alertData.name, alertData);
      }

      if (type === 2) { // BACKEND_MIXER_CHANGE

        context.MixerActions.mixersChanged(type, text)

        //if(context.JK.CurrentSessionModel)
        //  context.JK.CurrentSessionModel.onBackendMixerChanged(type, text)
      }
      else if (type === ALERT_NAMES.NO_VALID_AUDIO_CONFIG) { // NO_VALID_AUDIO_CONFIG
        if(context.JK.GearUtilsInstance && context.JK.GearUtilsInstance.isRestartingAudio()) {
          // squelch this warning, because we are restarting audio
        }
        else {
          onNoValidAudioConfig(type, text);
        }

      }
      else if (type === ALERT_NAMES.AUDIO_DEVICE_NOT_PRESENT) { // NO_VALID_AUDIO_CONFIG
        if(context.JK.GearUtilsInstance && context.JK.GearUtilsInstance.isRestartingAudio()) {
          // squelch this warning, because we are restarting audio
        }
        else {
          onGenericEvent(type, text);
        }
      }
      else if (type === 24) {
        onStunEvent();
      }
      else if (type === 26) { // DEAD_USER_REMOVE_EVENT
        MixerActions.deadUserRemove(text);
        //if(context.JK.CurrentSessionModel)
        //  context.JK.CurrentSessionModel.onDeadUserRemove(type, text);
      }
      else if (type === 27) { // WINDOW_CLOSE_BACKGROUND_MODE

        SessionActions.windowBackgrounded()

        //if(context.JK.CurrentSessionModel)
       //   context.JK.CurrentSessionModel.onWindowBackgrounded(type, text);
      }
      else if(type === ALERT_NAMES.SESSION_LIVEBROADCAST_FAIL) {
        SessionActions.broadcastFailure(text)
        //if(context.JK.CurrentSessionModel)
        //  context.JK.CurrentSessionModel.onBroadcastFailure(type, text);
      }
      else if(type === ALERT_NAMES.SESSION_LIVEBROADCAST_ACTIVE) {
        SessionActions.broadcastSuccess(text)
        //if(context.JK.CurrentSessionModel)
         // context.JK.CurrentSessionModel.onBroadcastSuccess(type, text);
      }
      else if(type === ALERT_NAMES.SESSION_LIVEBROADCAST_STOPPED) {
        SessionActions.broadcastStopped(text)
        //if(context.JK.CurrentSessionModel)
          //context.JK.CurrentSessionModel.onBroadcastStopped(type, text);
      }
      else if(type === ALERT_NAMES.RECORD_PLAYBACK_STATE) {
        //if(context.JK.CurrentSessionModel)
        //  context.JK.CurrentSessionModel.onPlaybackStateChange(type, text);
        context.MediaPlaybackActions.playbackStateChange(text);
      }
      else if(type === ALERT_NAMES.VIDEO_WINDOW_OPENED) {
        context.VideoActions.videoWindowOpened()
      }
      else if(type === ALERT_NAMES.VIDEO_WINDOW_CLOSED) {
        context.VideoActions.videoWindowClosed()
      }
      else if (type === ALERT_NAMES.VST_CHANGED) {
        console.log("VST CHANGED!")
        context.ConfigureTracksActions.vstChanged()
      }
      else if((!context.JK.CurrentSessionModel || !context.JK.CurrentSessionModel.inSession()) &&
        (ALERT_NAMES.INPUT_IO_RATE == type || ALERT_NAMES.INPUT_IO_JTR == type || ALERT_NAMES.OUTPUT_IO_RATE == type || ALERT_NAMES.OUTPUT_IO_JTR== type)) {
        // squelch these events if not in session
      }
      else if(type != 30 && type != 31 && type != 21){  // these are handled elsewhere
        onGenericEvent(type, text);
      }
    }

    function initialize() {
      context.jamClient.SessionSetAlertCallback("JK.AlertCallback");
    }

    this.initialize = initialize;

    context.JK.AlertCallback = alertCallback;

    return this;
  }

})(window, jQuery);