/**
 * Created with JetBrains PhpStorm.
 * User: xuheng
 * Date: 12-9-26
 * Time: 下午12:29
 * To change this template use File | Settings | File Templates.
 */

// 清空上次查找选择的痕迹相关变量设置
// 将 `editor` 对象（可能是整个编辑器相关的全局对象，包含了编辑器的各种状态和操作方法等）的 `firstForSR` 属性设置为 0，这个属性可能用于记录查找操作的起始相关状态，重置为初始值表示清除上次查找的起始相关痕迹。
// 将 `editor` 对象的 `currentRangeForSR` 属性设置为 `null`，该属性可能用于记录当前查找操作涉及的文本范围相关信息，设置为 `null` 即清除上次查找操作对应的文本范围记录。
editor.firstForSR = 0;
editor.currentRangeForSR = null;

// 给选项卡（tab）注册切换事件相关的函数定义及逻辑实现部分

// `clickHandler` 函数用于处理选项卡头部标签的点击事件，实现切换选项卡时的样式更改以及对应内容面板的显示隐藏切换功能。
// 接受三个参数：`tabHeads` 是包含所有选项卡头部标签元素的数组，`tabBodys` 是包含所有对应内容面板元素的数组，`obj` 是当前被点击的选项卡头部标签元素。
function clickHandler(tabHeads, tabBodys, obj) {
    // 遍历所有的选项卡头部标签元素，将它们的类名（className）清空，用于去除之前可能存在的表示选中状态等的类样式，为重新设置选中样式做准备。
    for (var k = 0, len = tabHeads.length; k < len; k++) {
        tabHeads[k].className = "";
    }
    // 将当前被点击的选项卡头部标签元素（`obj`）设置为 'focus' 类名，通过 CSS 中对 'focus' 类的样式定义（可能是设置不同的背景色、字体颜色等样式来突出显示当前选中的选项卡）来体现当前选项卡处于选中状态。
    obj.className = "focus";

    // 处理选项卡对应内容面板的显示隐藏切换逻辑。
    var tabSrc = obj.getAttribute("tabSrc");
    for (var j = 0, length = tabBodys.length; j < length; j++) {
        var body = tabBodys[j],
            id = body.getAttribute("id");
        // 如果当前内容面板的 `id` 与被点击选项卡头部标签元素的 `tabSrc` 属性值不相等，说明不是当前要显示的面板，则将其 `z-index` 设置为 1（通过 `z-index` 控制元素在页面中的堆叠顺序，较低的值表示在更下层，可能会被上层元素遮挡），使其处于隐藏或者靠后的显示层级。
        if (id!= tabSrc) {
            body.style.zIndex = 1;
        } else {
            // 如果 `id` 与 `tabSrc` 属性值相等，说明是当前要显示的面板，则将其 `z-index` 设置为 200，使其处于较高的显示层级，显示在最上层，实现显示当前选中选项卡对应的内容面板，隐藏其他面板的效果。
            body.style.zIndex = 200;
        }
    }
}

// `switchTab` 函数用于实现整个选项卡切换的功能，通过查找页面中指定 `tabParentId` 对应的父元素及其子元素，为每个选项卡头部标签添加点击事件监听器，在点击时调用 `clickHandler` 函数来完成切换操作。
// 接受一个参数 `tabParentId`，它可以是选项卡的父节点的 `ID`，也可以直接是选项卡所在的父节点对象本身，用于定位到包含选项卡头部和内容面板的父元素。
function switchTab(tabParentId) {
    // 通过 `$G` 函数（可能是自定义的用于获取页面元素的函数，根据传入的 `ID` 或者对象本身来获取对应的 DOM 元素）获取指定 `tabParentId` 的子元素数组，假设第一个子元素包含选项卡头部标签，第二个子元素包含对应的内容面板元素。
    var tabElements = $G(tabParentId).children,
        tabHeads = tabElements[0].children,
        tabBodys = tabElements[1].children;

    for (var i = 0, length = tabHeads.length; i < length; i++) {
        var head = tabHeads[i];
        // 如果当前选项卡头部标签已经有 'focus' 类名（表示当前处于选中状态），则直接调用 `clickHandler` 函数进行一次初始化的切换操作设置，确保页面加载时当前选中的选项卡对应的样式和面板显示是正确的。
        if (head.className === "focus") clickHandler(tabHeads, tabBodys, head);
        // 为每个选项卡头部标签添加点击事件监听器，当点击某个选项卡头部标签时，调用 `clickHandler` 函数，并传入对应的 `tabHeads`、`tabBodys` 和当前点击的标签元素（`this`）作为参数，实现选项卡的切换操作逻辑。
        head.onclick = function () {
            clickHandler(tabHeads, tabBodys, this);
        }
    }
}

// 为页面中 `id` 为 `searchtab` 的元素添加鼠标按下事件监听器，当在该元素上按下鼠标时，清空页面中 `id` 为 `search-msg` 和 `replace-msg` 的元素的内容（innerHTML）。
// 推测 `search-msg` 和 `replace-msg` 元素是用于显示查找和替换操作相关提示信息的区域，通过清空它们的内容，实现清除之前可能存在的提示信息，为下一次操作显示新的提示做准备。
$G('searchtab').onmousedown = function () {
    $G('search-msg').innerHTML = '';
    $G('replace-msg').innerHTML = ''
}

