/**
 * Attach simpledialog with a form with some email inputs as its content to the selected set of elements.
 *
 * The `de_epages.shopmailtypeUiEditmailaddress()` attaches simpledialog with a form with some email inputs as its content to the selected set of elements.
 *
 * ### Examples
 * Attach shopmailtypeUiEditmailaddress to edit button passing along some options in data attribute.
 *
 * JavaScript:
 *
 *     de_epages('#ep-edit-FROM').shopmailtypeUiEditmailaddress();
 *
 * HTML:
 *
 *     <input class="ep-width-70p Disabled-Edit" type="text" value="&quot;TTester&quot; &lt;ttester@epages.com&gt;" name="FROM" readonly="readonly">
 *     <span class="CommandLinkSmall" id="ep-edit-FROM" data-de_epages-shopmailtype-ui-editmailaddress="{&quot;name&quot; : &quot;FROM&quot;, &quot;data&quot;:{&quot;FROM&quot;:[{&quot;email&quot;:&quot;ttester@epages.com&quot;,&quot;name&quot;:&quot;TTester&quot;}]},&quot;multiple&quot;:false,&quot;showSetDefault&quot;:true,&quot;wording&quot;:{&quot;setDefault&quot;:&quot;Use This Address As Default Sender&quot;,&quot;email&quot;:&quot;E-mail address&quot;,&quot;name&quot; : &quot;Name&quot;, &quot;deleteMail&quot; : &quot;Delete&quot;, &quot;addMail&quot; : &quot;Add Email Address&quot;,&quot;apply&quot;:&quot;Apply&quot;}}"><span><span class="WithIcon Edit">Edit</span></span></span>
 *
 *
 * @class jQuery.ui.shopmailtypeUiEditmailaddress
 * @extends jQuery.widget
 *
 * @uses jQuery.ui.widget
 * @uses de_epages
 * @uses ep.ui.simpledialog
 * @uses ep.ui.validate
 * @uses ep.ui.input
 * @since 6.15.0
 */

/**
 * @cfg {Boolean} [multiple] Allow multiple e-mail addresses to be entered.
 */

/**
 * @cfg {String} [name] Name of the associated input. $('input[name="' + name + '"]')
 */

/**
 * @cfg {String} [showSetDefault] If true, there is a checkbox inside the dialog. When the checkbox is checked and apply is clicked, the entered e-mail address data is ajaxed over to the server.
 */

/**
 * @cfg {Object} wording Wording for the dialog. See example.
 */

/**
 * @cfg {Object} data E-mail data for the dialog. There has to be a key (named as the option name) which holds an array of objects with keys "email" and "name"
 */

/**
 * See `jQuery.ui.shopmailtypeUiEditmailaddress` for details.
 *
 * @param {Object} options A map of additional options pass to the method.
 * @param {Boolean} [multiple] Allow multiple e-mail addresses to be entered.
 * @param {String} [name] Name of the associated input. $('input[name="' + name + '"]')
 * @param {String} [showSetDefault] If true, there is a checkbox inside the dialog. When the checkbox is checked and apply is clicked, the entered e-mail address data is ajaxed over to the server.
 * @param {Object} wording Wording for the dialog. See example.
 * @param {Object} data E-mail data for the dialog. There has to be a key (named as the option name) which holds an array of objects with keys "email" and "name"
 *
 * @method shopmailtypeUiEditmailaddress
 * @member jQuery
 *
 * @since 6.15.0
 */

