var fomanticButton = new Shiny.InputBinding();
$.extend(fomanticButton, {
  find: function(scope) {
    return $(scope).find(".form-button");
  },

  getValue: function(el) {
    return $(el).data('val') || 0;
  },

  setValue: function(el, value) {
    $(el).data('val', value);
  },

  getType: function(el) {
    return 'shiny.action';
  },

  subscribe: function(el, callback) {
    $(el).on("click.fomanticButton", function(e) {
      var $el = $(this);
      var val = $el.data('val') || 0;

      // If button is a submit button in a form, then need to check validation is in place first
      if ($el.hasClass('submit') && $el.parent().hasClass('form')) {
        if (!$el.parent().form('is valid')) {
          return;
        }
      }

      $el.data('val', val + 1);

      callback();
    });
  },

  getState: function(el) {
    return { value: this.getValue(el) };
  },

  receiveMessage: function(el, data) {
    var $el = $(el);
    // retrieve current label and icon
    var label = $el.text();
    var icon = '';

    // to check (and store) the previous icon, we look for a $el child
    // object that has an i tag, and some (any) class (this prevents
    // italicized text - which has an i tag but, usually, no class -
    // from being mistakenly selected)
    if ($el.find('i[class]').length > 0) {
      var icon_html = $el.find('i[class]')[0];
      if (icon_html === $el.children()[0]) {     // another check for robustness
        icon = $(icon_html).prop('outerHTML');
      }
    }

    // update the requested properties
    if (data.hasOwnProperty('label')) label = data.label;
    if (data.hasOwnProperty('icon')) {
      icon = data.icon;
      // if the user entered icon=character(0), remove the icon
      if (icon.length === 0) icon = '';
    }

    // produce new html
    $el.html(icon + ' ' + label);
  },

  unsubscribe: function(el) {
    $(el).off(".fomanticButton");
  }
});
Shiny.inputBindings.register(fomanticButton, 'shiny.fomanticButton');
