///import core
///commands 查找替换
///commandsName  SearchReplace
///commandsTitle  查询替换
///commandsDialog  dialogs\searchreplace
/**
 * @description 查找替换
 * @author zhanyi
 */

UE.plugin.register('searchreplace',function(){
    var me = this;

    var _blockElm = {'table':1,'tbody':1,'tr':1,'ol':1,'ul':1};

    var lastRng = null;

    function getText(node){
        var text = node.nodeType == 3 ? node.nodeValue : node[browser.ie ? 'innerText' : 'textContent'];
        return text.replace(domUtils.fillChar,'')
    }

    function findTextInString(textContent,opt,currentIndex){
        var str = opt.searchStr;

        var reg = new RegExp(str,'g' + (opt.casesensitive ? '' : 'i')),
            match;

        if(opt.dir == -1){

            textContent = textContent.substr(0,currentIndex);
            textContent = textContent.split('').reverse().join('');
            str = str.split('').reverse().join('');
            match = reg.exec(textContent);
            if(match){
                return currentIndex - match.index - str.length;
            }

        }else{
            textContent = textContent.substr(currentIndex);
            match = reg.exec(textContent);
            if(match){
                return match.index + currentIndex;
            }
        }

        return  -1
    }
    function findTextBlockElm(node,currentIndex,opt){
        var textContent,index,methodName = opt.all || opt.dir == 1 ? 'getNextDomNode' : 'getPreDomNode';
        if(domUtils.isBody(node)){
            node = node.firstChild;
        }
        var first = 1;
        while(node){
            textContent = getText(node);
            index = findTextInString(textContent,opt,currentIndex );
            first = 0;
            if(index!=-1){
                return {
                    'node':node,
                    'index':index
                }
            }
            node = domUtils[methodName](node);
            while(node && _blockElm[node.nodeName.toLowerCase()]){
                node = domUtils[methodName](node,true);
            }
            if(node){
                currentIndex = opt.dir == -1 ? getText(node).length : 0;
            }

        }
    }
    function findNTextInBlockElm(node,index,str){
        var currentIndex = 0,
            currentNode = node.firstChild,
            currentNodeLength = 0,
            result;
        while(currentNode){
            if(currentNode.nodeType == 3){
                currentNodeLength = getText(currentNode).replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,'').length;
                currentIndex += currentNodeLength;
                if(currentIndex >= index){
                    return {
                        'node':currentNode,
                        'index': currentNodeLength - (currentIndex - index)
                    }
                }
            }else if(!dtd.$empty[currentNode.tagName]){
                currentNodeLength = getText(currentNode).replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,'').length;
                currentIndex += currentNodeLength;
                if(currentIndex >= index){
                    result = findNTextInBlockElm(currentNode,currentNodeLength - (currentIndex - index),str);
                    if(result){
                        return result;
                    }
                }
            }
            currentNode = domUtils.getNextDomNode(currentNode);

        }
    }

    function searchReplace(me,opt){

        var rng = lastRng || me.selection.getRange(),
            startBlockNode,
            searchStr = opt.searchStr,
            span = me.document.createElement('span');
        span.innerHTML = '$$ueditor_searchreplace_key$$';

        rng.shrinkBoundary(true);

        //判断是不是第一次选中
        if(!rng.collapsed){
            rng.select();
            var rngText = me.selection.getText();
            if(new RegExp('^' + opt.searchStr + '$',(opt.casesensitive ? '' : 'i')).test(rngText)){
                if(opt.replaceStr != undefined){
                    replaceText(rng,opt.replaceStr);
                    rng.select();
                    return true;
                }else{
                    rng.collapse(opt.dir == -1)
                }

            }
        }


        rng.insertNode(span);
        rng.enlargeToBlockElm(true);
        startBlockNode = rng.startContainer;
        var currentIndex = getText(startBlockNode).indexOf('$$ueditor_searchreplace_key$$');
        rng.setStartBefore(span);
        domUtils.remove(span);
        var result = findTextBlockElm(startBlockNode,currentIndex,opt);
        if(result){
            var rngStart = findNTextInBlockElm(result.node,result.index,searchStr);
            var rngEnd = findNTextInBlockElm(result.node,result.index + searchStr.length,searchStr);
            rng.setStart(rngStart.node,rngStart.index).setEnd(rngEnd.node,rngEnd.index);

            if(opt.replaceStr !== undefined){
                replaceText(rng,opt.replaceStr)
            }
            rng.select();
            return true;
        }else{
            rng.setCursor()
        }

    }
    function replaceText(rng,str){

        str = me.document.createTextNode(str);
        rng.deleteContents().insertNode(str);

    }
    return {
        commands:{
            'searchreplace':{
                execCommand:function(cmdName,opt){
                    utils.extend(opt,{
                        all : false,
                        casesensitive : false,
                        dir : 1
                    },true);
                    var num = 0;
                    if(opt.all){
                        lastRng = null;
                        var rng = me.selection.getRange(),
                            first = me.body.firstChild;
                        if(first && first.nodeType == 1){
                            rng.setStart(first,0);
                            rng.shrinkBoundary(true);
                        }else if(first.nodeType == 3){
                            rng.setStartBefore(first)
                        }
                        rng.collapse(true).select(true);
                        if(opt.replaceStr !== undefined){
                            me.fireEvent('saveScene');
                        }
                        while(searchReplace(this,opt)){
                            num++;
                            lastRng = me.selection.getRange();
                            lastRng.collapse(opt.dir == -1)
                        }
                        if(num){
                            me.fireEvent('saveScene');
                        }
                    }else{
                        if(opt.replaceStr !== undefined){
                            me.fireEvent('saveScene');
                        }
                        if(searchReplace(this,opt)){
                            num++;
                            lastRng = me.selection.getRange();
                            lastRng.collapse(opt.dir == -1)
                        }
                        if(num){
                            me.fireEvent('saveScene');
                        }

                    }

                    return num;
                },
                notNeedUndo:1
            }
        },
        bindEvents:{
            clearlastSearchResult:function(){
                lastRng = null;
            }
        }
    }
});