/*!
 * Code block dialog plugin for Editor.md
 *
 * @file        code-block-dialog.js
 * @author      pandao
 * @version     1.2.0
 * @updateTime  2015-03-07
 * {@link       https://github.com/pandao/editor.md}
 * @license     MIT
 */

(function() {

    var factory = function (exports) {
		var cmEditor;
		var pluginName    = "code-block-dialog";
    
		// for CodeBlock dialog select
		var codeLanguages = exports.codeLanguages = {
			asp           : ["ASP", "vbscript"],
			actionscript  : ["ActionScript(3.0)/Flash/Flex", "clike"],
			bash          : ["Bash/Bat", "shell"],
			css           : ["CSS", "css"],
			c             : ["C", "clike"],
			cpp           : ["C++", "clike"],
			csharp        : ["C#", "clike"],
			coffeescript  : ["CoffeeScript", "coffeescript"],
			d             : ["D", "d"],
			dart          : ["Dart", "dart"],
			delphi        : ["Delphi/Pascal", "pascal"],
			erlang        : ["Erlang", "erlang"],
			go            : ["Golang", "go"],
			groovy        : ["Groovy", "groovy"],
			html          : ["HTML", "text/html"],
			java          : ["Java", "clike"],
			json          : ["JSON", "text/json"],
			javascript    : ["Javascript", "javascript"],
			lua           : ["Lua", "lua"],
			less          : ["LESS", "css"],
			markdown      : ["Markdown", "gfm"],
			"objective-c" : ["Objective-C", "clike"],
			php           : ["PHP", "php"],
			perl          : ["Perl", "perl"],
			python        : ["Python", "python"],
			r             : ["R", "r"],
			rst           : ["reStructedText", "rst"],
			ruby          : ["Ruby", "ruby"],
			sql           : ["SQL", "sql"],
			sass          : ["SASS/SCSS", "sass"],
			shell         : ["Shell", "shell"],
			scala         : ["Scala", "clike"],
			swift         : ["Swift", "clike"],
			vb            : ["VB/VBScript", "vb"],
			xml           : ["XML", "text/xml"],
			yaml          : ["YAML", "yaml"]
		};

		exports.fn.codeBlockDialog = function() {

			var _this       = this;
            var cm          = this.cm;
            var lang        = this.lang;
            var editor      = this.editor;
            var settings    = this.settings;
            var cursor      = cm.getCursor();
            var selection   = cm.getSelection();
            var classPrefix = this.classPrefix;
			var dialogName  = classPrefix + pluginName, dialog;
			var dialogLang  = lang.dialog.codeBlock;

			cm.focus();

            if (editor.find("." + dialogName).length > 0)
            {
                dialog = editor.find("." + dialogName);
                dialog.find("option:first").attr("selected", "selected");
                dialog.find("textarea").val(selection);

                this.dialogShowMask(dialog);
                this.dialogLockScreen();
                dialog.show();
            }
            else 
            {      
                var dialogHTML = "<div class=\"" + classPrefix + "code-toolbar\">" +
                                        dialogLang.selectLabel + "<select><option selected=\"selected\" value=\"\">" + dialogLang.selectDefaultText + "</option></select>" +
                                    "</div>" +
                                    "<textarea placeholder=\"coding now....\" style=\"display:none;\">" + selection + "</textarea>";

                dialog = this.createDialog({
                    name   : dialogName,
                    title  : dialogLang.title,
                    width  : 780,
                    height : 565,
                    mask   : settings.dialogShowMask,
                    drag   : settings.dialogDraggable,
                    content    : dialogHTML,
                    lockScreen : settings.dialogLockScreen,
                    maskStyle  : {
                        opacity         : settings.dialogMaskOpacity,
                        backgroundColor : settings.dialogMaskBgColor
                    },
                    buttons : {
                        enter  : [lang.buttons.enter, function() {
                            var codeTexts  = this.find("textarea").val();
                            var langName   = this.find("select").val();

                            if (langName === "")
                            {
                                alert(lang.dialog.codeBlock.unselectedLanguageAlert);
                                return false;
                            }

                            if (codeTexts === "")
                            {
                                alert(lang.dialog.codeBlock.codeEmptyAlert);
                                return false;
                            }

                            langName = (langName === "other") ? "" : langName;

                            cm.replaceSelection(["```" + langName, codeTexts, "```"].join("\n"));

                            if (langName === "") {
                                cm.setCursor(cursor.line, cursor.ch + 3);
                            }

                            this.hide().lockScreen(false).hideMask();

                            return false;
                        }],
                        cancel : [lang.buttons.cancel, function() {                                   
                            this.hide().lockScreen(false).hideMask();

                            return false;
                        }]
                    }
                });
            }

			var langSelect = dialog.find("select");

			if (langSelect.find("option").length === 1) 
			{
				for (var key in codeLanguages)
				{
					var codeLang = codeLanguages[key];
					langSelect.append("<option value=\"" + key + "\" mode=\"" + codeLang[1] + "\">" + codeLang[0] + "</option>");
				}

				langSelect.append("<option value=\"other\">" + dialogLang.otherLanguage + "</option>");
			}
			
			var mode   = langSelect.find("option:selected").attr("mode");
		
			var cmConfig = {
				mode                      : (mode) ? mode : "text/html",
				theme                     : settings.theme,
				tabSize                   : 4,
				autofocus                 : true,
				autoCloseTags             : true,
				indentUnit                : 4,
				lineNumbers               : true,
				lineWrapping              : true,
				extraKeys                 : {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
				foldGutter                : true,
				gutters                   : ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
				matchBrackets             : true,
				indentWithTabs            : true,
				styleActiveLine           : true,
				styleSelectedText         : true,
				autoCloseBrackets         : true,
				showTrailingSpace         : true,
				highlightSelectionMatches : true
			};
			
			var textarea = dialog.find("textarea");
			var cmObj    = dialog.find(".CodeMirror");

			if (dialog.find(".CodeMirror").length < 1) 
			{
				cmEditor = exports.$CodeMirror.fromTextArea(textarea[0], cmConfig);
				cmObj    = dialog.find(".CodeMirror");

				cmObj.css({
					"float"   : "none", 
					margin    : "8px 0",
					border    : "1px solid #ddd",
					fontSize  : settings.fontSize,
					width     : "100%",
					height    : "390px"
				});

				cmEditor.on("change", function(cm) {
					textarea.val(cm.getValue());
				});
			} 
			else 
			{

				cmEditor.setValue(cm.getSelection());
			}

			langSelect.change(function(){
				var _mode = $(this).find("option:selected").attr("mode");
				cmEditor.setOption("mode", _mode);
			});
		};

	};
    
	// CommonJS/Node.js
	if (typeof require === "function" && typeof exports === "object" && typeof module === "object")
    { 
        module.exports = factory;
    }
	else if (typeof define === "function")  // AMD/CMD/Sea.js
    {
		if (define.amd) { // for Require.js

			define(["editormd"], function(editormd) {
                factory(editormd);
            });

		} else { // for Sea.js
			define(function(require) {
                var editormd = require("./../../editormd");
                factory(editormd);
            });
		}
	} 
	else
	{
        factory(window.editormd);
	}

})();