// `getMatchCase` 函数用于获取指定 `id` 对应的复选框元素的选中状态，返回一个布尔值，表示是否选中。
// 接受一个参数 `id`，即要获取选中状态的复选框元素的 `ID`，通过 `$G` 函数获取该元素，然后判断其 `checked` 属性（复选框的选中状态属性，`true` 表示选中，`false` 表示未选中），并返回对应的布尔值。
function getMatchCase(id) {
    return $G(id).checked? true : false;
}

// 以下是各个操作按钮的点击事件处理函数，分别对应不同的查找、替换操作逻辑

// “下一个查找”按钮（`id` 为 `nextFindBtn`）的点击事件处理函数
// 点击该按钮时，获取页面中 `id` 为 `findtxt` 的输入框中的值作为要查找的字符串，如果该值为空（即用户未输入查找内容），则直接返回 `false`，不执行后续查找操作。
// 然后创建一个包含查找字符串、查找方向（这里设置为 1，可能表示正向查找，具体含义依赖业务逻辑定义）以及是否区分大小写（通过调用 `getMatchCase` 函数获取 `matchCase` 复选框的选中状态来确定）等信息的对象 `obj`，并将其作为参数传递给 `frCommond` 函数来执行实际的查找操作。
// 如果 `frCommond` 函数返回 `false`（表示查找失败或者未找到匹配内容等情况），则创建一个书签（bookmark，可能用于记录当前文本选择的位置信息，方便后续恢复位置等操作），在页面中 `id` 为 `search-msg` 的元素内显示 `lang.getEnd`（可能是预定义的表示查找结束等相关提示信息的字符串，具体内容依赖语言配置等情况），并将文本选择范围移动到书签位置并选中该范围（可能用于突出显示查找的起始位置等情况）。
$G("nextFindBtn").onclick = function (txt, dir, mcase) {
    var findtxt = $G("findtxt").value, obj;
    if (!findtxt) {
        return false;
    }
    obj = {
        searchStr: findtxt,
        dir: 1,
        casesensitive: getMatchCase("matchCase")
    };
    if (!frCommond(obj)) {
        var bk = editor.selection.getRange().createBookmark();
        $G('search-msg').innerHTML = lang.getEnd;
        editor.selection.getRange().moveToBookmark(bk).select();
    }
};

// “下一个替换”按钮（`id` 为 `nextReplaceBtn`）的点击事件处理函数
// 点击该按钮时，获取页面中 `id` 为 `findtxt1` 的输入框中的值作为要查找的字符串，如果该值为空则返回 `false`，不执行后续操作。
// 创建一个包含查找字符串、查找方向（设置为 1，可能表示正向查找）以及是否区分大小写（通过 `getMatchCase` 函数获取 `matchCase1` 复选框的选中状态确定）等信息的对象 `obj`，并传递给 `frCommond` 函数执行实际的替换相关操作（具体替换逻辑在 `frCommond` 函数内部或者依赖其调用的其他函数实现）。
$G("nextReplaceBtn").onclick = function (txt, dir, mcase) {
    var findtxt = $G("findtxt1").value, obj;
    if (!findtxt) {
        return false;
    }
    obj = {
        searchStr: findtxt,
        dir: 1,
        casesensitive: getMatchCase("matchCase1")
    };
    frCommond(obj);
};

// “上一个查找”按钮（`id` 为 `preFindBtn`）的点击事件处理函数
// 与“下一个查找”按钮逻辑类似，获取 `findtxt` 输入框的值作为查找字符串，为空则返回 `false`。
// 创建包含查找字符串、查找方向（设置为 -1，可能表示反向查找）以及是否区分大小写信息的对象 `obj`，传递给 `frCommond` 函数执行查找操作，如果查找失败（`frCommond` 函数返回 `false`），则在 `search-msg` 元素内显示 `lang.getStart`（可能是表示查找起始等相关提示信息的字符串）。
$G("preFindBtn").onclick = function (txt, dir, mcase) {
    var findtxt = $G("findtxt").value, obj;
    if (!findtxt) {
        return false;
    }
    obj = {
        searchStr: findtxt,
        dir: -1,
        casesensitive: getMatchCase("matchCase")
    };
    if (!frCommond(obj)) {
        $G('search-msg').innerHTML = lang.getStart;
    }
}

// “上一个替换”按钮（`id` 为 `preReplaceBtn`）的点击事件处理函数
// 类似“下一个替换”按钮逻辑，获取 `findtxt1` 输入框的值作为查找字符串，为空则返回 `false`，创建相应对象并传递给 `frCommond` 函数执行替换相关操作。
$G("preReplaceBtn").onclick = function (txt, dir, mcase) {
    var findtxt = $G("findtxt1").value, obj;
    if (!findtxt) {
        return false;
    }
    obj = {
        searchStr: findtxt,
        dir: -1,
        casesensitive: getMatchCase("matchCase1")
    };
    frCommond(obj);
}

