(function (context, $) {

  "use strict";

  context.JK = context.JK || {};
  context.JK.AccountAudioProfile = function (app) {

    var EVENTS = context.JK.EVENTS;
    var ALERT_NAMES = context.JK.ALERT_NAMES;
    var gearUtils = context.JK.GearUtils;
    var logger = context.JK.logger;
    var rest = context.JK.Rest();
    var self = this;
    var reloadAudioTimeout = null;
    var $root;
    var $dialog;
    var $addNewGearBtn;
    var userId;
    var showingGearWizard = false;
    var cancelRescanFunc = null;

    function beforeShow(data) {
      userId = data.id;

      showingGearWizard = false;
      cancelRescanFunc = null;
      registerFtueSuccess();
      context.JK.onBackendEvent(ALERT_NAMES.USB_CONNECTED, 'accounts_audio_profile', onUsbDeviceConnected);
      context.JK.onBackendEvent(ALERT_NAMES.USB_DISCONNECTED, 'accounts_audio_profile', onUsbDeviceDisconnected);
    }

    function afterShow(data) {
      resetForm();
      renderAudioProfileScreen();
      scheduleRescanSystem(3000);
    }

    function beforeHide() {
      unregisterFtueSuccess();
      context.JK.offBackendEvent(ALERT_NAMES.USB_CONNECTED, 'accounts_audio_profile', onUsbDeviceConnected);
      context.JK.offBackendEvent(ALERT_NAMES.USB_DISCONNECTED, 'accounts_audio_profile', onUsbDeviceDisconnected);
      cancelRescan();

    }

    function cancelRescan() {
      if(cancelRescanFunc) {
        cancelRescanFunc();
        cancelRescanFunc = null;
      }
    }
    function scheduleRescanSystem(time) {

      cancelRescanFunc = gearUtils.scheduleAudioRestart('audio-profile', time,
        function() {
          $root.find('a[data-purpose=reload-audio]').addClass('disabled')
          $root.find('.rescanning-notice').show();
        },
        function(canceled) {
          $root.find('a[data-purpose=reload-audio]').removeClass('disabled')
          $root.find('.rescanning-notice').hide();

          if(!canceled) {
            var result = context.jamClient.ReloadAudioSystem(false, true, true);
          }

          populateAccountAudio();
        });
    }

    function onUsbDeviceConnected() {
      if(showingGearWizard) { return; } // gear wizard also handles these events; unpredictable if both are rebuilding port audio
      if(!context.jamClient.IsFrontendVisible()) {return;} // don't handle USB events when minimized
      logger.debug("USB device connected");

      scheduleRescanSystem(5000);
    }

    function onUsbDeviceDisconnected() {
      if(showingGearWizard) { return; } // gear wizard also handles these events; unpredictable if both are rebuilding port audio
      if(!context.jamClient.IsFrontendVisible()) {return;} // don't handle USB events when minimized

      logger.debug("USB device disconnected");

      scheduleRescanSystem(5000);
    }

    function renderAudioProfileScreen() {
      if (!gon.isNativeClient) {
        context.JK.guardAgainstBrowser(app, {d1: 'gear'});
      }
      else {
        var profiles = populateAccountAudio();
        if(profiles.length <= 1) {
          setTimeout(function() {
            context.JK.prodBubble($addNewGearBtn, 'no-audio-profiles', {}, {positions: ['bottom'], offsetParent: $addNewGearBtn.closest('.screen')})
          }, 1000);

        }
      }
    }

    function populateAccountAudio() {
      var profiles = gearUtils.getProfiles();

      context._.each(profiles, function(profile) {
          profile.active_text = profile.current ? '(active)' : '';
      });

      // If you are in the FTUE, and you close the client and/or it crashes
      // then you will have 'FTUE' (incomplete) profiles.  This is the only time

      var cleansedProfiles = [];
      context._.each(profiles, function(profile) {
        if(profile.id.indexOf('FTUE') == 0) {
          context.jamClient.TrackDeleteProfile(profile.id);
        }
        else {
          cleansedProfiles.push(profile)
        }
      });

      var template = context._.template($('#template-account-audio').html(), {is_admin: context.JK.currentUserAdmin, profiles: cleansedProfiles}, {variable: 'data'});

      appendAudio(template);

      return profiles;
    }

    function appendAudio(template) {
      $('#account-audio-content-scroller table tbody').replaceWith(template);
    }

    function resetForm() {
    }

    function handleDeleteAudioProfile(audioProfileId) {
      logger.debug("deleting audio profile: " + audioProfileId);

      context.jamClient.TrackDeleteProfile(audioProfileId);

      // redraw after deletion of profile
      populateAccountAudio();
    }

    function handleLoopbackAudioProfile(audioProfileId) {

      if(audioProfileId != context.jamClient.FTUEGetMusicProfileName()) {
        var result = context.jamClient.FTUELoadAudioConfiguration(audioProfileId);

        if(!result) {
          logger.error("unable to activate audio configuration: " + audioProfileId);
          context.JK.alertSupportedNeeded("Unable to activate audio configuration for profile named: " + audioProfileId);
        }
        else {
          // redraw after activation of profile
          populateAccountAudio();
        }
      }

      app.layout.showDialog('loopback-wizard');
    }

    function handleConfigureAudioProfile(audioProfileId) {

      if(!gearUtils.canBeConfigured(audioProfileId)) {

        context.JK.Banner.showAlert("The System Default (Playback Only) profile can not be configured.");
        return;
      }

      if(audioProfileId == gearUtils.GearUtil)
      if(audioProfileId != context.jamClient.FTUEGetMusicProfileName()) {
        logger.debug("activating " + audioProfileId);
        var result = context.jamClient.FTUELoadAudioConfiguration(audioProfileId);

        if(!result) {
          logger.error("unable to activate audio configuration: " + audioProfileId);
          context.JK.alertSupportedNeeded("Unable to activate audio configuration for profile named: " + audioProfileId);
          return;
        }

        // FTUELoadAudioConfiguration eventually sets this, but apparently asynchronously
        result = context.jamClient.SetLastUsedProfileName(audioProfileId);

        if(!result) {
          logger.error("unable to activate audio configuration after loading it: " + audioProfileId);
          context.JK.alertSupportedNeeded("Unable to activate audio configuration for profile named: " + audioProfileId);
          return;
        }

        // redraw after activation of profile
        populateAccountAudio();
      }

      app.layout.showDialog('configure-tracks')
        .one(EVENTS.DIALOG_CLOSED, populateAccountAudio)
    }

    function handleActivateAudioProfile(audioProfileId) {
      logger.debug("activating audio profile: " + audioProfileId);

      if(audioProfileId == context.jamClient.LastUsedProfileName()) {
        context.JK.Banner.showAlert("This profile is already active.");
        return;
      }

      var result = context.jamClient.SetLastUsedProfileName(audioProfileId);

      if(!result) {
        logger.error("unable to activate audio configuration: " + audioProfileId);
        context.JK.alertSupportedNeeded("Unable to activate audio configuration for profile named: " + audioProfileId);
      }

      // redraw after activation of profile
      populateAccountAudio();
    }

    function handleStartAudioQualification() {

      app.afterFtue = function() {
        showingGearWizard = false;
        if(populateAccountAudio().length == 1) {
          app.layout.showDialog('join-test-session');
        }
      };
      app.cancelFtue = function() { showingGearWizard = false; populateAccountAudio() };
      showingGearWizard = true;
      app.layout.startNewFtue()
    }

    function reloadAudio() {
      // false = don't start audio, true = reload last audio configuration, false = don't re-init tracks
      context.jamClient.ReloadAudioSystem(false, true, false);

      populateAccountAudio();
    }

    function registerFtueSuccess() {
      $('div[layout-id=ftue]').on("ftue_success", ftueSuccessHandler);
    }

    function unregisterFtueSuccess() {
      $('div[layout-id=ftue]').off("ftue_success", ftueSuccessHandler);
    }

    function ftueSuccessHandler() {
      populateAccountAudio();
    }

    // events for main screen
    function events() {
      // wire up main panel clicks
      $root = $('#account-audio-content-scroller');
      $root.on('click', 'a[data-purpose=delete-audio-profile]', function (evt) {
        evt.stopPropagation();
        handleDeleteAudioProfile($(this).attr('data-id'));
        return false;
      });

      $root.on('click', 'a[data-purpose=activate-audio-profile]', function (evt) {
        evt.stopPropagation();
        var $btn = $(this);
        var status = $btn.closest('tr').attr('data-status');
        if(status == "good") {
          handleActivateAudioProfile($btn.attr('data-id'));
        }
        else {
          context.JK.Banner.showAlert("Unable to activate this profile.  Please verify that the devices associated are connected.");
        }
        return false;
      });


      $root.on('click', 'a[data-purpose=loopback-audio-profile]', function (evt) {
        evt.stopPropagation();
        var $btn = $(this);
        var status = $btn.closest('tr').attr('data-status');
        if(status == "good") {
          cancelRescan();
          handleLoopbackAudioProfile($btn.attr('data-id'));
        }
        else {
          context.JK.Banner.showAlert("Unable to loopback test this profile.  Please verify that the devices associated are connected.");
        }
        return false;
      });

      $root.on('click', 'a[data-purpose=configure-audio-profile]', function (evt) {
        evt.stopPropagation();
        var $btn = $(this);
        var status = $btn.closest('tr').attr('data-status');
        if(status == "good") {
          cancelRescan();
          handleConfigureAudioProfile($btn.attr('data-id'));
        }
        else {
          context.JK.Banner.showAlert("Unable to configure this profile.  Please verify that the devices associated are connected.");
        }
        return false;
      });


      $root.on('click', 'a[data-purpose=add-profile]', function (evt) {
        evt.stopPropagation();
        cancelRescan();
        handleStartAudioQualification();
        return false;
      });

      $root.on('click',  'a[data-purpose=reload-audio]', function (evt) {
        evt.stopPropagation();
        if($(this).is('.disabled')) {
          return false;
        }

        scheduleRescanSystem(3000);
        return false;
      });
    }

    function initialize() {
      var screenBindings = {
        'beforeShow': beforeShow,
        'afterShow': afterShow
      };

      app.bindScreen('account/audio', screenBindings);

      $dialog = $('#account-audio-profile')
      $addNewGearBtn = $dialog.find('a[data-purpose=add-profile]');
      events();
    }

    this.initialize = initialize;
    this.beforeShow = beforeShow;
    this.afterShow = afterShow;
    this.beforeHide = beforeHide;
    return this;
  };

})(window, jQuery);