function bpFieldInitTinyMceElement(element) {
    // grab the configuration defined in PHP
    let configuration = element.data('options');

    // disable promotion button
    configuration['promotion'] = false;

    // the target should be the element the function has been called on
    configuration['target'] = element;
    configuration['file_picker_callback'] = eval(configuration['file_picker_callback']);


    // automatically update the textarea value on editor change
    configuration['setup'] = function (editor) {
         editor.on('change', function(e) {
            let hasOriginalEvent = typeof e.originalEvent !== 'undefined';
            // in case there is an original event, we make sure it's NOT our own `save()` event
            // avoiding re-triggering the change event twice.
            if(hasOriginalEvent && e.originalEvent.type !== 'savecontent') {
                // save only the current editor.
                editor.save();
                element.trigger('change');
            }

            // in case there is no original event, it means the change migth have already 
            // ocurred, for example, when adding an image or a link from the toolbar.
            // we just make sure that the process is complete and we have content
            if(!hasOriginalEvent && typeof e.level.content !== 'undefined') {
                editor.save();
                element.trigger('change');
            }
        });

        editor.on('input', function(e) {
            // only update the textarea in case the input is a text insertion,
            // other types of inputs like paste etc are handled in the
            // change event. 
            if(e.inputType === 'insertText') {
                editor.save();
                element.trigger('change');
            }
        });

        editor.on('Undo Redo', function(e) {
            editor.save();
            element.trigger('change');
        });

        editor.on('init', function() {
            setTinyMceBackgroundColor(editor);
        });
    };

    function isTinyMceEditorInDarkMode() {
        return typeof colorMode !== 'undefined' && colorMode.result === 'dark';
    }

    function setTinyMceColorMode() {
        configuration['skin'] = isTinyMceEditorInDarkMode() ? 'oxide-dark' : 'oxide';
        configuration['content_css'] = isTinyMceEditorInDarkMode() ? 'dark' : '';
    }

    function setTinyMceBackgroundColor(editor) {
        let iframeDocument = editor.contentDocument || editor.contentWindow.document;
        let body = iframeDocument.getElementsByTagName('body')[0];
        body.style.cssText = isTinyMceEditorInDarkMode() ? 'background-color: #221e26; color: #c9c1d6;' : 'background-color: #fff;';
    }

    function getTinyMceEditorId()
    {
        return configuration['target'][0].getAttribute('id');
    }

    // register a listener for color change that will update the tinymce skin 
    // and re-initialize the editor instances
    if(typeof colorMode !== 'undefined') {
        colorMode.onChange(function() {
            let editorId = getTinyMceEditorId();
            let editorInstance = tinymce.get(editorId);

            editorInstance.remove();

            setTinyMceColorMode();
            tinymce.init(configuration);                
        });
    }

    //set the color mode before initialization:
    setTinyMceColorMode();

    // initialize the TinyMCE editor
    tinymce.init(configuration);

    element.on('CrudField:disable', function(e) {
        let editorId = getTinyMceEditorId();
        let editorInstance = tinymce.get(editorId);
        editorInstance.focus();
        tinymce.activeEditor.mode.set('readonly');
    });

    element.on('CrudField:enable', function(e) {
        let editorId = getTinyMceEditorId();
        let editorInstance = tinymce.get(editorId);
        editorInstance.focus();
        tinymce.activeEditor.mode.set('design');
    });
}

function elFinderBrowser (callback, value, meta) {
    tinymce.activeEditor.windowManager.openUrl({
        title: 'elFinder 2.0',
        url: 'https://dev.legal.com/admin/elfinder/tinymce5',
        width: 900,
        height: 460,
        onMessage: function (dialogApi, details) {
            if (details.mceAction === 'fileSelected') {
                const file = details.data.file;

                // Make file info
                const info = file.name;

                // Provide file and text for the link dialog
                if (meta.filetype === 'file') {
                    callback(file.url, {text: info, title: info});
                }

                // Provide image and alt text for the image dialog
                if (meta.filetype === 'image') {
                    callback(file.url, {alt: info});
                }

                // Provide alternative source and posted for the media dialog
                if (meta.filetype === 'media') {
                    callback(file.url);
                }

                dialogApi.close();
            }
        }
    });
}

