/**
 * Created by JetBrains PhpStorm.
 * User: taoqili
 * Date: 12-1-30
 * Time: 下午12:50
 * To change this template use File | Settings | File Templates.
 */

// 定义一个名为 `wordImage` 的空对象，从后续代码来看，它可能用于聚合与图片相关的各种方法、属性等，作为图片功能模块的一个主要对象，通过向其添加不同的函数来实现具体的图片操作功能。
var wordImage = {};

// 以下原本是一个自执行函数的开头，但被注释掉了，若取消注释则可形成一个独立的作用域，避免全局变量污染。不过目前代码整体处于全局作用域下，定义的变量和函数在外部是可访问的（除了在函数内部通过闭包等方式限制访问的局部变量）。
//(function(){

// 通过 `baidu.g` 函数（可能是自定义的用于获取页面元素的函数，依赖于 `baidu` 对象，根据传入的 `ID` 等标识来获取对应的 DOM 元素，类似于 `document.getElementById` 的功能，但可能有更多自定义的逻辑处理）获取页面元素，这里获取了两个变量，`g` 可能用于后续多次获取元素的操作，更方便简洁；`flashContainer` 则专门用于指代某个与 Flash 相关的容器元素（从命名推测可能是用于承载 Flash 图片上传组件的元素，后续代码也体现了这一点），不过目前还未赋值，等待后续使用时再确定具体对应的元素。
var g = baidu.g,
    flashObj, flashContainer;

// 为 `wordImage` 对象添加 `init` 方法，用于初始化图片相关的各种功能，通过传入配置对象 `opt` 和回调函数对象 `callbacks`，在函数内部调用多个其他函数来实现诸如展示本地路径、创建 Flash 上传组件、添加上传事件监听以及添加确认按钮点击事件监听等操作，完成图片功能模块的初始化流程。
wordImage.init = function (opt, callbacks) {
    showLocalPath("localPath");
    // 调用 `showLocalPath` 函数，传入 `"localPath"` 参数，用于展示本地图片路径相关信息，将相应的路径显示在 `ID` 为 `localPath` 的页面元素（可能是一个输入框等用于展示路径的元素）中，方便用户查看。
    //createCopyButton("clipboard","localPath");
    // 这行代码被注释掉了，原本应该是调用 `createCopyButton` 函数，传入 `"clipboard"` 和 `"localPath"` 参数，从命名推测可能是用于创建一个复制按钮，关联到 `ID` 为 `clipboard` 的元素，并且与 `localPath` 相关（可能是用于复制 `localPath` 显示的本地路径内容等功能），不过目前暂未执行此功能。
    createFlashUploader(opt, callbacks);
    // 调用 `createFlashUploader` 函数，传入配置对象 `opt` 和回调函数对象 `callbacks`，用于创建 Flash 图片上传组件，进行相关的配置设置以及初始化操作，使其能够正常显示并实现图片上传功能。
    addUploadListener();
    // 调用 `addUploadListener` 函数，用于添加图片上传相关的事件监听，比如点击上传按钮时触发的上传操作逻辑等，确保用户操作能正确响应并执行相应的上传流程。
    addOkListener();
    // 调用 `addOkListener` 函数，用于添加确认按钮（可能是在完成图片上传等操作后，用于确认应用这些图片相关设置的按钮）点击事件的监听，在点击确认按钮时执行相应的业务逻辑，比如将上传后的图片信息应用到编辑器中的图片元素上，更新图片的链接、属性等内容。
};

// `hideFlash` 函数用于隐藏 Flash 相关的元素并清理相关的数据或内容，将 `flashObj` 设置为 `null`（可能用于释放相关资源或者标记 Flash 对象已不存在等情况），同时清空 `flashContainer` 元素的 `innerHTML`（即将其内部的子元素全部移除，实现清空容器内容的效果，比如隐藏或移除 Flash 上传组件的显示界面等）。
function hideFlash() {
    flashObj = null;
    flashContainer.innerHTML = "";
}

