(function () {
    var prontus_insert = (function () {
        'use strict';

        var Env = tinymce.util.Tools.resolve('tinymce.Env');

        var embedChange = Env.ie && Env.ie <= 8 ? 'onChange' : 'onInput';

        /* Muestra mensajes de error en el editor. */
        var handleError = function (editor, error) {
            var errorMessage = error ? 'Administrar Includes: ' + error : 'Error desconocido.';
            editor.notificationManager.open({
                type: 'error',
                text: errorMessage
            });
        };

        var submitForm = function (win, editor) {
            var data = win.toJSON();
            var attrs = {}; // se rellena con los datos a cargar en el elemento. No se usa si se edita un elemento existente.
            var the_content = 'Include Prontus';
            var activeTab = win.items()[0].activeTabId;
            var tabs = {
                't0': 'include',
                't1': 'js'
            };
            var include_type = tabs[activeTab];
            var element = tinymce.activeEditor.selection.getNode();
            // chequeo de errores y carga inicial de datos.
            // no encuentro una manera mejor de implementar este código en tiempo útil.

            if (include_type == 'js') {
                if (data.insert_js_type == 'code' && data.insert_js_code == '') {
                    handleError(editor, 'Debes ingresar el código JavaScript a incluir');
                    return false;
                } else if (data.insert_js_type == 'file' && data.insert_js_file == '') {
                    handleError(editor, 'Debes especificar un archivo JavaScript a incluir');
                    return false;
                } else {
                    if (data.insert_js_type == 'file') {
                        if(element.tagName.toLowerCase() == 'prontus_insert') {
                            element.setAttribute('data-type', 'js');
                            element.setAttribute('data-src', data.insert_js_file);
                            element.removeAttribute('data-code');
                            element.innerHTML = 'Include JavaScript';
                        } else {
                            attrs['data-type'] = 'js';
                            attrs['data-src'] = data.insert_js_file;
                            the_content = 'Include JavaScript';
                        }
                    } else {
                        if(element.tagName.toLowerCase() == 'prontus_insert') {
                            element.setAttribute('data-type', 'js');
                            element.setAttribute('data-code', tinymce.activeEditor.dom.encode(data.insert_js_code));
                            element.removeAttribute('data-src');
                            element.innerHTML = 'Código JavaScript';
                        } else {
                            attrs['data-type'] = 'js';
                            attrs['data-code'] = tinymce.activeEditor.dom.encode(data.insert_js_code);
                            the_content = 'Código JavaScript';
                        }
                    }
                }
            } else {
                if (data.insert_file == '') {
                    handleError(editor, 'Debes especificar un archivo a incluir');
                    return false;
                } else {
                    var types = {'php': 'PHP', 'ssi': 'SSI', 'ssi_virtual': 'SSI Virtual'};
                    if(element.tagName.toLowerCase() == 'prontus_insert') {
                        element.setAttribute('data-type', data.insert_html_type);
                        element.setAttribute('data-src', data.insert_file);
                        element.innerHTML = 'Include ' + types[data.insert_html_type];
                    } else {
                        attrs['data-type'] = data.insert_html_type;
                        attrs['data-src'] = data.insert_file;
                        the_content = 'Include ' + types[data.insert_html_type];
                    }
                }
            }
            // si el elemento seleccionado con el cursor es un tag prontus_insert, lo edito.
            // De otro modo, creo primero un tag de ese tipo y lo relleno.
            if(element.tagName.toLowerCase() !== 'prontus_insert') {
                element = tinymce.activeEditor.selection.setNode(tinymce.activeEditor.dom.create('prontus_insert', attrs, the_content));
            }
            return true;
        };

        // si el cursor está sobre un elemento Include Prontus, tomamos los datos y rellenamos los campos.
        var getData = function (editor) {
            var element = editor.selection.getNode();
            var data_type = element.getAttribute('data-type');
            var data_code = element.getAttribute('data-code');
            var data_src = element.getAttribute('data-src');
            var the_data = {
                include_type: 'include', // js | include
                js_path: '',
                js_code: '', // no deberían estar llenos nunca js_path, js_code e include_path a la vez.
                js_select: '',
                include_select: '',
                include_path: ''
            }
            switch (data_type) {
                case 'js':
                    the_data.include_type = 'js';
                    if (typeof data_code != 'undefined' && data_code) {
                        the_data.js_select = 'code';
                        the_data.js_code = tinymce.activeEditor.dom.decode(data_code);
                    } else {
                        the_data.js_select = 'file';
                        the_data.js_path = data_src;
                    }
                    break;
                case 'php':
                    the_data.include_type = 'include';
                    the_data.include_select = 'php';
                    the_data.include_path = data_src;
                    break;
                case 'ssi':
                    the_data.include_type = 'include';
                    the_data.include_select = 'ssi';
                    the_data.include_path = data_src;
                    break;
                case 'ssi_virtual':
                    the_data.include_type = 'include';
                    the_data.include_select = 'ssi_virtual';
                    the_data.include_path = data_src;
                    break;
                default:
                    the_data.include_type = 'include';
                    the_data.include_select = 'php';
                    the_data.include_path = data_src;
                    break;
            }
            return the_data;
        };

        var windowOpener = {
            open: function (editor) {
                // datos recibidos por el modal desde el editor.
                var field_data = getData(editor);
                var the_window;

                /* selector de tipo de include no js */
                var embedSourceDropdown = {
                    id: "mcesourcedropdown",
                    type: "listbox",
                    name: 'insert_html_type',
                    ariaLabel: 'Tipo',
                    values: [{
                        text: 'PHP',
                        value: 'php'
                    }, {
                        text: 'Include SSI',
                        value: 'ssi'
                    }, {
                        text: 'Include SSI virtual',
                        value: 'ssi_virtual'
                    }],
                    onPostRender: function () {
                        // seleccionamos el campo correcto según el dato elegido.
                        this.value(field_data.include_select);
                    }
                }

                /* campo para ingreso de path a archivo incluído no js */
                var embedSourceTextField = {
                    id: 'mcesourcetext',
                    type: 'textbox',
                    flex: 0,
                    placeholder: 'Path al archivo',
                    name: 'insert_file',
                    value: field_data.include_type == 'include' ? field_data.include_path : '',
                    rows: 1,
                    multiline: false,
                    ariaLabel: 'Source'
                };

                // determina qué campo de input para js se mostrará al abrir el modal.
                var showJsTextField = field_data.include_type == 'js' && field_data.js_select == 'file' ? false : true;

                /* campo para ingreso de path a archivo incluído de tipo js */
                var embedJsTextField = {
                    id: 'mcejslink',
                    type: 'textbox',
                    flex: 1,
                    placeholder: 'Path al archivo JavaScript',
                    name: 'insert_js_file',
                    value: field_data.include_type == 'js' ? field_data.js_path : '',
                    rows: 1,
                    multiline: false,
                    ariaLabel: 'Source',
                    disabled: showJsTextField,
                    hidden: showJsTextField
                };

                /* campo para ingreso de código JS. */
                var embedJsTextBox = {
                    id: 'mcejstext',
                    type: 'textbox',
                    flex: 1,
                    placeholder: 'Ingresa código JavaScript aquí',
                    name: 'insert_js_code',
                    value: field_data.js_select == 'code' ? field_data.js_code : '',
                    multiline: true,
                    rows: 5,
                    ariaLabel: 'Source',
                    disabled: !showJsTextField,
                    hidden: !showJsTextField
                };

                /* selector de tipo de include js: path a archivo o código. */
                var embedJsDropdown = {
                    id: "mcejsdropdown",
                    type: "listbox",
                    name: 'insert_js_type',
                    ariaLabel: 'Tipo',
                    onSelect: function (e) {
                        var select_data = this.value();
                        this.parent().parent().fromJSON(select_data);
                        // obtenemos los controles de texto a ocultar y mostrar. TODO: ver si hay mejor modo de obtener los items.
                        var items = this.parent().items();
                        if (select_data == 'file') {
                            items[3].disabled(false).visible(true);
                            items[4].disabled(true).visible(false);
                        } else {
                            items[4].disabled(false).visible(true);
                            items[3].disabled(true).visible(false);
                        }
                    },
                    values: [{
                        text: 'Código JavaScript',
                        value: 'code'
                    }, {
                        text: 'Archivo JavaScript externo',
                        value: 'file'
                    }],
                    onPostRender: function () {
                        // seleccionamos el campo correcto según el dato elegido.
                        if (field_data.js_select == '') {
                            field_data.js_select = 'code';
                        }
                        this.value(field_data.js_select);
                    }
                }

                /* texto descriptivo */
                var embedHelpBox = {
                    type: 'label',
                    multiline: true,
                    layout: 'flex',
                    text: "",
                    onPostRender: function (e) { // se hace de este modo para poder poner código html en el mensaje.
                        this.getEl().innerHTML = "<b>Importante</b>: La representación en el VTXT es sólo gráfica, a modo de ayuda.<br> Dependiendo del HTML incluído el resultado podría ser diferente. <br>No coloques 2 o más bloques \"Insert\" seguidos: el editor dejará sólo el primero."
                    },
                    style: "border:none;",
                }

                // tab para incluir archivos via PHP/SSI.
                var includeItems = [{
                    type: 'container',
                    layout: 'flex',
                    direction: 'column',
                    align: 'stretch',
                    padding: 10,
                    spacing: 10,
                    items: [{
                            type: 'label',
                            text: 'Agrega el path al archivo:'
                        },
                        embedSourceDropdown,
                        {
                            type: 'label',
                            multiline: true,
                            layout: 'flex',
                            text: "",
                            onPostRender: function () {
                                this.getEl().innerHTML = "Indica el tipo de include que usa tu sitio web.<br><br>Indica la ruta absoluta al archivo."
                            },
                            style: "border:none;"
                        },
                        embedSourceTextField,
                        embedHelpBox
                    ]
                }];
                // tab para incluir código o archivo js.
                var javascriptItems = [{
                    type: 'container',
                    layout: 'flex',
                    direction: 'column',
                    align: 'stretch',
                    padding: 10,
                    spacing: 10,
                    items: [,
                        {
                            type: 'label',
                            multiline: true,
                            layout: 'flex',
                            text: "",
                            onPostRender: function () {
                                this.getEl().innerHTML = "Puedes insertar código directamente, o un enlace a un archivo JavaScript externo.<br>Verifica la correcta sintaxis y lógica del código."
                            },
                            style: "border:none;"
                        },
                        {
                            type: 'label',
                            text: 'Inserta el código JavaScript debajo:',
                        },
                        embedJsDropdown,
                        embedJsTextField,
                        embedJsTextBox,
                        embedHelpBox
                    ]
                }];

                the_window = editor.windowManager.open({
                    title: 'Administrar Includes',
                    data: field_data,
                    bodyType: 'tabpanel',
                    stateSelector: ['prontus_insert'],
                    body: [{
                            title: 'Incluir un Archivo',
                            type: 'form',
                            items: includeItems,
                        },
                        {
                            title: 'Insertar JavaScript',
                            type: 'form',
                            items: javascriptItems,
                        }
                    ],
                    onPostRender: function (e) {
                        if (field_data.js_select == 'file') {
                            embedJsTextField.disabled = false;
                            embedJsTextField.hidden = false;
                            embedJsTextBox.disabled = true;
                            embedJsTextBox.hidden = true;
                        } else {
                            embedJsTextField.disabled = true;
                            embedJsTextField.hidden = true;
                            embedJsTextBox.disabled = false;
                            embedJsTextBox.hidden = false;
                        }
                        // muestra el tab de Javascript o de includes PHP/SSI según corresponda. TODO: encontrar un modo mejor.
                        this.items()[0].activateTab(field_data['include_type'] == 'js' ? 1 : 0);
                    },
                    onSubmit: function () {
                        submitForm(the_window, editor);
                    }
                });
            }
        };

        var registerButton = {
            register: function (editor) {
                editor.addButton('prontus_insert', {
                    icon: 'far fa-file-code',
                    tooltip: 'Administrar includes SSI/PHP/JavaScript',
                    onclick: function () {
                        windowOpener.open(editor);
                    }
                });
            }
        };

        tinymce.PluginManager.add('prontus_insert', function (editor, url) {
            registerButton.register(editor);
        });

        function Plugin() {}

        return Plugin;

    }());
})();
