function updateField(id, field, replacementInput, table) {
    var fields = [];
    if (typeof(field) != 'string') {
        fields = field;
        field = fields.join('');
    }
    var link = document.getElementById('uf-' + id + '-' + field);
    link.style.display = 'none';

    if (link.parentNode.childNodes.length > 1) {
        for (var i = 0; i < link.parentNode.childNodes.length; i++) {
            if (link.parentNode.childNodes[i] == link || link.parentNode.childNodes[i].className.match(/updatefield-(?:loading|status)/))
                continue;
            link.parentNode.childNodes[i].style.display = '';
        }
        return;
    }

    var text = document.createElement('span');
    text.style.display = 'none';
    link.parentNode.insertBefore(text, link);
    text.appendChild(document.createTextNode(''));

    if (replacementInput) {
        replacementInput = document.getElementById(replacementInput);
        var input = replacementInput.cloneNode(true);
        input.style.display = '';
        link.parentNode.insertBefore(input, link);
    }
    else {
        var input = document.createElement('input');
        input.type = 'text';
        input.className = 'updatefield-input';
        link.parentNode.insertBefore(input, link);
    }

    var done = document.createElement('a');
    done.className = 'updatefield-done';
    done.href = 'javascript:void(0)';
    done.onclick = function () {
        stat.style.display = 'none';

        var url = '/cgi-bin/divesites/update.cgi?ID=' + escape(id);
        var display = '';
        if (fields.length) {
            for (var i = 0; i < fields.length; i++) {
                var inputs = input.getElementsByTagName('input');
                var val = '';
                for (var j = 0; j < inputs.length; j++) {
                    if (inputs[j].name == fields[i]) {
                        val = inputs[j].value;
                        break;
                    }
                }
                if (!val) {
                    alert('Enter something'); // FIXME
                    return;
                }
                url += '&' + escape(fields[i]) + '=' + escape(val);
                display += fields[i] + ': ' + val + ' ';
            }
        }
        else {
            if (!input.value.length) {
                alert('Enter something'); // FIXME
                return;
            }
            url += '&' + escape(field) + '=' + escape(input.value);
            display += input.value;
        }
        if (table) {
            url += "&table=" + table;
        }

        img.style.display = '';
        asyncReq(function (req) {
                input.style.display = 'none';
                done.style.display = 'none';
                cancel.style.display = 'none';
                img.style.display = 'none';

                var success = req.responseXML.getElementsByTagName('success');
                if (success.length) {
                    success = success[0].firstChild.nodeValue;

                    text.firstChild.nodeValue = display;
                    text.style.display = '';

                    stat.firstChild.nodeValue = ' ' + success;
                    stat.style.display = '';
                }
                else {
                    var error = req.responseXML.getElementsByTagName('error')[0].firstChild.nodeValue;

                    input.style.display = '';
                    done.style.display = '';
                    cancel.style.display = '';

                    alert(error);
                }
            }, url);
    };
    done.appendChild(document.createTextNode('[Modify]'));
    link.parentNode.insertBefore(done, link);

    var cancel = document.createElement('a');
    cancel.className = 'updatefield-cancel';
    cancel.href = 'javascript:void(0)';
    cancel.onclick = function () {
        link.style.display = '';
        text.style.display = 'none';
        input.style.display = 'none';
        done.style.display = 'none';
        cancel.style.display = 'none';
        img.style.display = 'none';
        stat.style.display = 'none';
    };
    cancel.appendChild(document.createTextNode('[Cancel]'));
    link.parentNode.insertBefore(cancel, link);

    var img = document.createElement('img');
    img.style.display = 'none';
    img.src = '/js/updatefield/loading.gif';
    img.title = 'Loading...';
    img.className = 'updatefield-loading';
    link.parentNode.insertBefore(img, link);

    var stat = document.createElement('span');
    stat.style.display = 'none';
    stat.className = 'updatefield-status';
    link.parentNode.insertBefore(stat, link);
    stat.appendChild(document.createTextNode(''));
}

function asyncReq(handler, url, post_data) {
    var req;
    if (window.XMLHttpRequest)
        req = new XMLHttpRequest();
    else if (window.ActiveXObject)
        req = new ActiveXObject("Microsoft.XMLHTTP");
    else {
        alert('Your browser does not support XMLHttpRequest');
        return;
    }

    req.onreadystatechange = function (e) {
        if (req.readyState == 4) {
            if (req.status == 200)
                handler(req);
            else
                alert('A ' + req.status + " error occured while retrieving the XML data:\n" + req.statusText);
        }
    };
    req.open(post_data ? "POST" : "GET", url, true);
    if (post_data)
        req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    req.send(post_data);
}