// `addOkListener` 函数用于为对话框（`dialog`，可能是与图片操作相关的弹出式对话框，用于确认操作、显示提示信息等功能）的 `onok` 事件（通常是用户点击对话框中的确认按钮时触发的事件）和 `oncancel` 事件（用户点击取消按钮时触发的事件）添加事件处理函数。
function addOkListener() {
    dialog.onok = function () {
        if (!imageUrls.length) return;
        // 判断 `imageUrls` 数组（该数组用于保存从服务器返回的图片信息，在其他地方会将上传成功后的图片相关数据添加到这个数组中）的长度是否为 0，如果为空则直接返回，不执行后续操作，意味着只有当有上传成功的图片信息时才进行下面的处理逻辑。
        var urlPrefix = editor.getOpt('imageUrlPrefix'),
            images = domUtils.getElementsByTagName(editor.document, "img");
        // 通过 `editor` 对象（可能是整个应用中与文本编辑相关的核心对象，包含了各种编辑操作的方法、属性等）的 `getOpt` 方法（用于获取之前设置的配置选项的值）获取名为 `imageUrlPrefix` 的配置选项的值，赋值给 `urlPrefix` 变量，这个值可能是图片 URL 的前缀部分，用于拼接完整的图片链接；然后通过 `domUtils.getElementsByTagName` 函数（可能是自定义的用于获取指定元素下的特定标签元素的函数，类似于浏览器原生的 `document.getElementsByTagName` 方法，但基于 `editor.document`（可能是编辑器中的文档对象，用于操作编辑器内的元素）进行查找）获取文档中所有的 `<img>` 图片元素，存储在 `images` 变量中，后续会遍历这些图片元素来更新它们的相关属性。
        editor.fireEvent('saveScene');
        // 调用 `editor` 对象的 `fireEvent` 方法（可能用于触发编辑器中定义的特定事件，这里触发 `saveScene` 事件，具体该事件对应的处理逻辑依赖于编辑器中对其的定义，可能用于保存当前场景、状态等相关操作，此处可能是在更新图片前先保存一下相关状态）。
        for (var i = 0, img; img = images[i++];) {
            var src = img.getAttribute("word_img");
            if (!src) continue;
            // 遍历获取到的所有图片元素，获取每个图片元素的 `word_img` 属性值（从命名推测可能是在图片上传前用于临时标记图片的某个属性，比如原始路径或者临时的唯一标识等），如果该属性不存在（值为 `null` 或者 `undefined`）则跳过当前循环，继续下一个图片元素的处理，意味着只处理带有 `word_img` 属性的图片元素。
            for (var j = 0, url; url = imageUrls[j++];) {
                if (src.indexOf(url.original.replace(" ", ""))!= -1) {
                    // 内层循环遍历 `imageUrls` 数组中的每个图片信息对象（`url`），将图片元素的 `word_img` 属性值（`src`）与图片信息对象中的 `original` 属性值（去除空格后）进行比较（通过 `indexOf` 方法判断是否包含），如果找到匹配的，则执行以下更新图片元素属性的操作。
                    img.src = urlPrefix + url.url;
                    // 将图片元素的 `src` 属性（用于设置图片的链接地址）更新为 `urlPrefix`（前面获取的图片 URL 前缀）与图片信息对象中的 `url` 属性（完整的图片链接地址的一部分，与 `urlPrefix` 拼接后形成完整地址）拼接后的字符串，实现将图片链接替换为上传后服务器返回的正确链接地址。
                    img.setAttribute("_src", urlPrefix + url.url);  //同时修改"_src"属性
                    // 同时为图片元素添加 `_src` 属性（可能是用于备份原始 `src` 属性值或者有其他相关用途，具体依赖应用中的逻辑），并设置其值与 `src` 属性相同，也是拼接后的完整图片链接地址。
                    img.setAttribute("title", url.title);
                    // 为图片元素添加 `title` 属性，设置其值为图片信息对象中的 `title` 属性值（可能是图片的标题、描述等相关文字信息，用于在鼠标悬停等情况下显示提示信息）。
                    domUtils.removeAttributes(img, ["word_img", "style", "width", "height"]);
                    // 通过 `domUtils.removeAttributes` 函数（可能是自定义的用于移除元素指定属性的函数）移除图片元素的 `word_img`、`style`（可能是之前设置的一些临时样式属性等）、`width` 和 `height`（可能是上传前的图片原始尺寸属性，现在更新链接后可能不需要了或者后续会根据新图片重新计算尺寸等情况）属性，清理不必要的属性设置。
                    editor.fireEvent("selectionchange");
                    // 调用 `editor` 对象的 `fireEvent` 方法，触发 `selectionchange` 事件（可能用于通知编辑器图片选择等相关状态发生了变化，以便编辑器进行相应的界面更新、其他逻辑处理等操作，比如重新渲染图片所在区域等）。
                    break;
                    // 找到匹配的图片信息对象并更新完当前图片元素的属性后，通过 `break` 跳出内层循环，继续处理下一个图片元素，避免重复匹配和不必要的循环比较。
                }
            }
        }
        editor.fireEvent('saveScene');
        // 再次触发 `saveScene` 事件，可能是在完成所有图片元素属性更新后，再次保存一下最终的场景、状态等信息，确保数据的完整性和一致性。
        hideFlash();
        // 调用 `hideFlash` 函数，隐藏 Flash 相关元素并清理其内容，比如在图片处理完成后，隐藏或移除 Flash 上传组件的显示界面等，完成整个操作流程后的清理工作。
    };
    dialog.oncancel = function () {
        hideFlash();
    }
    // 为对话框的 `oncancel` 事件添加事件处理函数，当用户点击取消按钮时，直接调用 `hideFlash` 函数，隐藏 Flash 相关元素并清理其内容，撤销可能正在进行的图片上传操作或者清理已显示的相关界面元素等情况。
}

