
function iCabCaseInsensitiveIndexOf(s,t,idx) {
    var i,j;
    for (i=0; i<s.length-t.length; i++) {
        var ok = true;
        for (j=0; j<t.length;j++) {
            if (s.charAt(i+j+idx).toLowerCase() != t.charAt(j).toLowerCase()) {
                ok = false;
                break;
            }
        }
        if (ok) return i+idx;
    }
    return -1;
}

function iCabProcessComment(code,idx) {
    var length = 0;
    var closed = true;
    var i;
    for (i=idx+2; i<code.length; i++) {
        var c = code.charAt(i);
        if (c == "-" && i+1<code.length && code.charAt(i+1) == "-") {
            closed = !closed;
            i++;
        } else if (c == " " || c == "\t" || c == "\n" || c == "\r") {
            // ignore
        } else if (c == ">") {
            if (closed) {
                length = i - idx + 1;
                break;
            }
        }
    }
    return length;
}

function iCabProcessScript(code,idx) {
    var i = iCabCaseInsensitiveIndexOf(code,">",idx);
    if (i > 0) {
        if (code.charAt(i-1) == "/") {
            return i+1 - idx;
        }
        var i = iCabCaseInsensitiveIndexOf(code,"</script>",i);
        if (i >= 0) {
            return i+9 - idx;
        }
    }
    return 0;
}

function iCabProcessStyle(code,idx) {
    var i = iCabCaseInsensitiveIndexOf(code,"</style>",idx);
    if (i >= 0) {
        return i+8 - idx;
    }
    return 0;
}

function iCabProcessTag(code,idx) {
    var result = new Object();
    result.length = 0;
    result.name = "";
    result.endtag = false;
    var i = iCabCaseInsensitiveIndexOf(code,">",idx);
    if (i >= 0) {
        result.length = i+1 - idx;
        if (code.charAt(idx+1) == "/") {
            result.endtag = true;
            i = idx+2;
        } else {
            i = idx+1;
        }
        while (i < code.length) {
            var c = code.charAt(i,1).toLowerCase();
            if (c <= " " || c == ">") break;
            result.name += c;
            i++;
        }
    }
    return result;
}

function iCabProcessElement(code, idx) {
    var result = new Object();
    result.length = 0;
    result.type = 0;
    result.lbbefore = false;
    result.lbafter = false;
    
    var i = idx+1;
    if (i < code.length) {
        var c = code.charAt(i).toLowerCase();
        if (c == "s" && code.substr(i,6).toLowerCase() == "script") {
            result.length = iCabProcessScript(code,idx);
            if (result.length > 0) {
                result.type = 5;
                result.lbbefore = true;
                result.lbafter = true;
            }
        } else if (c == "s" && code.substr(i,5).toLowerCase() == "style") {
            result.length = iCabProcessStyle(code,idx);
            if (result.length > 0) {
                result.type = 6;
                result.lbbefore = true;
                result.lbafter = true;
            }
        } else if (c >= "a" && c <= "z" || c == "/") {
            var tag = iCabProcessTag(code,idx);
            if (tag.name == "a" || tag.name == "area") {
                result.type = 1;
            } else if (tag.name == "form" || tag.name == "input" || tag.name == "button" || tag.name == "select" || tag.name == "option" || tag.name == "textarea") {
                result.type = 2;
            } else if (tag.name == "img" || tag.name == "embed" || tag.name == "object" || tag.name == "video" || tag.name == "audio" || tag.name == "applet" || tag.name == "iframe") {
                result.type = 3;

            } else if (tag.name == "body" || tag.name == "html" || tag.name == "head") {
                result.type = 7;
                result.lbbefore = true;
                result.lbafter = true;

            } else if (tag.name == "meta" || tag.name == "link" || tag.name == "title") {
                result.type = 7;
                result.lbbefore = (tag.endtag == false);
                result.lbafter = (tag.endtag == true);

                
            } else if (tag.name == "style") {
                result.type = 6;

            } else if (tag.name == "script") {
                result.type = 5;

            } else {
                result.type = 0;
            }
            result.length = tag.length;
            if (tag.name == "h1" || tag.name == "h2" || tag.name == "h3" || tag.name == "h4" || tag.name == "h5" || tag.name == "h6" || tag.name == "pre" || tag.name == "li" || tag.name == "dt" || tag.name == "dd" || tag.name == "td" || tag.name == "th" || tag.name == "col" || tag.name == "colgroup" || tag.name == "title") {
                result.lbbefore = (tag.endtag == false);
                result.lbafter = (tag.endtag == true);
            } else if (tag.name == "p" || tag.name == "div" || tag.name == "bq" || tag.name == "blockquote" || tag.name == "ul" || tag.name == "ol" || tag.name == "dl" || tag.name == "address" || tag.name == "form" || tag.name == "body" || tag.name == "html" || tag.name == "meta" || tag.name == "link" || tag.name == "head" || tag.name == "table" || tag.name == "tr" || tag.name == "thead" || tag.name == "tbody" || tag.name == "tfoot" || tag.name == "br") {
                result.lbbefore = true;
                result.lbafter = true;
            }
        } else if (c == "!") {
            result.length = iCabProcessComment(code,idx);
            if (result.length > 0) {
                result.type = 4;
            }
        }
    }
    
    return result;
}


