var nowtools = {
    emailPattern: /^[0-9a-zA-z\.\-_]+@[0-9a-zA-z\.\-_]+\.[a-z]+$/,
    emailsPattern: /^(([0-9a-zA-z\.\-_]+@[0-9a-zA-z\.\-_]+\.[a-z]+)\s*)+$/,
    numberPattern: /^\+?(((\d+|\d{1,3})((\,)?\d{3})*)?(\.(\d{1,2})?)?)$/,

    each: function(list, func) {
        for( var i = 0; i < list.length; i++ )
            func(list[i], i);
    },

    event: function(obj, e, func) {
        if( obj.addEventListener ) {
            obj.addEventListener(e, func, false);
        }
        else if( obj.attachEvent ) {
            obj.attachEvent("on" + e, func);
        }
        else {
            obj["on" + e] = func;
        }
    },

    stop: function(event) {
        if( event.preventDefault ) {
            event.preventDefault();
            event.stopPropagation();
        }
        else {
            event.returnValue = false;
            event.cancelBubble = true;
        }
    },

    invalid: function(value, required, pattern) {
        pattern = arguments.length > 2 ? pattern : /.*/;
        return (value == "" && required) || (value != "" && !pattern.test(value));
    },

    normalizeEmails: function(s) {
        return s.replace(/[,\r\n;]/g, "\n").replace(/\n+/g, "\n");
    },

    normalizeCurrency: function(s) {
        return s.replace(/\$/g, "");
    },

    tooCheap: function(s, atLeast) {
        return parseFloat(s.replace(/[\$,]/g, "")) < atLeast;
    },

    submit: function(form) {
        form = nowtools.$(form);
        if( form.onsubmit && form.onsubmit() )
            form.submit();
    },

    showErrors: function(divId, errors) {
        var html = "";
        nowtools.each(errors, function(error) { html += "<li>" + error + "</li>"; });
        nowtools.$(divId).innerHTML = "<ul>" + html + "</ul>";
    },

    externalizeLinks: function() {
        var links = document.getElementsByTagName("a");
        nowtools.each(links, function(a) { if( a.className == "external" ) a.target = "_blank"; });
    },

    $: function(x) {
        return typeof(x) == "string" ? document.getElementById(x) : x;
    }
};