/**
 * 绑定开始上传事件
 */
function addUploadListener() {
    g("upload").onclick = function () {
        flashObj.upload();
        this.style.display = "none";
        // 通过 `g` 函数获取 `ID` 为 `upload` 的页面元素（可能是一个上传按钮元素），并为其添加点击事件监听器，当用户点击该按钮时，调用 `flashObj`（可能是 Flash 上传组件对应的对象，在 `createFlashUploader` 函数中实例化创建的）的 `upload` 方法，触发图片上传操作；然后将按钮自身的 `style.display` 属性设置为 `"none"`，隐藏该上传按钮，可能是为了避免用户重复点击或者表示上传正在进行中不需要再次点击等情况。
    };
}

function showLocalPath(id) {
    // 以下代码用于展示本地图片路径相关信息，根据不同的情况（单张编辑或者多张图片相关情况）来确定要显示的路径内容，并将其设置到对应的页面元素（通过传入的 `id` 参数指定的元素，通常是一个输入框用于展示路径）中。
    //单张编辑
    var img = editor.selection.getRange().getClosedNode();
    var images = editor.execCommand('wordimage');
    if (images.length == 1 || img && img.tagName == 'IMG') {
        g(id).value = images[0];
        return;
    }
    // 首先通过 `editor` 对象的 `selection` 属性（用于获取当前文本选择相关的信息）的 `getRange` 方法（获取选择范围相关的对象）的 `getClosedNode` 方法（获取选择范围对应的节点元素，比如选中的图片等元素）获取当前选中的节点元素，存储在 `img` 变量中；然后通过 `editor` 对象执行 `wordimage` 命令（具体 `wordimage` 命令的功能依赖编辑器中对其的定义，可能是获取相关图片信息等操作）获取图片相关的信息，存储在 `images` 数组中。如果获取到的 `images` 数组长度为 1（表示只有一张图片相关信息）或者 `img` 存在且其标签名是 `<IMG>`（即选中了一张图片），则通过 `g` 函数获取 `ID` 为 `id` 的页面元素（比如一个输入框），并将 `images[0]`（第一张图片相关信息，可能是路径等内容）设置为该元素的 `value` 属性值，完成路径展示后直接返回，结束函数执行。
    var path = images[0];
    var leftSlashIndex = path.lastIndexOf("/") || 0,  //不同版本的doc和浏览器都可能影响到这个符号，故直接判断两种
        rightSlashIndex = path.lastIndexOf("\\") || 0,
        separater = leftSlashIndex > rightSlashIndex? "/": "\\";
    // 如果不满足上述单张图片的情况，则获取 `images` 数组中的第一个元素（可能是一个包含路径信息的字符串等），赋值给 `path` 变量，然后分别查找路径字符串中最后一次出现斜杠（`/`）和反斜杠（`\`）的索引位置，存储在 `leftSlashIndex` 和 `rightSlashIndex` 变量中，通过比较这两个索引大小，确定实际的路径分隔符（选择最后出现的那个斜杠或反斜杠作为分隔符，存储在 `separater` 变量中），用于后续截取正确的路径部分。
    path = path.substring(0, path.lastIndexOf(separater) + 1);
    g(id).value = path;
    // 使用 `substring` 方法截取 `path` 字符串，从开头截取到最后一次出现分隔符的位置（加上 1 是包含分隔符本身），得到正确的路径前缀部分（比如文件夹路径部分），然后将其设置到通过 `g` 函数获取的 `ID` 为 `id` 的页面元素（如输入框）的 `value` 属性中，实现展示本地图片路径的功能。
}

