'use strict';
/**
 * Start the requirejs config.
 */
require.config({
  paths: {
    'bootstrap-switch': '../../webjars/bootstrap-switch/3.3.2/js/bootstrap-switch.min'
  },
  shim: {
    'bootstrap-switch' : ['jquery']
  }
});
/**
 * Start the real script.
 */
require(['jquery', 'xwiki-meta', 'ApplicationWidget', 'bootstrap', 'bootstrap-switch', 'xwiki-events-bridge'], function ($, xm, ApplicationWidget) {

  /**
   * Page initialization
   */
  var preferenceInit = function (event) {

    var applications = [];
    if (event.data && event.data.elements) {
      var container = $(event.data.elements);
    } else {
      var container = $(document);
    }

    // Create application widgets
    container.find('.applicationElem').each(function() {
      applications.push(new ApplicationWidget($(this)));
    });

    /**
     * Save the current settings
     */
    var save = function() {
      // To avoid having several requests in the same time (which could lead to error 500), we disable all the triggers during the save process
      var toggles = $('.bootstrap-switch input');
      toggles.bootstrapSwitch('disabled', true);
      var notification = new XWiki.widgets.Notification("Your settings are being saved...", 'inprogress');
      var data = [];
      for (var i = 0; i < applications.length; ++i) {
        for (var j = 0; j < applications[i].eventTypes.length; j++) {
          data.push({
            eventType: applications[i].eventTypes[j].eventType,
            format: 'alert',
            enabled: applications[i].eventTypes[j].getAlertState()
          });
          // Email might be disabled, so we don't send info about the email settings if the corresponding buttons are not there
          if ($('.notificationTypeCell[data-format="email"]').length > 0) {
            data.push({
              eventType: applications[i].eventTypes[j].eventType,
              format: 'email',
              enabled: applications[i].eventTypes[j].getEmailState()
            });
          }
        }
      }
      var target = $('.notifPreferences').attr('data-target');
      var targetUser = "";
      if (target == 'user') {
        var targetUser = $('.notifPreferences').attr('data-user');
      }
      var url = "https://peacock.place:443/xwiki/wiki/iotstuff/get/XWiki/Notifications/Code/NotificationPreferenceService?outputSyntax=plain";
      $.post(url, {
        action: 'savePreferences',
        target: $('.notifPreferences').attr('data-target'),
        user: targetUser,
        json: JSON.stringify(data),
        csrf: xm.form_token
      }).done(function() {
        notification.hide();
        new XWiki.widgets.Notification("Saved!", 'done');
      }).error(function() {
        notification.hide();
        new XWiki.widgets.Notification("Failed to save your settings", 'error');
      }).always(function() {
        // Enable again the triggers
        toggles.bootstrapSwitch('disabled', false);
      });
    };

    /**
     * Several changes can be received very closely (for example, when several switches are updated in the same time),
     * so we save only the last received event.
     * For that we postpone the save action (300ms is clone enought for the user) and we cancel it if an other event
     * happens in the meantime.
     */
    var nextSave = 0;
    $($('.notifPreferences')).off('switchChange.bootstrapSwitch').on('switchChange.bootstrapSwitch', function(event, state) {
      if (nextSave != 0) {
        clearTimeout(nextSave);
      }
      nextSave = setTimeout(save, 300);
    });

    // Disable the "loading" screens
    $('td.notificationTypeCell, td.notificationAppCell').each(function(){
      $(this).find('.hidden').removeClass('hidden');
      $(this).removeClass('loading');
    });

    /**
     * Disable the "loading" screens
     */
    $('td.notificationTypeCell').each(function(){
      $(this).find('> div.hidden').removeClass('hidden');
      $(this).removeClass('loading');
    });

  };
  
  $(document).ready(preferenceInit);
  $(document).on('xwiki:dom:updated', preferenceInit)
});

