/*
*  Custom Ace Editor plugin.
*  In order for this to integrate cleanly with html, preserving whitespace, a couple
*  of files needed to be modified:
*      core/tools.js: trim(), ltrim(), rtrim() - to preserve whitespace in wysiwyg
*      core/htmlparser/fragment.js: parser.onText() - to preserve whitespace in wysiwyg
*
*  UPDATE: the changes above were reverted as html itself was getting stripped out
*/

(function(cke) {

    cke.plugins.add('ace-adapter', {
        icons: 'ace-adapter',
        init: function(editor) {
            var rootPath = this.path
                , editorId = 'editor1'
                , aceMode = 'ace'
                , aceEditorId = 'aa-editor'
            //     , jsonPattern = /^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/
            //     // patterns like /*% custom comment %*/
            //     // to set a syntax mode from promo editor, use /*% syntax:javascript %*/
            //     , customCommentPattern = /^\/\*%((?:.|\n)*?)?%\*\/\n/m
                , setSize = function(aceEl) {
                        aceEl.setSize('width', editor.ui.space('contents').getSize('width'));
                        aceEl.setSize('height', editor.ui.space('contents').getSize('height'));
                        if (window.aceEditor) {
                            window.aceEditor.resize();
                        }
                    }
                ;

             // load ace.js first
            cke.scriptLoader.load('js/ace/src-min-noconflict/ace.js', function (pass, fail) {

                // if ace.js loads, load all themes, modes, etc.
                if (pass === true) {

                    // eventually put this array in the config
                    cke.scriptLoader.load([
                        'js/ace/src-min-noconflict/ext-elastic_tabstops_lite.js',
                        'js/ace/src-min-noconflict/ext-emmet.js',
                        'js/ace/src-min-noconflict/ext-keybinding_menu.js',
                        'js/ace/src-min-noconflict/ext-modelist.js',
                        'js/ace/src-min-noconflict/ext-options.js',
                        'js/ace/src-min-noconflict/ext-searchbox.js',
                        'js/ace/src-min-noconflict/ext-settings_menu.js',
                        'js/ace/src-min-noconflict/ext-spellcheck.js',
                        'js/ace/src-min-noconflict/ext-static_highlight.js',
                        'js/ace/src-min-noconflict/ext-statusbar.js',
                        'js/ace/src-min-noconflict/ext-textarea.js',
                        'js/ace/src-min-noconflict/ext-themelist.js',
                        'js/ace/src-min-noconflict/ext-whitespace.js',

                        'js/ace/src-min-noconflict/keybinding-emacs.js',
                        'js/ace/src-min-noconflict/keybinding-vim.js',

                        'js/ace/src-min-noconflict/mode-abap.js',
                        'js/ace/src-min-noconflict/mode-actionscript.js',
                        'js/ace/src-min-noconflict/mode-ada.js',
                        'js/ace/src-min-noconflict/mode-asciidoc.js',
                        'js/ace/src-min-noconflict/mode-assembly_x86.js',
                        'js/ace/src-min-noconflict/mode-autohotkey.js',
                        'js/ace/src-min-noconflict/mode-batchfile.js',
                        'js/ace/src-min-noconflict/mode-c9search.js',
                        'js/ace/src-min-noconflict/mode-c_cpp.js',
                        'js/ace/src-min-noconflict/mode-clojure.js',
                        'js/ace/src-min-noconflict/mode-cobol.js',
                        'js/ace/src-min-noconflict/mode-coffee.js',
                        'js/ace/src-min-noconflict/mode-coldfusion.js',
                        'js/ace/src-min-noconflict/mode-csharp.js',
                        'js/ace/src-min-noconflict/mode-css.js',
                        'js/ace/src-min-noconflict/mode-curly.js',
                        'js/ace/src-min-noconflict/mode-d.js',
                        'js/ace/src-min-noconflict/mode-dart.js',
                        'js/ace/src-min-noconflict/mode-diff.js',
                        'js/ace/src-min-noconflict/mode-django.js',
                        'js/ace/src-min-noconflict/mode-dot.js',
                        'js/ace/src-min-noconflict/mode-ejs.js',
                        'js/ace/src-min-noconflict/mode-erlang.js',
                        'js/ace/src-min-noconflict/mode-forth.js',
                        'js/ace/src-min-noconflict/mode-ftl.js',
                        'js/ace/src-min-noconflict/mode-glsl.js',
                        'js/ace/src-min-noconflict/mode-golang.js',
                        'js/ace/src-min-noconflict/mode-groovy.js',
                        'js/ace/src-min-noconflict/mode-haml.js',
                        'js/ace/src-min-noconflict/mode-haskell.js',
                        'js/ace/src-min-noconflict/mode-haxe.js',
                        'js/ace/src-min-noconflict/mode-html.js',
                        'js/ace/src-min-noconflict/mode-html_ruby.js',
                        'js/ace/src-min-noconflict/mode-ini.js',
                        'js/ace/src-min-noconflict/mode-jade.js',
                        'js/ace/src-min-noconflict/mode-java.js',
                        'js/ace/src-min-noconflict/mode-javascript.js',
                        'js/ace/src-min-noconflict/mode-json.js',
                        'js/ace/src-min-noconflict/mode-jsoniq.js',
                        'js/ace/src-min-noconflict/mode-jsp.js',
                        'js/ace/src-min-noconflict/mode-jsx.js',
                        'js/ace/src-min-noconflict/mode-julia.js',
                        'js/ace/src-min-noconflict/mode-latex.js',
                        'js/ace/src-min-noconflict/mode-less.js',
                        'js/ace/src-min-noconflict/mode-liquid.js',
                        'js/ace/src-min-noconflict/mode-lisp.js',
                        'js/ace/src-min-noconflict/mode-livescript.js',
                        'js/ace/src-min-noconflict/mode-logiql.js',
                        'js/ace/src-min-noconflict/mode-lsl.js',
                        'js/ace/src-min-noconflict/mode-lua.js',
                        'js/ace/src-min-noconflict/mode-luapage.js',
                        'js/ace/src-min-noconflict/mode-lucene.js',
                        'js/ace/src-min-noconflict/mode-makefile.js',
                        'js/ace/src-min-noconflict/mode-markdown.js',
                        'js/ace/src-min-noconflict/mode-matlab.js',
                        'js/ace/src-min-noconflict/mode-mushcode.js',
                        'js/ace/src-min-noconflict/mode-mushcode_high_rules.js',
                        'js/ace/src-min-noconflict/mode-mysql.js',
                        'js/ace/src-min-noconflict/mode-objectivec.js',
                        'js/ace/src-min-noconflict/mode-ocaml.js',
                        'js/ace/src-min-noconflict/mode-pascal.js',
                        'js/ace/src-min-noconflict/mode-perl.js',
                        'js/ace/src-min-noconflict/mode-pgsql.js',
                        'js/ace/src-min-noconflict/mode-php.js',
                        'js/ace/src-min-noconflict/mode-powershell.js',
                        'js/ace/src-min-noconflict/mode-prolog.js',
                        'js/ace/src-min-noconflict/mode-properties.js',
                        'js/ace/src-min-noconflict/mode-python.js',
                        'js/ace/src-min-noconflict/mode-r.js',
                        'js/ace/src-min-noconflict/mode-rdoc.js',
                        'js/ace/src-min-noconflict/mode-rhtml.js',
                        'js/ace/src-min-noconflict/mode-ruby.js',
                        'js/ace/src-min-noconflict/mode-rust.js',
                        'js/ace/src-min-noconflict/mode-sass.js',
                        'js/ace/src-min-noconflict/mode-scad.js',
                        'js/ace/src-min-noconflict/mode-scala.js',
                        'js/ace/src-min-noconflict/mode-scheme.js',
                        'js/ace/src-min-noconflict/mode-scss.js',
                        'js/ace/src-min-noconflict/mode-sh.js',
                        'js/ace/src-min-noconflict/mode-snippets.js',
                        'js/ace/src-min-noconflict/mode-sql.js',
                        'js/ace/src-min-noconflict/mode-stylus.js',
                        'js/ace/src-min-noconflict/mode-svg.js',
                        'js/ace/src-min-noconflict/mode-tcl.js',
                        'js/ace/src-min-noconflict/mode-tex.js',
                        'js/ace/src-min-noconflict/mode-text.js',
                        'js/ace/src-min-noconflict/mode-textile.js',
                        'js/ace/src-min-noconflict/mode-tmsnippet.js',
                        'js/ace/src-min-noconflict/mode-toml.js',
                        'js/ace/src-min-noconflict/mode-twig.js',
                        'js/ace/src-min-noconflict/mode-typescript.js',
                        'js/ace/src-min-noconflict/mode-vbscript.js',
                        'js/ace/src-min-noconflict/mode-velocity.js',
                        'js/ace/src-min-noconflict/mode-verilog.js',
                        'js/ace/src-min-noconflict/mode-xml.js',
                        'js/ace/src-min-noconflict/mode-xquery.js',
                        'js/ace/src-min-noconflict/mode-yaml.js',

                        'js/ace/src-min-noconflict/theme-ambiance.js',
                        'js/ace/src-min-noconflict/theme-chaos.js',
                        'js/ace/src-min-noconflict/theme-chrome.js',
                        'js/ace/src-min-noconflict/theme-clouds.js',
                        'js/ace/src-min-noconflict/theme-clouds_midnight.js',
                        'js/ace/src-min-noconflict/theme-cobalt.js',
                        'js/ace/src-min-noconflict/theme-crimson_editor.js',
                        'js/ace/src-min-noconflict/theme-dawn.js',
                        'js/ace/src-min-noconflict/theme-dreamweaver.js',
                        'js/ace/src-min-noconflict/theme-eclipse.js',
                        'js/ace/src-min-noconflict/theme-github.js',
                        'js/ace/src-min-noconflict/theme-idle_fingers.js',
                        'js/ace/src-min-noconflict/theme-kr.js',
                        'js/ace/src-min-noconflict/theme-merbivore.js',
                        'js/ace/src-min-noconflict/theme-merbivore_soft.js',
                        'js/ace/src-min-noconflict/theme-mono_industrial.js',
                        'js/ace/src-min-noconflict/theme-monokai.js',
                        'js/ace/src-min-noconflict/theme-pastel_on_dark.js',
                        'js/ace/src-min-noconflict/theme-solarized_dark.js',
                        'js/ace/src-min-noconflict/theme-solarized_light.js',
                        'js/ace/src-min-noconflict/theme-terminal.js',
                        'js/ace/src-min-noconflict/theme-textmate.js',
                        'js/ace/src-min-noconflict/theme-tomorrow.js',
                        'js/ace/src-min-noconflict/theme-tomorrow_night.js',
                        'js/ace/src-min-noconflict/theme-tomorrow_night_blue.js',
                        'js/ace/src-min-noconflict/theme-tomorrow_night_bright.js',
                        'js/ace/src-min-noconflict/theme-tomorrow_night_eighties.js',
                        'js/ace/src-min-noconflict/theme-twilight.js',
                        'js/ace/src-min-noconflict/theme-vibrant_ink.js',
                        'js/ace/src-min-noconflict/theme-xcode.js',

                        'js/ace/src-min-noconflict/worker-coffee.js',
                        'js/ace/src-min-noconflict/worker-css.js',
                        'js/ace/src-min-noconflict/worker-javascript.js',
                        'js/ace/src-min-noconflict/worker-json.js',
                        'js/ace/src-min-noconflict/worker-lua.js',
                        'js/ace/src-min-noconflict/worker-php.js',
                        'js/ace/src-min-noconflict/worker-xquery.js'
                    ], function (success, failure) {
                        console.info('loaded ' + success.length + ' ace scripts');
                    });

                } else {
                    console.error('Could not load ace.js!');
                }

            });

            window.editor = editor;
            // editor.config.protectedSource.push( jsonPattern );
            // editor.dataProcessor.writer.lineBreakChars = '\n';

            editor.addMode(aceMode, function(callback) {
                // console.log('aceMode active');

                var contentsSpace = editor.ui.space('contents')
                    , aceElement = contentsSpace.getDocument().createElement('div')
                    , editorData = editor.getData()
                    , cookieThemeKey = 'aceTheme-promoEditor'
                    , aceEditor, aceEditorSession, commentMatches, i, comment, syntaxStr, cookieData, theme
                    ;

                // fix FF bug which adds preceding <br /> to non-html or empty content
                if (cke.env.gecko) {
                    // console.log('in FF');
                    editor.setData(editorData.replace(/^<br\s*\/>\s*/, ''));
                    editorData = editor.getData();
                }

                // ensure trailing newline
                // if (!/\n$/.test(editorData)) {
                //     editorData += "\n";
                //     editor.setData(editorData);
                // }

                // console.log('editor.getData()', editor.getData());
                aceElement.setAttribute('id', aceEditorId);
                setSize(aceElement);
                // aceElement.setSize('width', contentsSpace.getSize('width'));
                // aceElement.setSize('height', contentsSpace.getSize('height'));
                aceElement.setHtml(
                    editorData
                        .replace(/&/g,'&amp;')
                        .replace(/</g,'&lt;')
                        .replace(/>/g,'&gt;')
                );
                window.aceElement = aceElement;

                editor.ui.space('contents').append(aceElement);

                // initialize the ACE editor
                aceEditor = ace.edit(aceEditorId);
                // aceEditor.setShowInvisibles(true);

                // look for saved theme in cookie
                theme = 'monokai';
                // if ($ && $.cookie) {
                //     cookieData = $.cookie(cookieThemeKey);
                //     // console.log('cookieData:', cookieData);
                //     if (cookieData && cookieData.length) {
                //         theme = cookieData;
                //     }
                // }
                // // update select list. if theme doesnt exist (bad cookie?) use default
                // var $opt = $('option[value="' + theme + '"]');
                // if ($opt.length) {
                //     $opt.attr('selected', 'true');
                // }
                // set the theme
                aceEditor.setTheme('ace/theme/' + theme);

                // save ace editor to window for debugging and global reference
                window.aceEditor = aceEditor;
                // console.log('aceEditor.getValue()', aceEditor.getValue());

                aceEditorSession = aceEditor.getSession();
                aceEditorSession.setMode("ace/mode/html"); // temporary. eventually utilize code below.

                // look for custom comments which define desired syntax
                // commentMatches = customCommentPattern.exec(editorData);
                // if (commentMatches !== null) {
                //     comment = commentMatches[1].replace(/^\s+|\s+$/g, '');
                //     syntaxStr = /syntax:([a-z]+)(?=\b)/i.exec(comment);
                //     if (syntaxStr !== null) {
                //         aceEditorSession.setMode("ace/mode/" + syntaxStr[1].toLowerCase());
                //     }

                // } else if (jsonPattern.test(editorData)) {
                //     aceEditorSession.setMode("ace/mode/json");

                // } else {
                //     aceEditorSession.setMode("ace/mode/html");
                // }
                // console.log('aceEditorSession.getMode().$id', aceEditorSession.getMode().$id);

                // aceEditorSession.on('change', function(e) {
                //     editor.setData(window.aceEditor.getValue().replace(/\s{2,}$/, '\n'));
                //     editor.updateElement();
                // });
                // // aceEditorSession.setUseWrapMode(true);

                // callback();
            });



            editor.addCommand('ace-edit', {
                // make sure the ace property matches aceMode
                modes: {
                    "wysiwyg": 1,
                    "ace": 1,
                    "source":  0
                },

                exec: function(editor) {
                    var aceElement = editor.ui.space('contents').getDocument().getById(aceEditorId)
                        ;

                    console.log('window.savedMode = ', window.savedMode);

                    // go into ace mode
                    if (!window.savedMode) {
                        // console.log('setting editor.mode = ', aceMode);
                        window.savedMode = editor.mode;
                        // editor.fire( 'saveSnapshot' );
                        editor.setMode(aceMode);
                        // show ace controls; timeout allows ace editor to setup
                        // setTimeout(function () { $(document).trigger('aceModeOn'); }, 200);

                    // go OUT of ace mode
                    } else {
                        // hide ace and show wysiwyg
                        editor.setData(window.aceEditor.getValue());
                        //console.log('editor.getSnapshot()', editor.getSnapshot()); // default state (last snapshot)
                        editor.updateElement();  // update original textarea
                        //console.log(document.getElementById( editorId ).value); //check original textarea for updates
                        editor.setMode(window.savedMode);

                        // cleanup
                        if (window.aceEditor) {
                            window.aceEditor.destroy();
                            delete window.aceElement;
                        }
                        // hide ace controls
                        // $(document).trigger('aceModeOff');
                    }

                    console.log('NEW window.savedMode = ', window.savedMode);

                    // console.log('new editor.mode = ', editor.mode);
                    // console.log(editor.ui.space('contents'));
                }
            });


            // add the button in the toolbar and hook it to the correct command
            editor.ui.addButton('Ace-Adapter', {
                label: 'Ace',
                command: 'ace-edit',
                toolbar: 'mode'
            });


            // ensure ace editor size matches ckeditor size
            editor.on('resize', function (e) {
                if (window.aceElement) {
                    setSize(window.aceElement);
                }
            });


            // editor.on('mode', function () {
            //     editor.getCommand(aceMode).setState(cke.TRISTATE_ON);
            // });
        }
    });

})(CKEDITOR);
