function popupError(msg, height, width) {
    win = open("", "ErrorWindow",
               "alwaysRaised=1"
               +",resizable=0"
               +",height="+(height+130)
               +",width="+width
               +",scrollbars=1"
               +",screenX="+(self.screenX+(self.outerWidth/2)-width/2)
               +",screenY="+(self.screenY+(self.outerHeight/2)-height/2)
               );
    d = win.document;
    d.write("<html><head><title>Submission Error</title>");
    d.write("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>");
    d.write("</head>");
    d.write("<body bgcolor='white' text='black'>");
    d.write("<center><table>");
    d.write("<tr>");
    d.write("<td>");
    d.write("<h3 align='center'>Submission Errors</h3>");
    d.write("<p>")
    d.write(msg);
    d.write("</p>")
    d.write("</td>");
    d.write("</tr>");
    d.write("<tr>");
    d.write("<td align='center'>");
    d.write("&nbsp;");
    d.write("</td>");
    d.write("</tr>");
    d.write("<tr>");
    d.write("<td align='center'>");
    d.write("<form>");
    d.write("<input type='button' onClick='return self.close()' value='Close'>");
    d.write("</form>"); 
    d.write("</td>");
    d.write("</tr>");
    d.write("</table></center>");
    d.write("</body></html>\n");
}
    
function makeresult(bool, msg) {
    result = Object();
    result.value = bool;
    result.message = msg;
    return result;
}

uregex = /^(http:\/\/|ftp:\/\/|mailto:|gopher:)./;
function ValidateURL(url) {
    if (! uregex.test(url)) {
	return makeresult(false, url.bold()+" is an invalid web address (missing 'http://' prefix?)");
    }
    if (url.indexOf(" ") != -1) {
	return makeresult(false, "url "+url.bold()+" contains spaces");
    }	
    return makeresult(true, "");
}

function ValidateLength(text,length) {
    if (text.length > length) {
	return makeresult(false, "more than "+length+" characters in "+text.slice(0,7).bold()+"...");
    }
    return makeresult(true, "");
}

function ValidateList(list,length) {
    if (list.length > length) {
	return makeresult(false, " more than "+length+" items selected in "+list.name);
    }
    return makeresult(true, "");
}

function ValidateURLs(urls) {
    items = urls.split(/\s+/);
    for (i = 0; i < items.length; i++) {
	result = ValidateURL(items[i]);
	if (! result.value) {
	    return result;
	}
    }
    return makeresult(true, "");
}

function ValidateEmail(addr) {
    at = addr.indexOf("@");
    dot = addr.lastIndexOf(".");
    if (at == -1) {
            return makeresult(false, "'"+addr.bold()+"' does not contain an '@'");
    }
    else if (dot < at) {
            return makeresult(false, "host portion of '"+addr.bold()+"' does not contain a '.'");
    }
    return makeresult(true, "");
}

function ValidateCityState(cs) {
    firstcomma = cs.indexOf(",");
    lastcomma = cs.lastIndexOf(",");
    // require precisely one comma
    if (firstcomma == -1) {
        return makeresult(false, "'"+cs.bold()+"' has no comma separating city and state or country");
    }
    if (firstcomma != lastcomma) {
        return makeresult(false, "'"+cs.bold()+"' has multiple commas");
    }

    return makeresult(true, "");
}

function ValidatePerformer(p) {
    first = p.indexOf(",");
    last = p.lastIndexOf(",");
    slash = p.indexOf("/");
    // at least two commas and no slashes
    if (first > 0 && last > first && slash == -1) {
        return makeresult(false, "'"+p.bold()+"' has multiple names not separated by '/'");
    }
    first = p.indexOf(";");
    last = p.lastIndexOf(";");
    // at least two semicolons and no slashes
    if (first > 0 && last > first && slash == -1) {
        return makeresult(false, "'"+p.bold()+"' appears to separate multiple names by ';' instead of '/'");
    }
    return makeresult(true, "");
}

iregex = /^\s*-?[0-9]+\s*$/;
function ValidateInteger(n) {
    result = iregex.test(n);
    return makeresult(result, result?"":"'"+n.bold()+"' is not an integer");
}

fregex = /^\s*-?[0-9]+(\.[0-9]*)?([eE]-?[0-9]+)?$/;
function ValidateFloat(n) {
    result = fregex.test(n);
    return makeresult(result,
                      result?"":"'"+n.fixed()+"' is not a floating point number");
}

dregex = /^\s*([0-9]{1,2}\/[0-9]{1,2}(\/[0-9]{2,4})?|[0-9]{1,2}\s+[a-z]+(\s+[0-9]{2,4})?|[a-z]+\s+[0-9]{1,2}((,\s*|\s+)[0-9]{2,4})?)\s*$/i;dregex = /^\s*([0-9]{1,2}\/[0-9]{1,2}(\/[0-9]{2,4})?|[0-9]{1,2}\s+[a-z]+(\s+[0-9]{2,4})?|[a-z]+\s+[0-9]{1,2}((,\s*|\s+)[0-9]{2,4})?)\s*$/i;
isodregex = /^\s*([0-9]{4,4}-[0-9]{2,2}-[0-9]{2,2})\s*$/;