define('EventTypeWidget', ['jquery', 'xwiki-meta', 'bootstrap-switch'], function($, xm) {
  /**
  * Construct an EventTypeWidget.
  */
  return function(domElement, application) {
    var self               = this;
    self.domElement        = domElement;
    self.application       = application;
    self.eventType         = domElement.attr('data-eventtype');
    self.cellAlert         = domElement.find('.notificationTypeCell[data-format="alert"]');
    self.cellEmail         = domElement.find('.notificationTypeCell[data-format="email"]');
    self.switchAlert       = self.cellAlert.find('.notificationTypeCheckbox');
    self.switchEmail       = self.cellEmail.find('.notificationTypeCheckbox');
    self.alertObjectNumber = self.cellAlert.attr('data-objnumber');
    self.emailObjectNumber = self.cellEmail.attr('data-objnumber');

    /**
     * Initialization
     */
    self.init = function () {
      // Replace the 'hidden' class by a call to jQuery.hide();
      self.domElement.removeClass('hidden').hide();
      // Enable bootstrap switches
      $([self.switchAlert, self.switchEmail]).bootstrapSwitch({
        size: 'mini',
        labelText: '<span class=\"fa fa-bell\"><\/span>'
      });
    };

    // On change
    $(self.switchAlert).on('switchChange.bootstrapSwitch', function(event, state) {
      self.application.updateSwitches();
    });
    $(self.switchEmail).on('switchChange.bootstrapSwitch', function(event, state) {
      self.application.updateSwitches();
    });

    /**
     * Get the state of the alert switch
     */
    self.getAlertState = function() {
      return self.switchAlert.bootstrapSwitch('state');
    };

    /**
     * Get the state of the email switch
     */
    self.getEmailState = function() {
      return self.switchEmail.bootstrapSwitch('state');
    };

    /**
     * Set the state of the alert switch
     */
    self.setAlertState = function (state) {
      self.switchAlert.bootstrapSwitch('state', state);
    };

    /**
     * Set the state of the email switch
     */
    self.setEmailState = function (state) {
      self.switchEmail.bootstrapSwitch('state', state);
    };

    /**
     * Hide/Show the event type widget
     */
    self.toggleVisibility = function () {
      self.domElement.toggle();
    };

    // Call init
    self.init();
  };
});

define('ApplicationWidget', ['jquery', 'EventTypeWidget', 'bootstrap-switch'], function($, EventTypeWidget) {
  /**
   * Construct an application widget.
   */
  return function(domElement) {

    var self             = this;
    self.domElement      = domElement;
    self.applicationId   = domElement.attr('data-applicationid');
    self.cellAlert       = domElement.find('.notificationAppCell[data-format="alert"]');
    self.cellEmail       = domElement.find('.notificationAppCell[data-format="email"]');
    self.switchAlert     = self.cellAlert.find('.notificationAppCheckbox');
    self.switchEmail     = self.cellEmail.find('.notificationAppCheckbox');
    self.collapseButton  = domElement.find('.collapseButton');
    self.eventTypes      = [];

    /**
     * Initialization
     */
    self.init = function () {
      // Creates event type widgets for this application
      self.domElement.find('.rowEventType').each(function() {
        self.eventTypes.push(new EventTypeWidget($(this), self));
      });
      // Enable bootstrap switch.
      $([self.switchAlert, self.switchEmail]).bootstrapSwitch({
        size: 'small',
        labelText: '<span class=\"fa fa-bell\"><\/span>'
      });
      // Set initial state for the switches
      self.updateSwitches();
      self.updateTypesOnChange = true;
      // Handle collapsing
      // Make sure the click listener is registered only once.
      self.collapseButton.off('click.toggleVisibility').on('click.toggleVisibility', function() {
        for (var i = 0; i < self.eventTypes.length; ++i) {
          self.eventTypes[i].toggleVisibility();
        }
      });

      // Handle switch change
      self.switchAlert.on('switchChange.bootstrapSwitch', function(event, state) {
        for (var i = 0; i < self.eventTypes.length; ++i) {
          self.eventTypes[i].setAlertState(state);
        }
      });
      self.switchEmail.on('switchChange.bootstrapSwitch', function(event, state) {
        for (var i = 0; i < self.eventTypes.length; ++i) {
          self.eventTypes[i].setEmailState(state);
        }
      });
    };

    /**
     * Set the switch states according to their event type
     */
    self.updateSwitches = function() {
      var allAlertsOn = true;
      var allAlertsOff = true;
      var allEmailsOn = true;
      var allEmailsOff = true;
      for (var i = 0; i < self.eventTypes.length; ++i) {
        var eventType = self.eventTypes[i];
        allAlertsOn  &=  eventType.getAlertState();
        allAlertsOff &= !eventType.getAlertState();
        allEmailsOn  &=  eventType.getEmailState();
        allEmailsOff &= !eventType.getEmailState();
      }
      if (allAlertsOn) {
        self.switchAlert.bootstrapSwitch('state', true);
      } else if (allAlertsOff) {
        self.switchAlert.bootstrapSwitch('state', false);
      } else {
        self.switchAlert.bootstrapSwitch('indeterminate', true);
      }
      if (allEmailsOn) {
        self.switchEmail.bootstrapSwitch('state', true);
      } else if (allEmailsOff) {
        self.switchEmail.bootstrapSwitch('state', false);
      } else {
        self.switchEmail.bootstrapSwitch('indeterminate', true);
      }
    };

    // Call to init()
    self.init();
  };
});