/*jslint nomen: true*/
/*global define*/
define('de_epages/shopmailtype/ui/editmailaddress', [
    'jquery',
    'ep',
    'de_epages',
    '$tmpl!./editmailaddress',

    'jquery/ui/widget',
    'ep/ajax',
    'ep/ui/simpledialog',
    'ep/ui/validate',
    'ep/ui/input'
], function ($, ep, de_epages, tmplEditMailadress) {
    'use strict';

    // Widget.
    $.widget('ui.shopmailtypeUiEditmailaddress', {

        dataContainer: {
            FROM: {email: [], name: []},
            CC: {email: [], name: []},
            BCC: {email: [], name: []},
            TO: {email: [], name: []},

            // inputCounter counts all visible email input fields of the dialog
            inputCounter: 0
        },

        options: {
            wording: {},
            data: {
                'dummy': []
            },
            name: 'dummy',
            multiple: true,
            showSetDefault: false,
            mailRequired: true
        },

        _create: function () {
            var self = this,
                inputEmail,
                inputName,
                o = self.options;

            // Merge in options from data attribute.
            $.extend(true, o, $.parseJSON(self.element.attr('data-de_epages-shopmailtype-ui-editmailaddress') || "null"));

            // Set corresponding input element.
            if (!o.name) {
                return self.destroy();
            }

            self.input = $('input[name="' + o.name + '"]');

            // Render template.
            self.content = $('<form>').append(tmplEditMailadress(o.data[o.name].length ? o.data[o.name] : [{}], {
                wording: o.wording,
                mailRequired: o.mailRequired
            }));
            // Init delete event listeners.
            self.content.on('click', '.fa-times', $.proxy(self, '_deleteMail'));

            // Init *uiValidate* and *uiInput*.
            $(self.content.find('input[type="email"]')).uiValidate({
                type: 'email'
            });
            $(self.content.find('input[type="text"]')).uiInput();

            inputEmail = self.content.find('input[type="email"]');
            inputName = self.content.find('input[name="name"]');

            inputEmail.each(function (index, email) {
                self.dataContainer[o.name].email[index] = $(email).val();
                if (inputName.eq(index)) {
                // Get the jquery element back with eq
                    self.dataContainer[o.name].name[index] = inputName.eq(index).val();
                }
            });

            // Add footer.
            // i.e. *setDefault* checkbox or *addMail* button.
            self.footer = $('<footer>');
            if (o.multiple) {
                $('<span  style="padding-left:158px;" class="DisplayBlock PseudoLink CursorPointer">').text(o.wording.addMail).on('click', $.proxy(self, '_addMail')).appendTo(self.footer);
            } else {
                if (o.showSetDefault) {
                    // Init and render template.
                    if (!$.template['de_epages.shopmailtype.inc.setdefault']) {
                        $.template('de_epages.shopmailtype.inc.setdefault', '<div class="InputRow">' + '<input type="checkbox" name="setdefault" id="setdefault"/>' + '<label class="InputLabellingXWide AlignLeft" for="setdefault">${$item.wording.setDefault}</label>' + '</div>');
                    }

                    self.setDefault = $.tmpl('de_epages.shopmailtype.inc.setdefault', {}, {
                        wording: o.wording
                    }).appendTo(self.footer).find('input[type="checkbox"]').uiInput();
                }
            }

            // Init *uiSimpleDialog*.
            self.element = $(self.element).uiSimpledialog({
                content: [self.content[0], self.footer[0]],
                buttons: [{
                    text: o.wording.apply,
                    callback: function () {
                        if (self.content.find('input[type="email"]:invalid').length) {
                            $(self.content.find('input[type="email"]:invalid')).trigger('validate.uiValidate');
                        } else {
                            self._apply();
                            self._close();
                        }
                    }
                }]
            });


            self.element.on("open", function () {
                var parent,
                    i,j;

                if (self.dataContainer[o.name].email.length === 0){
                    self.dataContainer[o.name].email = [""];
                    self.dataContainer[o.name].name = [""];
                }

                // Set input arrays anew, because their values could have changed here
                inputEmail = self.content.find('input[type="email"]');
                inputName = self.content.find('input[name="name"]');

                // Reset inputCounter to the total number of email input fields for every "open" event
                self.dataContainer.inputCounter = self.dataContainer[o.name].email.length;

                // Fill input fields with all data stored in the appropriate dataContainer array
                self.content.find('.InputRow').removeClass("HideElement");
                for (i = 0; i < self.dataContainer[o.name].email.length; i++) {
                    inputEmail.eq(i).val(self.dataContainer[o.name].email[i]);
                    inputName.eq(i).val(self.dataContainer[o.name].name[i]);
                };

                // Delete all input fields that have no data passed to by the dataContainer array
                for (j = i ; j < inputEmail.length; j++) {
                    parent = inputEmail.eq(j).parent();
                    parent.next().remove();
                    parent.remove();
                };
            });
        },
        _deleteMail: function (event) {
            var self = this,
                o = self.options,
                inputEmail = self.content.find('input[type="email"]'),
                inputName = self.content.find('input[name="name"]'),
                parent = $(event.target).parent();

            event.stopPropagation();
            // Otherwise *self.dialog._close()* is called, since
            // the click was fired by an element which at that point
            // is no longer part of the dialog.

            // Hide all elements affected by the delete action (they will only be deleted from the DOM when pressing the apply button, see below)
            if (self.dataContainer.inputCounter > 1){
                parent.next().addClass("HideElement");
                parent.addClass("HideElement");
                self.dataContainer.inputCounter--;
            } else {
                // Make sure that at least one input element is still visible when trying to delete it
                inputEmail.val("");
                inputName.val("");
            }
        },

        _addMail: function () {
            var self = this,
                o = self.options,
                inputrow = tmplEditMailadress({}, {
                    wording: o.wording
                });

            // Init *uiValidate* and *uiInput*.
            $(inputrow.find('input[type="email"]')).uiValidate({
                type: 'email'
            });
            $(inputrow.find('input[type="text"]')).uiInput();

            inputrow.appendTo(self.content);
            self.dataContainer.inputCounter++;
        },

        _apply: function () {
            var self = this,
                o = self.options,
                value = '',
                inputs,
                names,
                name = '',
                doajax = self.setDefault && self.setDefault.is(':checked');

            // Delete all hidden elements
            self.content.find('.InputRow').filter('.HideElement').remove();

            inputs = self.content.find('input[type="text"], input[type="email"]');
            names = inputs.filter('[type="text"]');

            // Empty the dataContainer array first to fill it up with all the data below
            self.dataContainer[o.name].email.length = 0;
            self.dataContainer[o.name].name.length = 0;

            // Let us add all those emails and names together.
            inputs.filter('[type="email"]').each(function (index, email) {
                email = email.value;
                name = names[index].value;
                // Set default Sender Address, if the checkbox is checked.
                if ((index === 0) && doajax) {
                    ep.ajax({
                        type: 'POST',
                        dataType: 'json',
                        data: {
                            'DefaultEmail': email,
                            'DefaultName': name,
                            'ViewAction': 'JSONViewResponse',
                            'ChangeAction': 'JSONMakeDefaultSender',
                            'ObjectID': ep.config.objectId
                        }
                    });
                }
                if (email !== "") {
                    value = value + (value ? ';' : '') + name + (name ? ' <' : '') + email + (name ? '>' : '');
                // Store email and name in its correponding dataContainer arrays
                // for retrieving them when the "open" event is executed
                    self.dataContainer[o.name].email[index] = email;
                    self.dataContainer[o.name].name[index] = name;
                }
            });

            // Output email string into input.
            self.input.val(value);
        },

        _close: function () {
            this.element.uiSimpledialog('close');
        },

        destroy: function () {
            var self = this;
            if (self.content) {
                self.content.remove();
            }
            self.element.uiSimpledialog('destroy');
            self._superApply(arguments);
        }

    });

    return de_epages;
});