var FindFirstWhat, HTMLIsValidExt, HTMLIsValidAA;
function HTMLIsValid(checkstring, additional_disallowed_tags, additional_disallowed_attributes)
{
    s = checkstring;
    q = new Array(); qp = 0;
    
    if(typeof(additional_disallowed_tags) == "undefined") additional_disallowed_tags = new Array();
    if(typeof(additional_disallowed_attributes) == "undefined") additional_disallowed_attributes = new Array();

    disallowed_tags = new Array("meta", "script", "base", "basefont", "body", "html", "link", "embed", "object", "applet", "iframe", "plaintext", "style");
    disallowed_tags = disallowed_tags.concat(additional_disallowed_tags);
    if(HTMLIsValidExt) disallowed_tags = disallowed_tags.concat(HTMLIsValidExt);
    HTMLIsValidAA = additional_disallowed_attributes;
    // Mimochodem, při povolení něčeho, co může mít HREF, nezapomenout v něm zakázat javascript:/about:

    while((p = s.indexOf("<")) != -1) {
        s = s.substr(p);
        if((p = FindFirstStr(s, new Array(">", " "), 0)) === false) return "Kontrola HTML: Chyba v HTML kódu: Neukončená lomená závorka? (pro < chybí >)";
        tag = s.substr(1, p - 1);
        if(tag.toLowerCase() != tag) return "Kontrola HTML: Všechny tagy musí být psány malými písmeny, např. <input> namísto <INPUT>.";
        if(_in_array(tag, disallowed_tags)) return "Kontrola HTML: Nalezen nepovolený tag " + tag.toUpperCase() + ".";
        if(tag.charAt(0) == "/") {
            if("/" + q[--qp] != tag)
                return "Kontrola HTML: Očekáván uzavírací tag " + q[qp].toUpperCase() + " a nalezen uzavírací tag " + tag.substr(1).toUpperCase() + ".";
        }
        else if(tag != "img" && tag != "input" && tag != "br" && tag != "hr")
            q[qp++] = tag;

        s = _ltrim(s.substr(tag.length + 1));
        while(s.charAt(0) != ">") {
            if((p = FindFirstStr(s, new Array(" ", "=", ">"), 0)) === false) return "Kontrola HTML: Chyba v HTML kódu: Neukončená lomená závorka? Chybí uzavírací uvozovka či apostrof?";
            attrib = s.substr(0, p);
            attrval = '';
            if(FindFirstWhat == "=") {
                if(s.charAt(p + 1) == '"') {
                    if((pp = s.indexOf('"', p + 2)) == -1) return "Kontrola HTML: Chyba v HTML kódu: Chybí uzavírací uvozovka?";
                    attrval = s.substr(p + 2, pp - p - 2);
                    s = _ltrim(s.substr(pp + 1));
                }
                else if(s.charAt(p + 1) == "'") {
                    if((pp = s.indexOf("'", p + 2)) == -1) return "Kontrola HTML: Chyba v HTML kódu: Chybí uzavírací apotrof?";
                    attrval = s.substr(p + 2, pp - p - 2);
                    s = _ltrim(s.substr(pp + 1));
                }
                else {
                    if((pp = FindFirstStr(s, new Array(" ", ">"), p + 1)) === false) return "Kontrola HTML: Chyba v HTML kódu: Neukončená lomená závorka? Chybná definice atributu u tagu " + tag.toUpperCase() + "?";
                    attrval = s.substr(p + 1, pp - p - 1);
                    s = _ltrim(s.substr(pp));
                }
            }
            else s = _ltrim(s.substr(p));
            if((tmp = HTMLAttributeIsValid(attrib, attrval, tag)) !== true) return tmp;
        }
    }
    if(qp != 0) return "Kontrola HTML: Neuzavřeny všechny tagy (například " + q[qp - 1].toUpperCase() + ").";
    return true;
}
function FindFirstStr(where, what, offset)
{
    a = new Array(); 
    for(i = 0; i < what.length; i++)
        if((tmp = where.indexOf(what[i], offset)) != -1)
            a[what[i]] = tmp;
    for(i in a) { // pouze zjišťuje, zda 'a' není prázdné pole
        tmp = _min(a);
        FindFirstWhat = _array_search(tmp, a);
        return tmp;
    }
    return false;
}
function HTMLAttributeIsValid(aname, aval, tagname)
{
    if(aname.toLowerCase() != aname)
        return "Kontrola HTML: Kontrola atributů: Všechny atributy musí být psány malými písmeny (např. <input type='button'> namísto <INPUT TYPE='BUTTON'>).";

    aval = aval.toLowerCase();
    if(aname == "style" && aval.indexOf('position') != -1 && (aval.indexOf('absolute') != -1 || aval.indexOf('relative') != -1)) return "Kontrola HTML: Kontrola atributů: Nepovolené vlatnosti v atributu STYLE.";
    if(aname == "width" && aval > 400) return "Kontrola HTML: Kontrola atributů: WIDTH má příliš velkou hodnotu.";
    if(aname == "height" && aval > 400) return "Kontrola HTML: Kontrola atributů: HEIGHT má příliš velkou hodnotu.";
    if(aname == "size" && aval > 7) return "Kontrola HTML: Kontrola atributů: SIZE bere nejvýše 7. A doporučuji nejvýše 6.";
    if(aname == "type" && aval == "" && tagname == "input") return "Kontrola HTML: Kontrola atributů: Tag INPUT nesmí mít TYPE s prázdnou hodnotou (MSIE bug).";
    if(aname.search("^on") != -1 && aname.search("^(onclick|ondblclick|onmousedown|onmouseup|oncontextmenu)$") == -1) return "Kontrola HTML: Kontrola atributů: Nalezen nepovolený atribut " + aname.toUpperCase() + ".";
    if(aname.search("^(src|lowsrc|dynsrc)$") != -1 && aval.search("about:|javascript:|vbscript:") != -1) return "Kontrola HTML: Kontrola atributů: Nepovolené použítí javascript: či vbscript: či about: v " + aname.toUpperCase() + ".";
    if(aname.search("^(src|lowsrc|dynsrc)$") != -1 && aval.search("op.php|kick.php|deop.php|bans.php|putmsg.php") != -1) return "Kontrola HTML: Kontrola atributů: Pokus o narušení bezpečnosti chatu pomocí volání systémového skriptu v atributu " + aname.toUpperCase() + ".";
    for(i in HTMLIsValidAA)
         if(aname == HTMLIsValidAA[i])
             return "Kontrola HTML: Kontrola atributů: Nalezen nepovolený atribut " + aname.toUpperCase() + '.';
    return true;
}
function _ltrim(s)
{
    while(s.charAt(0) == " " || s.charAt(0) == "\n" || s.charAt(0) == "\r")
        s = s.substr(1);
    return s;
}
function _min(a)
{
    min = 9999999;
    for(i in a)
        if(a[i] < min) {
            min = a[i];
            array_search_tmp = i;
        }
    return min;
}
function _in_array(what, where)
{
    for(i in where)
        if(what == where[i])
            return true;
    return false;
}
var array_search_tmp;
function _array_search(what, where) // WARN:SIMULATED
{
    return array_search_tmp;
}
