(function () {
  'use strict';

  /**
   * @copyright  (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
   * @license    GNU General Public License version 2 or later; see LICENSE.txt
   */
  (function (document) {
    /*
     * JField 'showon' class
     */
    var Showon = /*#__PURE__*/function () {
      /*
       * Constructor
       *
       * @param {HTMLElement} cont Container element
       */
      function Showon(cont) {
        var _this = this;

        var self = this;
        this.container = cont || document;
        this.fields = {// origin-field-name: {
          //   origin:  ['collection of all the trigger nodes'],
          //   targets: ['collection of nodes to be controlled control']
          // }
        };
        this.showonFields = [].slice.call(this.container.querySelectorAll('[data-showon]')); // Populate the fields data

        if (this.showonFields.length) {
          // @todo refactor this, dry
          this.showonFields.forEach(function (field) {
            // Set up only once
            if (field.hasAttribute('data-showon-initialised')) {
              return;
            }

            field.setAttribute('data-showon-initialised', '');
            var jsondata = field.getAttribute('data-showon') || '';
            var showonData = JSON.parse(jsondata);
            var localFields;

            if (showonData.length) {
              localFields = [].slice.call(self.container.querySelectorAll("[name=\"" + showonData[0].field + "\"], [name=\"" + showonData[0].field + "[]\"]"));

              if (!_this.fields[showonData[0].field]) {
                _this.fields[showonData[0].field] = {
                  origin: [],
                  targets: []
                };
              } // Add trigger elements


              localFields.forEach(function (cField) {
                if (_this.fields[showonData[0].field].origin.indexOf(cField) === -1) {
                  _this.fields[showonData[0].field].origin.push(cField);
                }
              }); // Add target elements

              _this.fields[showonData[0].field].targets.push(field); // Data showon can have multiple values


              if (showonData.length > 1) {
                showonData.forEach(function (value, index) {
                  if (index === 0) {
                    return;
                  }

                  localFields = [].slice.call(self.container.querySelectorAll("[name=\"" + value.field + "\"], [name=\"" + value.field + "[]\"]"));

                  if (!_this.fields[showonData[0].field]) {
                    _this.fields[showonData[0].field] = {
                      origin: [],
                      targets: []
                    };
                  } // Add trigger elements


                  localFields.forEach(function (cField) {
                    if (_this.fields[showonData[0].field].origin.indexOf(cField) === -1) {
                      _this.fields[showonData[0].field].origin.push(cField);
                    }
                  }); // Add target elements

                  if (_this.fields[showonData[0].field].targets.indexOf(field) === -1) {
                    _this.fields[showonData[0].field].targets.push(field);
                  }
                });
              }
            }
          }); // Do some binding

          this.linkedOptions = this.linkedOptions.bind(this); // Attach events to referenced element, to check condition on change and keyup

          Object.keys(this.fields).forEach(function (key) {
            if (_this.fields[key].origin.length) {
              _this.fields[key].origin.forEach(function (elem) {
                // Initialize the showon behaviour for the given HTMLElement
                self.linkedOptions(key); // Setup listeners

                elem.addEventListener('change', function () {
                  self.linkedOptions(key);
                });
                elem.addEventListener('keyup', function () {
                  self.linkedOptions(key);
                });
                elem.addEventListener('click', function () {
                  self.linkedOptions(key);
                });
              });
            }
          });
        }
      }
      /**
       *
       * @param key
       */


      var _proto = Showon.prototype;

      _proto.linkedOptions = function linkedOptions(key) {
        var _this2 = this;

        // Loop through the elements that need to be either shown or hidden
        this.fields[key].targets.forEach(function (field) {
          var elementShowonDatas = JSON.parse(field.getAttribute('data-showon')) || [];
          var showfield = true;
          var itemval; // Check if target conditions are satisfied

          elementShowonDatas.forEach(function (elementShowonData, index) {
            var condition = elementShowonData || {};
            condition.valid = 0; // Test in each of the elements in the field array if condition is valid

            _this2.fields[key].origin.forEach(function (originField) {
              if (originField.name !== elementShowonData.field) {
                return;
              }

              var originId = originField.id; // If checkbox or radio box the value is read from properties

              if (originField.getAttribute('type') && ['checkbox', 'radio'].indexOf(originField.getAttribute('type').toLowerCase()) !== -1) {
                if (!originField.checked) {
                  // Unchecked fields will return a blank and so always match
                  // a != condition so we skip them
                  return;
                }

                itemval = document.getElementById(originId).value;
              } else {
                // Select lists, text-area etc. Note that multiple-select list returns
                // an Array here s0 we can always treat 'itemval' as an array
                itemval = document.getElementById(originId).value; // A multi-select <select> $field  will return null when no elements are
                // selected so we need to define itemval accordingly

                if (itemval === null && originField.tagName.toLowerCase() === 'select') {
                  itemval = [];
                }
              } // Convert to array to allow multiple values in the field (e.g. type=list multiple)
              // and normalize as string


              if (!(typeof itemval === 'object')) {
                itemval = JSON.parse("[\"" + itemval + "\"]");
              } // Test if any of the values of the field exists in showon conditions


              itemval.forEach(function (val) {
                // ":" Equal to one or more of the values condition
                if (condition.sign === '=' && condition.values.indexOf(val) !== -1) {
                  condition.valid = 1;
                } // "!:" Not equal to one or more of the values condition


                if (condition.sign === '!=' && condition.values.indexOf(val) === -1) {
                  condition.valid = 1;
                }
              });
            }); // Verify conditions
            // First condition (no operator): current condition must be valid


            if (condition.op === '') {
              if (condition.valid === 0) {
                showfield = false;
              }
            } else {
              // Other conditions (if exists)
              // AND operator: both the previous and current conditions must be valid
              if (condition.op === 'AND' && condition.valid + elementShowonDatas[index - 1].valid < 2) {
                showfield = false;
                condition.valid = 0;
              } // OR operator: one of the previous and current conditions must be valid


              if (condition.op === 'OR' && condition.valid + elementShowonDatas[index - 1].valid > 0) {
                showfield = true;
                condition.valid = 1;
              }
            }
          }); // If conditions are satisfied show the target field(s), else hide

          if (field.tagName !== 'option') {
            if (showfield) {
              field.classList.remove('hidden');
            } else {
              field.classList.add('hidden');
            }
          } else {
            // TODO: If chosen or choices.js is active we should update them
            field.disabled = !showfield;
          }
        });
      };

      return Showon;
    }(); // Provide a public API


    window.Joomla = window.Joomla || {};

    if (!Joomla.Showon) {
      Joomla.Showon = {
        initialise: function initialise(container) {
          return new Showon(container);
        }
      };
    }
    /**
     * Initialize 'showon' feature at an initial page load
     */


    document.addEventListener('DOMContentLoaded', function () {
      Joomla.Showon.initialise(document);
    });
    /**
     * Initialize 'showon' feature when part of the page was updated
     */

    document.addEventListener('joomla:updated', function (_ref) {
      var target = _ref.target;

      // Check is it subform, then wee need to fix some "showon" config
      if (target.classList.contains('subform-repeatable-group')) {
        var elements = [].slice.call(target.querySelectorAll('[data-showon]'));
        var search = new RegExp("\\[" + target.dataset.baseName + "X\\]", 'g');
        var replace = "[" + target.dataset.group + "]"; // Fix showon field names in a current group

        elements.forEach(function (element) {
          var showon = element.dataset.showon.replace(search, replace);
          element.dataset.showon = showon;
        });
      }

      Joomla.Showon.initialise(target);
    });
  })(document);

}());