// “替换”按钮（`id` 为 `repalceBtn`）的点击事件处理函数
// 点击该按钮时，首先触发编辑器（`editor`）的 `clearLastSearchResult` 事件（可能用于清除上次查找替换操作留下的一些结果相关状态，比如之前选中的文本范围等，确保本次操作不受上次影响）。
// 获取 `findtxt1` 和 `replacetxt` 输入框的值，分别作为要查找和替换成的字符串，并去除字符串两端的空白字符（通过正则表达式 `/^\s|\s$/g` 进行匹配替换）。
// 如果要查找的字符串为空则返回 `false`，不执行替换操作。
// 接着判断要查找和替换的字符串是否相等（包括不区分大小写情况下相等，通过 `toLowerCase` 方法将字符串转换为小写后进行比较），如果相等也返回 `false`，不进行无意义的替换操作。
// 最后创建一个包含查找字符串、查找方向（设置为 1）、是否区分大小写以及替换字符串等信息的对象 `obj`，并传递给 `frCommond` 函数执行实际的替换操作。
$G("repalceBtn").onclick = function () {
    editor.trigger('clearLastSearchResult');
    var findtxt = $G("findtxt1").value.replace(/^\s|\s$/g, ""), obj,
        replacetxt = $G("replacetxt").value.replace(/^\s|\s$/g, "");
    if (!findtxt) {
        return false;
    }
    if (findtxt == replacetxt || (!getMatchCase("matchCase1") && findtxt.toLowerCase() == replacetxt.toLowerCase())) {
        return false;
    }
    obj = {
        searchStr: findtxt,
        dir: 1,
        casesensitive: getMatchCase("matchCase1"),
        replaceStr: replacetxt
    };
    frCommond(obj);
}

// “全部替换”按钮（`id` 为 `repalceAllBtn`）的点击事件处理函数
// 与“替换”按钮类似，获取 `findtxt1` 和 `replacetxt` 输入框的值并去除两端空白字符，为空则返回 `false`，判断两者相等情况（包括不区分大小写相等情况），相等则返回 `false`，不执行操作。
// 创建一个包含查找字符串、是否区分大小写、替换字符串以及 `all` 属性设置为 `true`（表示执行全部替换操作，区别于单个替换）的对象 `obj`，传递给 `frCommond` 函数执行全部替换操作，获取返回的替换次数 `num`（如果替换成功，`frCommond` 函数可能返回替换的次数）。
// 如果 `num` 有值（即替换次数大于 0，表示有进行替换操作），则在页面中 `replace-msg` 元素内显示替换次数相关的提示信息，通过 `lang.countMsg.replace` 方法（可能是根据预定义的字符串模板，将其中的 `{#count}` 占位符替换为实际的替换次数 `num`）来生成具体的提示内容，向用户展示替换的结果情况。
$G("repalceAllBtn").onclick = function () {
    var findtxt = $G("findtxt1").value.replace(/^\s|\s$/g, ""), obj,
        replacetxt = $G("replacetxt").value.replace(/^\s|\s$/g, "");
    if (!findtxt) {
        return false;
    }
    if (findtxt == replacetxt || (!getMatchCase("matchCase1") && findtxt.toLowerCase() == replacetxt.toLowerCase())) {
        return false;
    }
    obj = {
        searchStr: findtxt,
        casesensitive: getMatchCase("matchCase1"),
        replaceStr: replacetxt,
        all: true
    };
    var num = frCommond(obj);
    if (num) {
        $G('replace-msg').innerHTML = lang.countMsg.replace("{#count}", num);
    }
}

// `frCommond` 函数用于执行实际的查找替换命令，它接受一个对象参数 `obj`（包含查找替换相关的各种信息，如查找字符串、替换字符串、是否区分大小写、查找方向等），并调用 `editor` 对象的 `execCommand` 方法（可能是编辑器提供的用于执行各种命令操作的接口函数），传入 `searchreplace` 命令和 `obj` 参数，将实际的查找替换操作转发给编辑器内部进行处理，最后返回 `execCommand` 方法的执行结果，用于判断操作是否成功等情况。
var frCommond = function (obj) {
    return editor.execCommand("searchreplace", obj);
};

// 调用 `switchTab` 函数，传入 `searchtab`（可能是包含搜索和替换选项卡的父元素的 `ID`），启动选项卡切换功能的初始化设置，确保页面加载时选项卡的初始状态和切换逻辑正常工作。
switchTab("searchtab");

// 为对话框（`dialog`，可能是与查找替换操作相关的弹出式对话框，用于显示一些提示信息、操作确认等功能）的关闭事件（`onclose`）添加监听器，当对话框关闭时，触发编辑器的 `clearLastSearchResult` 事件，用于清除查找替换操作相关的一些遗留状态，保证下次操作的初始状态正确。
dialog.onclose = function () {
    editor.trigger('clearLastSearchResult')
};