// Register TinyMCE plugin
(function() {

    tinymce.create('tinymce.plugins.LinkBrowser', {
        init : function(ed) {
            ed.addCommand('mceConflink', AJS.Editor.LinkBrowser.open);
            ed.addCommand('mceConfAttachments', function () {
                return AJS.Editor.LinkBrowser.open({
                    panelId: AJS.Editor.LinkBrowser.ATTACHMENTS_PANEL_ID
                });                
            }); // attachments item in insert menu

            ed.addButton("linkbrowserButton", {title: "confluence.conflink_desc", cmd: "mceConflink", "class": "mce_conflink" });
            ed.addShortcut("ctrl+k", ed.getLang("confluence.conflink_desc"), "mceConflink");
        },
        getInfo : function () {
            return {
                longname : "Confluence Link Browser",
                author : "Atlassian",
                authorurl : "http://www.atlassian.com",
                version : tinymce.majorVersion + "." + tinymce.minorVersion
            };
        }
    });

    tinymce.PluginManager.add('linkbrowser', tinymce.plugins.LinkBrowser);
})();

AJS.Editor.Adapter.addTinyMcePluginInit(function(settings) {
    settings.plugins += ",linkbrowser";
    var buttons = settings.theme_advanced_buttons1;
    var index = buttons.indexOf("confimage");
    settings.theme_advanced_buttons1 = buttons.substring(0, index) + "linkbrowserButton," + buttons.substring(index);
});

