﻿/**
* @author szsheng
* requires the Prototype JavaScript framework
*/
var CSSMLEngine = Class.create();
CSSMLEngine.instance = [];
CSSMLEngine._imgPath = "@images/";
CSSMLEngine._cssPath = "@css/";
CSSMLEngine._arrSpeeds = [300, 100, -100, -250, -400];
CSSMLEngine._useDisplayPinyin = true; //true or false. When convert html to cssml use the pinyin for display(user can change it).

CSSMLEngine.prototype = {
    initialize: function(editor) {
        this._editor = editor;
        this._editor.document.designMode = "on";
        this.editorInit(this);
        this._range = null;
        this.index = CSSMLEngine.instance.length;
        this.requireSelected = true;
        CSSMLEngine.instance.push(this);
        CSSMLEngine.callResx();
    },
    editorInit: function(_this) {
        if (_this._editor.document.documentElement) {
            var eBody = _this._editor.document.body;
            eBody.innerHTML = "<div></div>";
            if (_this._onload != Prototype.emptyFunction)
                _this._onload(_this._editor);
            eBody.className = "scrollbar";
            var cssPath = CSSMLEngine._cssPath + "cssml.css";
            _this._editor.document.createStyleSheet(cssPath);
            _this._editor.document.documentElement.attachEvent('onpaste', function() { _this.docOnpaste(_this) });
            if (_this._onselecttext != Prototype.emptyFunction) {
                _this._onselecttext(false);
                _this._editor.document.onselectionchange = function() {
                    if (_this.selectTimeId) //此处的setTimeout 防止频繁 selectionchange
                        clearTimeout(_this.selectTimeId);
                    var range = _this._editor.document.selection.createRange();
                    _this.selectTimeId = setTimeout(function() { _this._onselecttext(range.text && range.text.length > 0); }, 200);
                };
                _this._editor.document.body.onblur = _this._editor.document.onselectionchange;
            }
        }
        else
            _this._editor.setTimeout(function() { _this.editorInit(_this) }, 100);
    },
    _onload: Prototype.emptyFunction,
    _onselecttext: Prototype.emptyFunction,
    docOnpaste: function(_this) {
        _this._editor.event.returnValue = false;
        var txt = _this._editor.clipboardData.getData("Text");
        if (!txt || txt == "")
            return;

        txt = txt.replace(/</g, "＜").replace(/>/g, "＞").replace(/\r\n/g, "<br/>"); //.replace(/ /g,"&nbsp;");
        _this._editor.document.selection.createRange().pasteHTML(txt);
    },
    getSelectedRange: function() {
        var range = this._editor.document.selection.createRange();
        if (range.htmlText != "")
            return range;
        if (!this.requireSelected)
            range = this._editor.document.body.createTextRange();
        return range;
    },
    createDivPy: function() {
        if ($("divPy" + this.index))
            return;
        var divPy = window.document.createElement("div");
        divPy.id = "divPy" + this.index;
        divPy.style.display = "none";
        divPy.style.position = "absolute";
        divPy.style.height = "200px";
        divPy.style.width = "500px";
        divPy.style.backgroundColor = "#ffffff";
        divPy.style.border = "2px solid #0595D2";
        divPy.style.borderTop = "none";
        divPy.style.textAlign = "center";
        divPy.style.zIndex = 99;
        var inHtml = "<div class='dlgBar'>";
        inHtml += "        <span style='float:left;font-size:14px;font-weight:bold;margin-top:2px;'>" + this.getResx("SetPinyin", "设置拼音") + "</span>";
        inHtml += "        <img id='pyclose" + this.index + "' src='" + CSSMLEngine._imgPath + "close.gif' style='border:0px;' />";
        inHtml += "    </div>";
        inHtml += "    <div id='pyMsg" + this.index + "' style='font-size:14px;margin-top:20px;'>" + this.getResx("InputPinyin", "请输入拼音：") + "</div>";
        inHtml += "    <input id='txtPy" + this.index + "' type='text' style='margin-top:10px;width:400px;' onkeypress='if(event.keyCode==13)$(\"btnPyConfirm" + this.index + "\").click();' /><br/>";
        inHtml += "    <input id='btnPyConfirm" + this.index + "' type='button' value='" + this.getResx("Confirm", " 确 定 ") + "'  style='margin-top:20px;' class='btn' onclick='CSSMLEngine.instance[" + this.index + "].eSetPinyin($(\"txtPy" + this.index + "\").value);' />";
        inHtml += "    <div style='text-align:left;font-size:12px;margin-top:50px;padding:5px;background-color:#C8E0ED;'>" + this.getResx("Note", "备注：如为“你”设置拼音，可输入“ni3”，为“你好”设置拼音，可输入“ni3hao3”。") + "</div>";
        window.document.body.appendChild(divPy);
        divPy.innerHTML = inHtml;
    },
    createDivMark: function() {
        if ($("divMark" + this.index))
            return;
        var divMark = window.document.createElement("div");
        divMark.id = "divMark" + this.index;
        divMark.style.display = "none";
        divMark.style.position = "absolute";
        divMark.style.height = "200px";
        divMark.style.width = "500px";
        divMark.style.backgroundColor = "#ffffff";
        divMark.style.border = "2px solid #0595D2";
        divMark.style.borderTop = "none";
        divMark.style.textAlign = "center";
        divMark.style.zIndex = 99;
        var inHtml = "<div class='dlgBar'>";
        inHtml += "        <span style='float:left;font-size:14px;font-weight:bold;margin-top:2px;'>" + this.getResx("SetMark", "设置注释") + "</span>";
        inHtml += "        <img id='markclose" + this.index + "' src='" + CSSMLEngine._imgPath + "close.gif' style='border:0px;' />";
        inHtml += "    </div>";
        inHtml += "    <input id='hidMarkName" + this.index + "' type='hidden' value=''/>";
        inHtml += "    <div id='markMsg" + this.index + "' style='font-size:14px;margin-top:20px;'>" + this.getResx("InputMark", "请输入注释：") + "</div>";
        inHtml += "    <textarea id='txtMark" + this.index + "' class='scrollbar textarea' style='margin-top:10px;width:400px;height:200px;'></textarea><br/>";
        inHtml += "    <input id='btnMarkConfirm" + this.index + "' type='button' value='" + this.getResx("Confirm", " 确 定 ") + "'  style='margin-top:20px;' class='btn' onclick='CSSMLEngine.instance[" + this.index + "].eSetMark($F(\"txtMark" + this.index + "\"));' />";
        inHtml += "    <div style='text-align:left;font-size:12px;margin-top:50px;padding:5px;background-color:#C8E0ED;'>" + this.getResx("NoteMark", "备注：注释的备注。") + "</div>";
        window.document.body.appendChild(divMark);
        divMark.innerHTML = inHtml;
        //        new Draggable('divMark',{
        //		    handle:'divMark',
        //		    onDrag:function(){
        //		        $('divMark').style.border='2px dotted #FFD94F';
        //		    },
        //		    onEnd:function(){
        //		        $('divMark').style.border='2px solid #0595D2';
        //		    }
        //	    });
    },
    format: function(type, para) {
        var f = this._editor;
        if (!para) {
            f.document.execCommand(type);
        } else {
            f.document.execCommand(type, false, para);
        }
        f.focus();
    },
    insertNode: function(type, args) {
        try {
            if (!args)
                args = "";
            var range = this.getSelectedRange(); //this._editor.document.selection.createRange();
            var sText = range.htmlText;
            if (/^\r\n/.test(sText)) {
                if (range.findText(range.text, 1, 0)) {
                    range.select();
                    sText = range.htmlText;
                }
            }
            if (sText.length < 1)
                return;
            if (!CSSMLEngine.checkHTML(sText)) {
                alert(this.getResx("ErrNodeNest", "操作错误，节点嵌套错误或不配对。"));
                return;
            }
            var editorBody = this._editor.document.body;
            var bodyHtml = editorBody.innerHTML;
            var eHtml = "<span class=" + type + "Start " + args + "></span>" + sText + "<span class=" + type + "End></span>";
            if (type == "sub" && (bodyHtml.indexOf(sText) != bodyHtml.lastIndexOf(sText)) && confirm(this.getResx("SetAllNotRead", "是否将所有相同的文本设置为不读？"))) {
                var bodyRange = editorBody.createTextRange();
                sText = sText.unescapeHTML();
                while (bodyRange.findText(sText, 1, 0)) {
                    bodyRange.select();
                    bodyRange.pasteHTML(eHtml);
                    //bodyRange.moveStart("character",0);
                }
            }
            else if (/^voice/i.test(type)) {
                sText = sText.replace(/<span(\s+[^<>]*?)class=voice\w+([^<>]*?)>.*?<\/span>/ig, "");
                eHtml = "<span class=" + type + "Start " + args + "></span>" + sText + "<span class=" + type + "End></span>";
                range.pasteHTML(eHtml);
            }
            else {
                range.pasteHTML(eHtml);
            }
        } catch (ex) { }
    },
    eMakeWord: function() {
        var range = this.getSelectedRange(); //this._editor.document.selection.createRange();
        var sText = range.text;
        if (/[^\u4e00-\u9fa5]/i.test(sText)) {
            alert(this.getResx("WordNotHanzi", "不能为非汉字字符组词。"));
            return;
        }
        if (sText.length > 8) {
            alert(this.getResx("OverMaxWordLen", "组词的字符长度不能超过8"));
            return;
        }
        this.insertNode("word");
    },
    eSetSpeed: function(val) {
        var rate = val / 1000 + 1;
        switch (val) {
            case CSSMLEngine._arrSpeeds[2]:
                this.insertNode("prosody", "rate=\"" + rate + "\"");
                break;
            case CSSMLEngine._arrSpeeds[1]:
                this.insertNode("prosodyFast", "rate=\"" + rate + "\"");
                break;
            case CSSMLEngine._arrSpeeds[0]:
                this.insertNode("prosodyFastest", "rate=\"" + rate + "\"");
                break;
            case CSSMLEngine._arrSpeeds[3]:
                this.insertNode("prosodySlow", "rate=\"" + rate + "\"");
                break;
            case CSSMLEngine._arrSpeeds[4]:
                this.insertNode("prosodySlowest", "rate=\"" + rate + "\"");
                break;
            default:
                if (val > 0)
                    this.insertNode("prosodyFast", "rate=\"" + rate + "\"");
                else if (val == 0)
                    this.insertNode("prosody", "rate=\"" + rate + "\"");
                else
                    this.insertNode("prosodySlow", "rate=\"" + rate + "\"");
                break;
        }
    },
    eSelectVoice: function(gender) {
        if (gender == "male")
            this.insertNode("voiceMale", "gender=\"" + gender + "\"");
        else
            this.insertNode("voice", "gender=\"" + gender + "\"");
    },
    eSetReader: function(name) {
        var tagName = "voice" + name;
        this.insertNode(tagName, "name=\"" + name + "\"");
    },
    eMakeSentence: function() {
        this.insertNode("sentence");
    },
    eSetPinyin: function(pinyin) {
        var _this = this;
        var editorBody = _this._editor.document.body;
        if (arguments.length == 0) {
            try {
                var range = this.getSelectedRange(); //this._editor.document.selection.createRange();
                this._range = range.duplicate();
                var sText = range.text;
                if (sText.length == 0)
                    return;
                if (/[^\u4e00-\u9fa5]/i.test(sText)) {
                    alert(this.getResx("NotHanzi", "不能为非汉字字符设置拼音。"));
                    return;
                }
                this.createDivPy();
                $("txtPy" + this.index).value = "";
                $("pyMsg" + this.index).innerHTML = this.getResx("PleaseFor", "请为 ") + "<font style='color:#ff0000;'>" + sText + "</font>" + this.getResx("SetPinyinFor", " 设置拼音：");
                Lightbox.utilShowHtml('divPy' + this.index, 'pyclose' + this.index);
                $("txtPy" + this.index).focus();
                var divPy = $("divPy" + this.index);
                var arrayPageSize = LightboxUtil.getPageSize();
                var arrayPageScroll = LightboxUtil.getPageScroll();
                var lightboxTop = arrayPageScroll[1] + (arrayPageSize[3] / 15);
                var lightboxLeft = (arrayPageSize[2] - 500) / 2;
                divPy.style.left = lightboxLeft + "px";
                divPy.style.top = lightboxTop + "px";
            }
            catch (ex) { }
        }
        else {
            this._range.select();
            if (pinyin != "" && pinyin) {
                var mt = pinyin.match(/[a-z]+\d/ig);
                if (pinyin.replace(/([a-z]+[0-9])+/, "") == "" && mt.length == this._range.text.length) {
                    var inHtml = this._range.htmlText;
                    inHtml = inHtml.replace(/([\u4e00-\u9fa5]+)/i, '<span class=phonemeStart py="' + pinyin + '"></span>$1<span class=phonemeEnd>' + pinyin + '</span>');
                    this._range.pasteHTML(inHtml);
                    $("txtPy" + this.index).focus();
                }
                else {
                    alert(this.getResx("ErrPinyin", "输入的拼音格式有误。"));
                    $("txtPy" + this.index).focus();
                    return;
                }
            }
            this._range = null;
            $("pyclose" + this.index).click();
        }
    },
    eReadPinyin: function() {
        var range = this.getSelectedRange(); //this._editor.document.selection.createRange();
        var inHtml = range.htmlText;
        if (/<span[^<>]+?class\s*=\s*(?:'|")*phoneme/i.test(inHtml)) {
            alert(this.getResx("ErrNodeNest", "操作错误，节点嵌套错误或不配对。"));
            return;
        }
        var arrMt = inHtml.match(/[a-z]+\d/ig);
        if (!arrMt) return;
        if (arrMt.length > 8) {
            alert(this.getResx("OverMaxReadPy", "设定的汉语拼音个数不能超过 8"));
            return;
        }
        //inHtml = inHtml.replace(/((?:[a-z]+\d)+)/ig, '<span class=phonemeStart lang="zh-cn"></span>$1<span class=phonemeEnd></span>');
        inHtml = inHtml.replace(/((?:[a-z]+\d)+)/ig, function($0, $1) {
            var lowPy = $1.toLowerCase();
            return '<span class=phonemeStart lang="zh-cn"></span>' + lowPy + '<span class=phonemeEnd></span>';
        });
        range.pasteHTML(inHtml);
    },
    eNotRead: function() {
        this.insertNode("sub", "alias=\"\"");
    },
    eSetDialog: function(manName) {
        var editorBody = this._editor.document.body;
        var html = editorBody.innerHTML;
        var arrName = this.getRoleNames();
        var args = arguments;
        arrName.each(function(name) {
            var rgx = new RegExp("(" + name + ")(?!<span)(.+?)((?:<\\/div>|<br\\s*\\/?>|<\\/p>|$))", "ig");
            var isMan = (name == manName);
            var classHead, voiceName;
            if (args.length == 1) {
                classHead = (isMan ? "voiceXiaoyu" : "voiceXiaoyan");
                voiceName = (isMan ? "xiaoyu" : "xiaoyan");
            }
            else if (args[1]) { //英文高级朗读
                classHead = (isMan ? "voiceHenry" : "voiceMary");
                voiceName = (isMan ? "henry" : "mary");
            }
            var reStr = '<span class=subStart alias=""></span>$1<span class=subEnd></span>';
            reStr += '<span class=' + classHead + 'Start name="' + voiceName + '"></span>$2<span class=' + classHead + 'End></span>$3';
            html = html.replace(rgx, reStr);
        });
        editorBody.innerHTML = html;
    },
    eSetMark: function(txtMark) {
        var editorBody = this._editor.document.body;
        if (arguments.length == 0) {
            try {
                this.createDivMark();
                var range = this.getSelectedRange(); //this._editor.document.selection.createRange();
                if (!CSSMLEngine.checkHTML(range.htmlText)) {
                    alert(this.getResx("ErrNodeNest", "操作错误，节点嵌套错误或不配对。"));
                    return;
                }
                this._range = range.duplicate();
                var htmlText = range.htmlText;
                if (htmlText.length == 0) {
                    range.moveStart("textedit", -1);
                    range.select();
                    htmlText = range.htmlText;
                    this._range.select();
                    htmlText = htmlText.replace(/<span\s+class=markStart[^<>]*?>[^<>]*?<\/span>(?:(?!<span\s+class=mark(?:Start|End)).|\r\n|\r|\n)*?<span\s+class=markEnd>[^<>]*?<\/span>/ig, "");
                    var mt = htmlText.match(/<span\s+class=markStart[^<>]*?>[^<>]*?<\/span>/ig);
                    if (mt) {
                        this.readAndSetMark(mt[mt.length - 1]);
                    }
                    else { return; }
                }
                else if (!(/<span\s+class=markStart[^<>]*?>[^<>]*?<\/span>/ig.test(htmlText)) && !(/<span\s+class=markEnd>[^<>]*?<\/span>/ig.test(htmlText))) {
                    range.moveStart("textedit", -1);
                    range.select();
                    htmlText = range.htmlText;
                    this._range.select();
                    htmlText = htmlText.replace(/<span\s+class=markStart[^<>]*?>[^<>]*?<\/span>(?:(?!<span\s+class=mark(?:Start|End)).|\r\n|\r|\n)*?<span\s+class=markEnd>[^<>]*?<\/span>/ig, "");
                    var mt = htmlText.match(/<span\s+class=markStart[^<>]*?>[^<>]*?<\/span>/ig);
                    if (mt) {
                        this.readAndSetMark(mt[mt.length - 1]);
                    }
                    else {
                        $("hidMarkName" + this.index).value = "";
                        $("txtMark" + this.index).value = "";
                    }
                }
                else {
                    var mt = htmlText.match(/<span\s+class=markStart[^<>]*?>[^<>]*?<\/span>(?:(?!<span\s+class=mark(?:Start|End)).|\r\n|\r|\n)*?<span\s+class=markEnd>[^<>]*?<\/span>/ig)
                    if (mt && mt.length == 1 && mt[0] == htmlText) {
                        this.readAndSetMark(mt[0]);
                    }
                    else {
                        alert(this.getResx("ErrNodeNest", "操作错误，节点嵌套错误或不配对。"));
                        return;
                    }
                }
                Lightbox.utilShowHtml('divMark' + this.index, 'markclose' + this.index);
                $("txtMark" + this.index).focus();
            } catch (ex) { }
        }
        else if (arguments.length == 1) {
            if (txtMark == "") {
                alert(this.getResx("MarkRequired", "请输入注释的内容"));
                return;
            }
            txtMark = encodeURIComponent(txtMark); ;
            var hidMarkName = $F("hidMarkName" + this.index);
            if (hidMarkName == "") {
                this._range.select();
                var inHtml = this._range.htmlText;
                inHtml = inHtml.replace(/(?:\r\n|\r|\n)/g, "");
                var now = new Date();
                var rndMarkName = now.getFullYear() + "" + now.getMonth() + "" + now.getDay() + "" + now.getHours() + "" + now.getMinutes() + "" + now.getSeconds();
                rndMarkName = rndMarkName + Math.round(Math.random() * 100);
                inHtml = inHtml.replace(/(.*?)(<br\/?>)?$/i, '<span class=markStart name="' + rndMarkName + '" markcontent="' + txtMark + '"></span>$1<span class=markEnd></span>$2');
                this._range.pasteHTML(inHtml);
            }
            else {
                var re = new RegExp('<span\\s+class=markStart\\s+[^<>]*?name=\\"' + hidMarkName + '\\"[^<>]*?>', 'i');
                editorBody.innerHTML = editorBody.innerHTML.replace(re, '<span class=markStart name="' + hidMarkName + '" markcontent="' + txtMark + '">');
            }
            this._range = null;
            $("markclose" + this.index).click();
        }
    },
    readAndSetMark: function(strMt) {
        $("hidMarkName" + this.index).value = /<span[^<>]+?name=\"([^<>]+?)\"[^<>]*?>/i.exec(strMt)[1];
        $("txtMark" + this.index).value = decodeURIComponent(/<span[^<>]+?markcontent=\"([^<>]*?)\"[^<>]*?>/i.exec(strMt)[1]);
    },
    insertImage: function(imgHtml) {
        try {
            var range = this.getSelectedRange(); //this._editor.document.selection.createRange();
            range.pasteHTML(imgHtml);
        } catch (ex) { }
    },
    getRoleNames: function() {
        var html = this._editor.document.body.innerHTML;
        var arrName = new Array();
        var mt = html.match(/\s*(?:^|<\/?div>|<br\/?>)\s*\S+?(?:\:|：)/ig);
        if (mt) {
            for (var i = 0; i < mt.length; i++) {
                var name = mt[i].match(/[^<>]+(?:\:|：)/i, "$1")[0].replace(/^(?:&nbsp;|\s)+/ig, "");
                var hasName = false;
                for (var j = 0; j < arrName.length; j++) {
                    if (name == arrName[j]) {
                        hasName = true;
                        break;
                    }
                }
                if (!hasName)
                    arrName.push(name);
            }
        }
        return arrName;
    },
    eSetBreak: function() {
        var range = this.getSelectedRange(); //this._editor.document.selection.createRange();
        var time = range.text.strip();

        if (isNaN(time)) {
            alert("时间必须是数字");
        }
        else {
            range.pasteHTML('<span class=breakStart></span><span class=breakEnd>' + time + '</span>');
        }
    },
    toCSSML: function() {
        var s = this._editor.document.body.innerHTML;
        if (!CSSMLEngine.checkHTML(s)) {
            alert(this.getResx("ErrNode", "节点不配对，请检查文本内容。"));
            return "";
        }
        return CSSMLEngine.toCSSML(s);
    },
    getResx: function(key, defaultStr) {
        return CSSMLEngine.getResx(key, defaultStr);
    }
};
CSSMLEngine.toCSSML = function(srcHtml) {
    var s = srcHtml;
    s = s.replace(/(<span\s+[^<>]*)style\=\"[^<>]*?\"([^<>]*>)/ig, "$1$2"); //remove styles
    s = s.replace(/<\/?img[^<>]*?>/ig, ""); //remove images
    s = s.replace(/<span\s+[^<>]*?class=breakStart[^<>]*?>.*?<\/span>.*?<span\s+class=breakEnd>(.+?)<\/span>/ig, function($0, $1) {
        var time = parseFloat($1);
        time = Math.round(time * 1000);
        return '<break time="' + time + 'ms"/>';
    });
    if (CSSMLEngine._useDisplayPinyin) {
        s = s.replace(/<span\s+[^<>]*?class=phonemeStart[^<>]*?>\s*<\/span>([\u4e00-\u9fa5]+?)<span\s+class=phonemeEnd>(\w+?)<\/span>/ig, '<phoneme py="$2">$1</phoneme>');
    }

    s = s.replace(/<span(\s+[^<>]*?)class=(\w+)(?:Start)([^<>]*?)>.*?<\/span>/ig, "<$2$1$3>");
    s = s.replace(/<span\s+class=(\w+)(?:End)>.*?<\/span>/ig, "</$1>");
    s = s.replace(/<div>(.*?)<\/div>/gi, "<s>$1</s> ");
    s = s.replace(/<br\/?>/ig, "\r\n");
    s = CSSMLEngine.unHtmlCode(s);
    //fix
    s = s.replace(/<voice\w*([^<>]*)>/ig, "<voice$1></s> ");
    s = s.replace(/<\/voice\w*>/ig, "</voice>");
    //s = s.replace(/(<\/?)voice\w*/ig,"$1voice");
    s = s.replace(/(<\/?)prosody\w*/ig, "$1prosody");
    s = s.replace(/<\/?div>/ig, "");

    s = s.replace(/^<p>/i, "");
    s = s.replace(/\r\n\s*<p>/ig, "\r\n");
    s = s.replace(/<\/p>/ig, "");
    s = s.replace(/<p>/ig, "\r\n");
    s = s.replace(/<a href=.*?>(.*?)<\/a>/ig, "\$1");
    s = s.replace(/(<sub alias="">(\n|\r|.)+?<\/sub>)/, '</s> <s>$1</s> <s>');
    return "<?xml version=\"1.0\" encoding=\"GB2312\"?><speak>" + s + "</speak>";
}
CSSMLEngine.checkHTML = function(srcHtml) {
    srcHtml = srcHtml.replace(/(<span\s+[^<>]*)style\=\"[^<>]*?\"([^<>]*>)/ig, "$1$2");
    while (/<span\s+[^<>]*?class=(\w+)Start[^<>]*?>[^<>]*?<\/span>(?:(?!<span\s+class=\w+(?:Start|End)).|\r\n|\r|\n)*?<span\s+class=\1End>[^<>]*?<\/span>/ig.test(srcHtml)) {
        srcHtml = srcHtml.replace(/<span\s+[^<>]*?class=(\w+)Start[^<>]*?>[^<>]*?<\/span>(?:(?!<span\s+class=\w+(?:Start|End)).|\r\n|\r|\n)*?<span\s+class=\1End>[^<>]*?<\/span>/ig, "");
    }
    var matchResult = srcHtml.match(/<span\s+[^<>]*?class=\w+Start[^<>]*?>[^<>]*?<\/span>/ig);
    var sLen = matchResult == null ? 0 : matchResult.length;
    matchResult = srcHtml.match(/<span\s+class=\w+End>[^<>]*?<\/span>/ig);
    var eLen = matchResult == null ? 0 : matchResult.length;
    if (0 == sLen && 0 == eLen)
        return true;
    else
        return false;
}
CSSMLEngine.checkCanRead = function(srcHtml) {
    while (/<span\s+class=subStart[^<>]*?>[^<>]*?<\/span>(?:(?!<span\s+class=sub(?:Start|End)).|\r\n|\r|\n)*?<span\s+class=subEnd>[^<>]*?<\/span>/ig.test(srcHtml)) {
        srcHtml = srcHtml.replace(/<span\s+class=subStart[^<>]*?>[^<>]*?<\/span>(?:(?!<span\s+class=sub(?:Start|End)).|\r\n|\r|\n)*?<span\s+class=subEnd>[^<>]*?<\/span>/ig, "");
    }
    srcHtml = srcHtml.replace(/<[^<>]*?>/g, "");
    if (/[A-ZＡ-Ｚ０-９0-9\u4e00-\u9fa5]+/i.test(srcHtml.unescapeHTML()))
        return true;
    else
        return false;
}
CSSMLEngine.checkPinyin = function(srcHtml) {
    var arrErr = new Array();
    var regx = /<span\s+class=phonemeStart[^<>]*?>.*?<\/span>([\u4e00-\u9fa5]+?)<span\s+class=phonemeEnd>([^<>]+?)<\/span>/ig;
    var obj;
    while (regx.exec(srcHtml)) {
        obj = { txt: RegExp.$1, py: RegExp.$2 };
        if (obj.py.replace(/([a-z]+[0-9])+/, "") != "")
            arrErr.push(obj);
    }
    return arrErr;
}
CSSMLEngine.unHtmlCode = function(str) {
    return str.replace(/&nbsp;/ig, " ").replace(/&lt;/ig, "＜").replace(/&gt;/ig, "＞").replace(/&amp;/ig, "＆").replace(/&quot;/ig, '＂').replace(/&copy;/ig, "©").replace(/&times;/ig, "×").replace(/&divide;/ig, "÷").replace(/&reg;/ig, "®");
    //unescapeHTML();
}

CSSMLEngine.getEvalText = function(srcHtml) {
    var txt = srcHtml.replace(/<br\/?>/ig, "\r\n");
    txt = txt.replace(/<span\s+class=\w+(?:start|end).*?>.*?<\/span>/ig, "").replace(/<[^<>]+>/ig, "");
    txt = CSSMLEngine.unHtmlCode(txt);
    return txt;
}
CSSMLEngine.getBaseHtml = function(srcHtml) {
    var html = srcHtml.replace(/<span\s+class=\"?\w+(?:start|end)\"?[^<>]*?>[^<>]*?<\/span>/ig, '');
    return html;
}
CSSMLEngine.generateNoteTip = function(srcHtml) {
    var re = /<span[^<>]+?markcontent=\"([^<>]*?)\"[^<>]*?>[^<>]*?<\/span>((?:(?!<span\s+class=mark(?:Start|End)).|\r\n|\r|\n)*?)<span\s+class=markEnd>[^<>]*?<\/span>/ig;
    srcHtml = srcHtml.replace(re, function($0, $1, $2) {
        var markContent = decodeURIComponent($1).replace(/(?:\r\n|\n|\r)/g, "[br/]");
        markContent = markContent.escapeHTML().replace(/\[br\/\]/ig, "<br/>").replace(/ /g, "&nbsp;");
        var sScript = "var tip=new TipEngine();tip.sticky=false;tip.show(this,this.firstChild.innerHTML);";
        var sTtsMark = "[<span style='font-weight:bold;color:#0865A0;'>" + CSSMLEngine.getResx("ttsMark", "注释") + "</span>]<br/>";
        var sNote = "<span class='markTip' onmouseover=\"" + sScript + "\"><span style='display:none;'>" + sTtsMark + markContent + "</span>" + $2 + "</span>";
        return sNote;
    });
    return srcHtml;
}
CSSMLEngine.filterEvalHtml = function(srcHtml) {
    return srcHtml; //建华在服务端处理
}

/**----------多语言------------**/
CSSMLEngine.resxObj = null;
CSSMLEngine.callResx = function()
{
    var GET_CSSMLENGINEE_RESX = 1;
    var pars='operate='+GET_CSSMLENGINEE_RESX;
	myRequest=new Ajax.Request(
		CSSMLEngine._cssPath+'../'+'AjaxCall.aspx?rnd='+((new Date()).valueOf()),
		{
			parameters: pars,
			onSuccess:function(req){try{CSSMLEngine.resxObj=eval("("+req.responseText+")");}catch(ex){}},
			onFailure:function(){}
		}
	);  
}
CSSMLEngine.getResx = function(key,defaultStr){
    if(CSSMLEngine.resxObj && CSSMLEngine.resxObj[key])
        return CSSMLEngine.resxObj[key];
    return defaultStr;
}
