// 'rootNode' (Node) node to start on
// 'maxCharacterRun' (integer)  longest run of characters before break
// 'resetOnTags' (Array) reset counter on these tags
// 'ignoreTags' (Array) tags to ignore direct children if text nodes
function addingBreaks(rootNode, maxCharacterRun, ignoreTags) {
    // Defaults (if arguments are null or undefined)
    if (isNotDefined(maxCharacterRun)) {
        maxCharacterRun = 20;
    }
    if (isNotDefined(ignoreTags)) {
        ignoreTags = [];
    }
 
    var reWhitespace = /\s+/;
    var reOnlyWhitespace = /^\s*$/;
    // Start
    ownNorm();
    var nextX = rootNode.firstChild;
    for ( ; ; ) { // infinite loop
        nextX = innerFunc(nextX);
        if (!nextX) { break; }
    }
    ownNorm();
    return;
    // recursive function for node and children.
    // returns next node to use
    // uses addingBreaks() arguments by scope
    function innerFunc(nod, currentRun) {
        //var nextNode = nod.nextSibling;
        if (nod.nodeName == '#text') { // Text Node
            if (reOnlyWhitespace.test(nod.data)) {
                return nod.nextSibling;
            }
            for ( ; ; ) {
                if (nod.length <= maxCharacterRun) {
                    return nod.nextSibling;
                }
                var foundat = (nod.data+'').search(reWhitespace);
                if (foundat == -1) {
                    var nextnode = nod.splitText(maxCharacterRun);
                    nod.data += '- ';
                    nod = nextnode;
                    //return [nod.nextSibling, currentRun];
                }
                else {
                    nod = nod.splitText(foundat+1);
                }
            }
        }
        var nodename = nod.nodeName;
        if (ignoreTags.length) {
            for (var i=0; i<ignoreTags.length; i++) {
                if (nod.nodeName == ignoreTags[i]) {
                    return nod.nextSibling;
                }
            }
        }
        var nextX = nod.firstChild;
        if (isNotDefined(nextX)){return nod.nextSibling;}
        for ( ; ; ) { // infinite loop
            nextX = innerFunc(nextX);
            if (!nextX) { break; }
        }
        return nod.nextSibling;
    }
    // safe way to use document.normalize().
    // uses addingBreaks() argument by scope
    function ownNorm() {
        try {
            rootNode.ownerDocument.normalize();
        }
        catch (e) {}
    }
    
    // simple test to see if argument was passed in or null
    function isNotDefined(arg) {
        return ((typeof arg == 'undefined') || (arg == null));
    }
}