function iCabShowSource() {
    var html = document.getElementsByTagName("html");
    var code = html[0].outerHTML;
    code = code.replace(/\r\n/g,'\n');
    var output = "";
    var i;
    for (i=0; i<code.length; i++) {
        var c = code.charAt(i);
        if (c == '&') {
            output += "&amp;"
        } else if (c == '<') {
            var element = iCabProcessElement(code,i);
            if (element.length > 0) {
                if (element.type >= 0) {
                    var tag = "<span class='";

                    switch (element.type) {
                        case 0: tag += "tag";       break;
                        case 1: tag += "link";      break;
                        case 2: tag += "form";      break;
                        case 3: tag += "img";       break;
                        case 7: tag += "head";      break;
                        case 4: tag += "comment";   break;
                        case 5: tag += "script";    break;
                        case 6: tag += "style";     break;
                    }
                    tag += "'>";
                    var etag = "</span>";

                    if (element.lbbefore && output.length > 0) tag = "<br>" + tag;
                    if (element.lbafter) etag += "<br>";
                    var e = code.substr(i,element.length);
                    e = e.replace(/\</g,'&lt;');
                    if (element.type == 4 || element.type == 5 || element.type == 6) {
                        e = e.replace(/\n/g,'</div><div>');
                        e = "<div>" + e + "</div>"
                    }
                    output += tag + e + etag;
                }
                i += element.length-1;
            }
        } else {
            output += c;
        }
    }
    output = output.replace(/\t/g,'  ');
    output = output.replace(/\n/g,'<br>');
    i = output.length;
    while (true) {
        output = output.replace(/ <br>/g,'<br>');
        output = output.replace(/<br><br>/g,'<br>');
        if (output.length == i) break;
        i = output.length;
    }
    output = output.replace(/<br>/g,'</div><div>');
    iCabPostSource(output)
}

function iCabShowSimpleSource() {
    var html = document.getElementsByTagName("html");
    var code = html[0].outerHTML;
    iCabPostSource("<plaintext>"+code)
}

function iCabPostSource(source) {
    var head = "<!doctype html><html><head><style>" +
    "body { font-family: monospace; font-size: 10pt; /*white-space: pre-wrap;*/ word-wrap: break-word; width:100%; height:100%; overflow-x:scroll; background-color: #fff; color: #000; } " +
    "span { margin: 0; padding:0; display:inline; } " +
    "div { margin: 0; padding:0; display:block; } " +
    ".tag { color: #448; } " +
    ".link { color: #844; } " +
    ".form { color: #488; } " +
    ".img { color: #484; } " +
    ".head { color: #88f; } " +
    ".comment { color: #888; } " +
    ".script { color: #848; } " +
    ".style { color: #884; } " +
    "@media (prefers-color-scheme: dark) { " +
    "body { background-color: #282828; color: #ccc; } " +
    ".tag { color: #66D; } " +
    ".link { color: #D66; } " +
    ".form { color: #6CC; } " +
    ".img { color: #6A6; } " +
    ".head { color: #88f; } " +
    ".comment { color: #999; } " +
    ".script { color: #969; } " +
    ".style { color: #996; } " +
    "} " +
    "</style></head><body>\n<div>";
    var footer = "</div>\n</body></html>"
    window.webkit.messageHandlers.iCab.postMessage({"source": head + source + footer});
}