AJS.Editor.LinkBrowser = (function($) {

    var loadI18nThen = function (open) {
    	if (window.LinkBrowserI18n) {
	       open();
	    }
	    else {
            AJS.I18n.get("com.atlassian.confluence.plugins.linkbrowser", function(i18n) {
                window.LinkBrowserI18n = i18n;
                open();
            }, function() {
                alert("There was an error loading the link browser, please try again");
            });
	    }    	
    	return false;
    },

    makeRichTextLinkInfo = function (linkAlias) {
        var t = AJS.Editor.LinkBrowser,
            selectedNode = tinyMCE.activeEditor.selection.getNode(),
            linkNode = $(selectedNode);

        if (linkNode.is("a[href]")) {
            var location = linkNode.attr("wikidestination");
            if (location){
                // for RTE links, we need to see if the alias was put there by the user or by the link renderer
                var alias = null;
                if (linkNode.attr("aliasspecified") == "true")
                {
                    alias = linkNode.text();
                }
                t.selectedNode = selectedNode;
                return t.loadRTELink(location, alias);
            }
        }

        if (linkAlias && linkAlias.length) {
            return t.loadSelection(linkAlias);
        }
    },

    makeMarkupLinkInfo = function (linkAlias) {
        var t = AJS.Editor.LinkBrowser,
            wikiLink = getSelectedWikiLink();

        if (wikiLink) {
            return t.parseWikiLink(wikiLink);
        }

        if (linkAlias && linkAlias.length) {
            return t.loadSelection(linkAlias);
        }
    },

    restoreSelection = function() {
        if (AJS.Editor.inRichTextMode())
            AJS.Editor.Adapter.restoreSelectionState();
        else
            restoreMarkupSelection();
    },

    storeMarkupSelection = function() {
        var t = AJS.Editor.LinkBrowser,
            textarea = $("#markupTextarea");

        t.selection = textarea.selectionRange();
        t.scrollTop = textarea.scrollTop();
        return t.selection.text;
    },

    restoreMarkupSelection = function() {
        var t = AJS.Editor.LinkBrowser,
            textarea = $("#markupTextarea");

        if (t.selection) {
            textarea.selectionRange(t.selection.start, t.selection.end);
        }
        textarea.scrollTop(t.scrollTop);
    },

    getSelectedWikiLink = function() {
    	var t = AJS.Editor.LinkBrowser,
	        textarea = $("#markupTextarea");

    	var beforeSelection = t.selection.textBefore;
    	var wikiText = textarea.val();

    	var m = /^(?:.|\n)*[^\\](?=\[(?:\\\]|[^\]])+$)/m.exec(" " + beforeSelection + " "); // spaces required for when [ is the first or last character
    	if (!m) return null;

    	var startIndex = m[0].substring(1).length;

    	// now try and find the end of the link we're inside of
    	m = /\[((?:\\\]|[^\]])+)\]/m.exec(wikiText.substring(startIndex));
    	if (!m) return null;

    	textarea.selectionRange(startIndex, startIndex + m[0].length);
    	t.selection = textarea.selectionRange();
    	return m[1];
    };

    return {

    ATTACHMENTS_PANEL_ID: "attachments-panel-id",
    WEBLINK_PANEL_ID: "weblink-panel-id",

    /**
     * Loads any I18N required and then launches the dialog.
     *
     * If the options include an "opener" function, that is used to launch the dialog; otherwise a LinkInfo object is
     * created for the current Editor and the default launcher called.
     *
     * @param options : panelId - (optional) a panel of the Link Browser to open to
     *                  gwtOpener - (optional) a GWT function used to launch the Link Browser
     */
    open: function(options) {
        options = options || {};
        return loadI18nThen(function () {
            
        	// prevent it from opening if another popup dialog is open
        	if ($('.popup.dialog:visible').length){
        		return false;
        	}
        	
            var linkAlias, isRTE = AJS.Editor.inRichTextMode();

            // Store the current selection and scroll position, and get the selected text.
            if (isRTE) {
                AJS.Editor.Adapter.storeCurrentSelectionState();
                linkAlias = tinyMCE.activeEditor.selection.getContent({format : 'text'});
            } else {
                linkAlias = storeMarkupSelection();
            }

            if (options.gwtOpener) {
                // Any supplied opener function must include required state in its scope.
                options.gwtOpener(linkAlias);
            } else {
                var linkInfo = isRTE ? makeRichTextLinkInfo(linkAlias) : makeMarkupLinkInfo(linkAlias);
                AJS.Editor.LinkBrowser.openDialog(linkInfo, options.panelId || "");
            }

            // Close the Link Browser on Escape key
            $(document).keydown(function (e) {
                if (e.keyCode == 27 && !AJS.dropDown.current)  {
                    $("#link-browser-cancel").click();
                    $(document).unbind("keydown", arguments.callee);
                    return AJS.stopEvent(e);
                }
            });            
        });
    },

    // Called from GWT
    cancel: function() {
        restoreSelection();
        AJS.Editor.LinkBrowser.selectedNode = null;
    },

    // Called from GWT
    insert: function(destination, alias, href, aliasspecified, markup) {
        restoreSelection();
        if (AJS.Editor.inRichTextMode()) {
            var linkDetails = {destination: destination, alias: alias, href: href, aliasspecified: aliasspecified};

            AJS.Editor.Adapter.insertLink(linkDetails, AJS.Editor.LinkBrowser.selectedNode);
            AJS.Editor.LinkBrowser.selectedNode = null;
        }
        else {
            var textArea = $("#markupTextarea");
            textArea.selection("[" + markup + "]");
            var selection = textArea.selectionRange();
            textArea.selectionRange(selection.end, selection.end);
        }
    },

    // Called from GWT
    bindUploadAttachment: function(formElement, onSubmit, onError, onSuccess) {
        var form = $(formElement);
        form.ajaxForm({
            dataType: "json",
            data: {
                contentId: AJS.params.attachmentSourceContentId,
                responseFormat: "html" // ensure response comes back as HTML for IE compatibility
            },
            resetForm: true,
            beforeSubmit: function () {
                onSubmit();
            },
            error: function (xhr) {
                onError([xhr.responseText]);
            },
            success: function (response) {
                if (response.actionErrors) {
                    onError(response.actionErrors);
                }
                else if(response.attachmentsAdded) {
                    onSuccess(response.attachmentsAdded);
                }
            }
        });
        form.find("input:file").change(function () { form.submit(); });
    }
};})(AJS.$);

AJS.toInit(function ($) {
    $("#editor-insert-link").click(function(e) {
        AJS.Editor.LinkBrowser.open();
        return AJS.stopEvent(e);
    });

    $("#markupTextarea").keyup(function (e) {
        if (e.ctrlKey && e.keyCode == 75) {// bind ctrl+k to insert link
            $("#editor-insert-link").click();
            return AJS.stopEvent(e);
        }

    }).keydown(function (e) {
        // prevent firefox's default behaviour
        if (e.ctrlKey && e.keyCode == 75) {
            return AJS.stopEvent(e);
        }
    });
});


