dataGridFieldFunctions = new Object()

dataGridFieldFunctions.removeFieldRow = function(node) {
    /* Remove the row in which the given node is found */
    
    var row = this.getParentElement(node, 'TR')
    var tbody = this.getParentElement(row, 'TBODY')
    tbody.removeChild(row);
}

dataGridFieldFunctions.getInputOrSelect = function(node) {
    /* Get the (first) input or select form element under the given node */
    
    var inputs = node.getElementsByTagName("input");
    if(inputs.length > 0) {
        return inputs[0];
    }
    
    var selects = node.getElementsByTagName("select");
    if(selects.length > 0) {
        return selects[0];
    }

    return null;
}


dataGridFieldFunctions.addRowOnChange = function(e) {
    /* Add a new row when changing the last row */

    // XXX: Generalize window.event for windows
    // Grab current node, replicate, remove listener, append
    var currnode = window.event ? window.event.srcElement : e.currentTarget;

    // XXX Should add/remove event listeners via JS, but IE has
    // non-standard methods.  Not hard, but for now, just check 
    // if we are the last row.  If not, bail.
    
    var tbody = this.getParentElement(currnode, "TBODY");
    var tr = this.getParentElement(currnode, "TR");
    var rows = tbody.getElementsByTagName("TR");
    
    if(rows.length ==(tr.rowIndex)) {
        // Create a new row
        var newtr = tr.cloneNode(true);
        tr.parentNode.appendChild(newtr);
            
        // Turn on hidden button images for current node
        var imgs = tr.getElementsByTagName("img");
        for(var i=0; i<imgs.length; i++)
            imgs[i].style.display = "block";
                                                       
        // Clear content of newly created cells that were duplicated from 
        // current cell
        cells = newtr.getElementsByTagName("td");
        for(var i=0; i<cells.length; i++) {
            
            td = cells[i];
            
            input = this.getInputOrSelect(td);
            if(input == null) 
                continue;

            input.value = ""
        }
        
        this.updateOrderIndex(tbody)
    }
}


dataGridFieldFunctions.getParentElement = function(currnode, tagname) {
    /* Find the first parent node with the given tag name */

    tagname = tagname.toUpperCase();
    var parent = currnode.parentNode;

    while(parent.tagName.toUpperCase() != tagname) {
        parent = parent.parentNode;
        // Next line is a safety belt
        if(parent.tagName.toUpperCase == "BODY") 
            return null;
    }

    return parent;
}


dataGridFieldFunctions.moveRowDown = function(node){
    /* Move the given row down one */
    
    var row = this.getParentElement(node, "TR")
    var tbody = this.getParentElement(row, "TBODY");
    var rows = tbody.getElementsByTagName('TR')
    var idx = null
    
    // We can't use nextSibling because of blank text nodes in some browsers
    // Need to find the index of the row
    for(var t = 0; t < rows.length; t++) {
        if(rows[t] == row) {
            idx = t;
            break;
        }
    }

    // Abort if the current row wasn't found
    if(idx == null)
        return;
        
    // If this was the last row (before the blank row at the end used to create
    // new rows), move to the top, else move down one.
    if(idx + 2 == rows.length) {
        var nextRow = rows.item(0)
        this.shiftRow(row, nextRow)
    } else {
        var nextRow = rows.item(idx+1)
        this.shiftRow(nextRow, row)
    }
    
    this.updateOrderIndex(tbody)

}

dataGridFieldFunctions.moveRowUp = function(node){
    /* Move the given row up one */
    
    var row = this.getParentElement(node, "TR")
    var tbody = this.getParentElement(row, "TBODY");
    var rows = tbody.getElementsByTagName('TR')
    var idx = null
    
    // We can't use nextSibling because of blank text nodes in some browsers
    // Need to find the index of the row
    for(var t = 0; t < rows.length; t++) {
        if(rows[t] == row) {
            idx = t;
            break;
        }
    }
    
    // Abort if the current row wasn't found
    if(idx == null)
        return;
        
    // If this was the first row, move to the end (i.e. before the blank row
    // at the end used to create new rows), else move up one
    if(idx == 0) {
        var previousRow = rows.item(rows.length - 1)
        this.shiftRow(row, previousRow)
    } else {
        var previousRow = rows.item(idx-1)
        this.shiftRow(row, previousRow)
    }
    
    this.updateOrderIndex(tbody)
}

dataGridFieldFunctions.shiftRow = function(bottom, top){
    /* Put node top before node bottom */
    
    bottom.parentNode.insertBefore(bottom, top)   
}

dataGridFieldFunctions.updateOrderIndex = function (tbody) {
    /* Update the hidden orderindex variables to be in the right order */
    
    var xre = new RegExp(/^orderindex__/)
    var idx = 0;
    for (var c = 0; (cell = tbody.getElementsByTagName('INPUT').item(c)); c++) {
        if (cell.getAttribute('id')) {
            if (xre.exec(cell.id)) {
                cell.value = idx++;
            }
        }
    }
}