function ValidateDate(d) {
    if (d.indexOf("-") > 0) {
        dates = d.split("-");
        result1 = ValidateDate(dates[0]);
        result2 = ValidateDate(dates[1]);
        return makeresult(result1.value && result2.value,
                          result1.message +
                            (result2.value?"":" " + result2.message));
    }
    result = dregex.test(d);
    return makeresult(result, (result?"":"'"+d.bold()+"' doesn't look like a date"));
}

function ValidateISODate(d) {
    result = isodregex.test(d);
    return makeresult(result, (result?"":"'"+d.bold()+"' doesn't look like an ISO date (e.g., 2004-05-09)"));
}

function ValidateForm(form,paramspec) {
    params = paramspec.split(",");
    isvalid = true;
    msgs = Array(params.length);
    for (i = 0; i < params.length; i++) {
        param = params[i].split("/");
        val = eval("form['"+param[0]+"'].value");

        isrequired = param[1].charAt(0) == 'r';
        if (isrequired && (val == null || val.length == 0)) {
            isvalid = false;

	    // trim Zope type quantifiers
	    cindex = param[0].indexOf(":");
	    p = param[0];
            if (cindex != -1) {
		p = param[0].substring(0, cindex);
	    }
            msgs[i] = "missing required parameter " + p.bold();
        }
        else if (val) { 
            type = param[1].substring(1);
            if (type == "int") {
                result = ValidateInteger(val);
                isvalid = isvalid && result.value;
                msgs[i] = result.message;
            }
            else if (type == "email") {
                result = ValidateEmail(val);
                isvalid = isvalid && result.value;
                msgs[i] = result.message;
            }
            else if (type == "length") {
                result = ValidateLength(val,256);
                isvalid = isvalid && result.value;
                msgs[i] = result.message;
            }
            else if (type == "list") {
                result = ValidateList(eval(form[param[0]]),5);
                isvalid = isvalid && result.value;
                msgs[i] = result.message;
            }
            else if (type == "urls") {
		if (val == "http://") {
		    result = makeresult(true,"");
		    val = "";
		    msgs[i] = "";
		} else {
		    result = ValidateURLs(val);
		    isvalid = isvalid && result.value;
		    msgs[i] = result.message;
		}
            }
            else if (type == "url") {
		if (val == "http://") {
		    result = makeresult(true,"");
		    val = "";
		    msgs[i] = "";
		} else {
		    result = ValidateURL(val);
		    isvalid = isvalid && result.value;
		    msgs[i] = result.message;
		}
            }
            else if (type == "citystate") {
                result = ValidateCityState(val);
                isvalid = isvalid && result.value;
                msgs[i] = result.message;
            }
            else if (type == "perf") {
                result = ValidatePerformer(val);
                isvalid = isvalid && result.value;
                msgs[i] = result.message;
            }
            else if (type == "float") {
                result = ValidateFloat(val);
                isvalid = isvalid && result.value;
                msgs[i] = result.message;
            }
            else if (type == "iso") {
                result = ValidateISODate(val);
                isvalid = isvalid && result.value;
                msgs[i] = result.message;
            }
            else if (type == "date") {
                result = ValidateDate(val);
                isvalid = isvalid && result.value;
                msgs[i] = result.message;
            }
            else {
                msgs[i] = "";
            }
        }
        else {
            msgs[i] = "";
        }
// 	alert("param: "+param[0]
// 	      +"\nprops: "+param[1]
// 	      +"\nvalue: "+val
// 	      +"\nisvalid: "+result.value
// 	      +"\nisrequired: "+isrequired
// 	      +"\nmsg: <"+msgs[i]+">");
    }
    if (! isvalid) {
        msg = "";
	ht = 20;
        for (i = 0; i < msgs.length; i++) {
            if (msgs[i]) {
                msg = msg + "<li>" + msgs[i] + "</li>";
		ht += 20;
            }
        }
        popupError("<ul>"+msg+"</ul>", ht, 300);
    }
    return isvalid;
}

function ValidateOneOf(form, paramspec) {
    params = paramspec.split(",");
    isvalid = false;
    for (i = 0; i < params.length; i++) {
        param = params[i];
        val = eval("form['" + param + "'].value");
        if (val != null && val != undefined && val.length != 0) {
            return true;
	}
    }
    msg = "";
    ht = 25;
    for (i = 0; i < params.length; i++) {
        ht += 20;
        msg = msg + "<li>" + params[i].bold() + "</li>";
    }
    msg = "One of the following parameters must be given:<ul>"+msg+"</ul>";
    popupError(msg, ht, 300);
    return false;
}
    