function createFlashUploader(opt, callbacks) {
    // 该函数用于创建 Flash 图片上传组件，进行相关的配置设置、处理国际化相关的图片资源地址编码问题，并实例化 Flash 上传组件对象，使其能够正常显示并实现图片上传功能。
    //由于lang.flashI18n是静态属性，不可以直接进行修改，否则会影响到后续内容
    var i18n = utils.extend({}, lang.flashI18n);
    // 通过 `utils.extend` 函数（可能是自定义的用于合并对象属性的函数，将第一个对象的属性复制到第二个对象上，如果有同名属性则覆盖，这里将 `lang.flashI18n` 的属性复制到一个新的空对象 `i18n` 上，用于获取一份原始的国际化相关属性的副本，避免直接修改原始的静态属性，影响其他地方的使用）创建一个新对象 `i18n`，复制了 `lang.flashI18n`（可能是存储了 Flash 相关的国际化文本信息、图片资源路径等属性的对象，用于根据不同语言环境展示相应内容）的属性，后续可以对这个副本进行修改操作。
    //处理图片资源地址的编码，补全等问题
    for (var i in i18n) {
        if (!(i in {"lang": 1, "uploadingTF": 1, "imageTF": 1, "textEncoding": 1}) && i18n[i]) {
            i18n[i] = encodeURIComponent(editor.options.langPath + editor.options.lang + "/images/" + i18n[i]);
        }
    }
    // 遍历 `i18n` 对象的属性，对于除了 `lang`、`uploadingTF`、`imageTF`、`textEncoding` 这几个特定属性之外的其他属性（通过判断属性名是否在一个特定的对象中存在来筛选），并且属性值不为 `null` 或者 `undefined` 的情况，使用 `encodeURIComponent` 函数（JavaScript 内置函数，用于对 URI 组件进行编码，将特殊字符转换为对应的编码格式，确保在 URL 等场景中能正确传输和解析）对其进行编码处理，编码的内容是将 `editor.options.langPath`（可能是语言相关的路径前缀）、`editor.options.lang`（当前使用的语言标识）、`"/images/"`（固定的图片资源路径部分）以及属性值（原始的图片资源相关的文件名等信息）拼接后的字符串进行编码，这样处理后的属性值可以正确地在 Flash 上传组件中使用，避免因特殊字符等问题导致资源加载错误。
    opt = utils.extend(opt, i18n, false);
    // 再次使用 `utils.extend` 函数，将处理好的 `i18n` 对象的属性合并到传入的 `opt` 对象（可能是用于配置 Flash 上传组件的各种参数的对象，包含了如上传地址、文件格式限制、尺寸限制等相关属性）上，不过这里第三个参数 `false` 不太明确其具体作用（可能是控制合并的方式，比如是否深度合并等情况，需要查看 `utils.extend` 函数的具体实现），完成对 `opt` 对象的配置参数更新，添加了国际化相关的处理后的属性内容。
    var option = {
        createOptions: {
			id:'flash',
			url:opt.flashUrl,
			width:opt.width,
			height:opt.height,
			errorMessage:lang.flashError,
			wmode:browser.safari ? 'transparent' : 'window',
			ver:'10.0.0',
			vars:opt,
			container:opt.container
		}
	};

	option = extendProperty(callbacks, option);
	flashObj = new baidu.flash.imageUploader(option);
    flashContainer = $G(opt.container);
}

function extendProperty(fromObj, toObj) {
	for (var i in fromObj) {
		if (!toObj[i]) {
			toObj[i] = fromObj[i];
		}
	}
	return toObj;
}

//})();

function getPasteData(id) {
	baidu.g("msg").innerHTML = lang.copySuccess + "</br>";
	setTimeout(function() {
		baidu.g("msg").innerHTML = "";
	}, 5000);
	return baidu.g(id).value;
}

function createCopyButton(id, dataFrom) {
	baidu.swf.create({
			id:"copyFlash",
			url:"fClipboard_ueditor.swf",
			width:"58",
			height:"25",
			errorMessage:"",
			bgColor:"#CBCBCB",
			wmode:"transparent",
			ver:"10.0.0",
			vars:{
				tid:dataFrom
			}
		}, id
	);

	var clipboard = baidu.swf.getMovie("copyFlash");
	var clipinterval = setInterval(function() {
		if (clipboard && clipboard.flashInit) {
			clearInterval(clipinterval);
			clipboard.setHandCursor(true);
			clipboard.setContentFuncName("getPasteData");
			//clipboard.setMEFuncName("mouseEventHandler");
		}
	}, 500);
}
createCopyButton("clipboard", "localPath");