/* Shared Javascript Library

This file should contain only *generic* functions used on *multiple* pages.
Specialized Javascript used only by a single page should reside on that page.

Other JavaScript Libraries:

        Action Results -- Javascript functions to mimic server-side Action Results
        messages, such as setInfo(), setWarn(), setError(), and setConfirm() in:
        ~/godspeed/ui/webui/common-packages/navigation/ActionResults.tmpl

*/






// Standard method always called before the closing BODY tag.
function bodyOnLoad() {
        //Test confirm dialog
        //setYesNoConfirm("Ist das gut?","alert('Gut!')");
}

// Simply a more compact method call.
function getObj(Id) {
        obj = document.getElementById(Id);
        return obj
}

// Save the standard alert;
this['standard_alert'] = this['alert'];

// Replaces the standard alert with an improved version.
var abortAlerts = false;
function our_alert(alertmsg) {
        if (!abortAlerts)
                if (!confirm(alertmsg + '\n\n' +
                                         'Continue displaying alerts?'))
                        abortAlerts = true;
}
this['alert'] = our_alert;

// ActionResults Methods
function setInfo(message) {
  setActionResults('action-results-info', 'Info', 'yellow',  message)
}

function setWarn(message) {
  setActionResults('action-results-warn', 'Warning', 'red', message)
}

function setError(message) {
  setActionResults('action-results-error', 'Error', 'red', message)
}

function setAttention(message) {
  setActionResults('action-results-attention', 'Attention', 'yellow', message)
}

function setActionResults(className, title, color, message) {
  var ar_box = getObj('action-results');
  var ar_title = getObj('action-results-title');
  var ar_message = getObj('action-results-message');
  var display = 'None';
  if (message != '') {
    display = '';
    ar_title.className = className;
    ar_title.innerHTML = title;
    ar_message.innerHTML = message;
    window.scrollTo(0,0);
    showObj(ar_box);
    if (className != 'action-results-info')
      flicker('action-results-title', color, '#FFFFFF');
  }
  ar_box.style.display = display;
  ar_title.style.display = display;
  ar_message.style.display = display;
}

function clearActionResults() {
  var ar_box = getObj('action-results');
  var ar_title = getObj('action-results-title');
  var ar_message = getObj('action-results-message');
  ar_box.style.display = 'none';
  ar_title.style.display = 'none';
  ar_message.style.display = 'none';
}

// Confirmation Dialog Methods

// Create a customized confirmation dialog.
// Parameters must not contain double-quotes.
function setConfirm(title, message, buttonCancel, buttonOk, onCancel, onOk,
                    default_choice) {
//    var dlg = YAHOO.webui.SmallDialog('webui.confirmDialog', 'confirmation_dialog', title, message, 'Yes', //'No', onOk, onCancel, modal=true, draggable=false);
    var dlg = YAHOO.webui.SmallDialog('webui.confirmDialog', 'confirmation_dialog', title, message, buttonOk, buttonCancel, onOk, onCancel, modal=true, draggable=false);

    dlg.show();
}

// Shortcut for dialogs that have a cancel action.
function setConfirmCancel(title, message, buttonOk, onOk, default_choice) {
    setConfirm(title, message, 'Cancel', buttonOk,
               '', onOk, default_choice)
}
//Shortcuts for other common dialogs.
function setYesNoConfirm(message, onOk) {
        setConfirmCancel('Confirm', message, 'Continue',
                                         onOk)
}
function setConfirmOk(title, message, onOk) {
        setConfirmCancel(title, message, 'OK', onOk)
}
function setConfirmDelete(message, onOk) {
        setConfirmCancel('Confirm Delete', message,
                                         'Delete', onOk)
}

function confirmDialogHide() {
  return
}

/* These help us find the absolute +X and +Y position of an element from
the top left corner of the browser. */
function getAbsX(elt) { return (elt.x) ? elt.x : getAbsPos(elt,"Left"); }
function getAbsY(elt) { return (elt.y) ? elt.y : getAbsPos(elt,"Top"); }

function getAbsPos(elt,which) {
        iPos = 0;
        while (elt != null) {
                iPos += elt["offset" + which];
                elt = elt.offsetParent;
        }
        return iPos;
}

function getAbsX(ele) { return (ele.x) ? ele.x : getAbsPos(ele,"Left"); }
function getAbsY(ele) { return (ele.y) ? ele.y : getAbsPos(ele,"Top"); }

function getAbsPos(ele, side) {
    pos = 0;
    while (ele != null) {
        pos += ele["offset" + side];
        ele = ele.offsetParent;
    }
    return pos
}

// Contextual Bubble Dialog Methods
YAHOO.webui.buildBubbleDialog('webui.bubbleDialog', 'bubble_dialog');

// Create a customized bubble dialog.
// Parameters must not contain double-quotes.
function bubbleDialog(ctrl, type, title, message) {
    var dlg = YAHOO.webui.bubbleDialog;
    xOffset = getAbsX(ctrl) + 20;
    yOffset = getAbsY(ctrl);

    if (type == 'error'){
        getObj('win_h').style.backgroundColor = '#990000';
    }else{
        getObj('win_h').style.backgroundColor = '#ecede3';
        getObj('win_h').style.color = '#000000';

        // logic for coloring close button
        var w = getObj('win');
        if(w){
            var spans = w.getElementsByTagName('span');
            if(spans){
                for(var i=0; i < spans.length; i++){
                    var e = spans[i];
                    if(e && e.className){
                        if(e.className.indexOf('container-close')>-1){
                            e.style.backgroundColor = '#777777';
                        }
                    }
                }
            }
        }

    }
    dlg.widget.setHeader(title);
    dlg.widget.setBody(message);
    dlg.widget.render();
    dlg.widget.moveTo(xOffset,yOffset);

    var newText = document.createTextNode(title);
    var newElem = document.createElement('SPAN');
    newElem.id = 'tempSpanID';
    newElem.appendChild(newText);
    document.body.appendChild(newElem);
    var definedWidth = document.getElementById('tempSpanID').offsetWidth;
    newElem.style.display = 'none';
    document.body.removeChild(newElem);
    definedWidth = definedWidth + (definedWidth / 2.4);
    if (definedWidth > 220) {
      definedWidth.toString();
      definedWidth = definedWidth + 'px';
      dlg.widget.configWidth('width', [definedWidth], YAHOO.widget.Panel.win);
    }
    else {
      dlg.widget.configWidth('width', ['220px'], YAHOO.widget.Panel.win);
    }

    dlg.widget.show();
}

function bubbleInfo(ctrl, title, message) {
        bubbleDialog(ctrl, 'info', title, message)
}

function bubbleError(ctrl, title, message) {
        bubbleDialog(ctrl, 'error', title, message)
}

// Display very debug info for an object.
// Usage examples:
//        debugObject(object, Event);
//        debugObject(input, HTMLInputElement);
function debugObject(obj, objType) {
        // Build event properties table. This was inspired by:
        // http://www.devguru.com/Technologies/ecmascript/quickref/event.html
        var div = document.createElement('div');
        var table = document.createElement('table');
        div.appendChild(table);
        table.border="1";
        var tr = document.createElement('tr');
        table.appendChild(tr);
        var th = document.createElement('th');
        th.innerHTML = 'Property';
        tr.appendChild(th);
        th = document.createElement('th');
        th.innerHTML = 'Value';
        tr.appendChild(th);
        var td;
        for(property in objType.prototype) {
                // Do not show object constants.
                if(property != property.toUpperCase()) {
                        tr = document.createElement('tr');
                        table.appendChild(tr);
                        td = document.createElement('td');
                        td.innerHTML = property;
                        tr.appendChild(td);
                        td = document.createElement('td');
                        td.innerHTML = obj[property];
                        tr.appendChild(td);
                }
        }
        // Display results in new window.
        var win = window.open('debug');
        win.document.open();
        win.document.write('<h2>' + obj + '</h2>');
        win.document.write(div.innerHTML);
        win.document.close();
}

// Trap the ENTER key for form submission onKeyPress within a text-input field.
// Do not use this for onKeyUp because that breaks multilanguage IME support.
function doTextAction(event, form, action) {
        if (event.keyCode == 13) {
                if(action != '')
                        return doClickAction(form, action);
                else
                        form.submit();
                return false;
        }
}

// Make an input-button work like an input-submit.
//        form - form object
//        action - action name
//        sf - bool option whether to submit form or not (default true)
//
// This example allows different actions, default action on "Enter" press,
// in IE prevents multiple POSTs on submitting
// via submit button or "Enter" press:
//
// <form name="form" id="form" action="...">
//         <input type="hidden" name="action" value="MyDefaultAction" />
//                ...
//         <input type="button" class="button"
//                         onclick="doClickAction(this.form, 'Cancel');"
//                         value="Cancel" />
//         <input type="button" class="button"
//                         onclick="doClickAction(this.form, 'AnotherAction');"
//                         value="Another action" />
//         <input type="submit"
//                         onclick="doClickAction(this.form, 'MyDefaultAction', false);" />
// </form>

// This example allows different actions, default action on "Enter" press
// (except IE), prompts,
// in IE prevents multiple POSTs on submitting
// via submit button or "Enter" press:
// TODO: in IE submit on "Enter" press
//
// <form name="form" id="form" action="..." onsubmit="return false">
//         <input type="hidden" name="action" value="MyDefaultAction" />
//                ...
//         <input type="button" class="button"
//                         onclick="doClickAction(this.form, 'Cancel');"
//                         value="Cancel" />
//         <input type="button" class="button"
//                         onclick="setYesNoConfirm('Another prompt', \
//                                 'doClickAction(f, \'AnotherAction\');');"
//                         value="Another action" />
//         <input type="submit"
//                         onclick="setYesNoConfirm('Default prompt', \
//                                         'doClickAction(f, \'MyDefaultAction\');');" />
// </form>
// <script language="javascript"><!--
//        f = document.forms['form'];
// // -->
// </script>

function enableActionSubmit(checkList, actionList, formObj){
        var midSelected = false;
        var actionSelected = false;
        if (checkList.length){
                for (i=0; i < checkList.length; i++)
                        if (checkList[i].checked)
                                midSelected = true;
                if ((actionList.value) && (actionList.value != '0'))
                        actionSelected = true;
                if ((midSelected) && (actionSelected))
                        doClickAction(formObj,'Message');
        }else{
                if (checkList.checked)
                        midSelected = true;
                if ((actionList.value) && (actionList.value != '0'))
                        actionSelected = true;
                if ((midSelected) && (actionSelected))
                        doClickAction(formObj,'Message');
        }
}

function doClickAction(form, action, sf) {
        if (sf == null) sf = true;
        if (sf){
                if ((form.onsubmit) || (bypassSubmit)){
                        form.elements['action'].value = action;
                        form.submit();
                }
                else {
                        return false;
                }
        }
        else
                return false;
}

// Submit only with a confirmation message.
var _doConfirm_form;
var _doConfirm_action;
function doConfirmClickAction(form, action, title, message, buttonOk) {
        _doConfirm_form = form;
        _doConfirm_action = action;
        setConfirmCancel(title, message, buttonOk,
                "doClickAction(_doConfirm_form, _doConfirm_action)");
}

function doCancelClickAction(form, action, title, message, buttonCancel, buttonOk) {
        _doConfirm_form = form;
        _doConfirm_action = action;
        setConfirm(title, message, buttonCancel, buttonOk, '', "doClickAction(_doConfirm_form, _doConfirm_action)");
}


function goPage(page, param, fm) {
        if (fm != ''){
                fm.elements['pg'].value = page;
                fm.submit();
        }
        else {
                location.href="?pg=" + page + param;
        }
}

function doSorting(column, order, param, fm) {
    if (fm != ''){
        fm.elements['s_col'].value = column;
        if(fm.elements['s_ord']) fm.elements['s_ord'].value = order;
        fm.submit();
    }
    else {
        location.href="?s_col=" + column + "&amp;s_ord=" + order + param;
    }
}

// Debounce functions

  var clicks = 0;
  var bypassSubmit = false;

  function resetClicks(){
        clicks = 0;
  }

  function addClick(){
        setTimeout("resetClicks()",2000);
        if (clicks == 0){
          clicks++;
          return true;
        }
        else
          return false;
  }

  function addClickMute(){
        setTimeout("resetClicks()",2000);
        bypassSubmit = true;
        return false;
  }
  function appendActions(){
        forms = document.forms;
        for (i=0; i < forms.length; i++){
          if (forms[i].onsubmit){
                forms[i].onsubmit = addClickMute;
          }
          else
                forms[i].onsubmit = addClick;
        }
  }

function safeOnLoad(onload_function) {
  var onload_existing = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = function() {
      onload_function();
    };
  } else {
    window.onload = function() {
      onload_existing();
      onload_function();
    };
  }
}

// Enable or disable an object, and set the background color.
function set_obj_enabled(obj, enabled) {
  obj.disabled = !enabled;

  if (!enabled) {
    if (obj.type != 'radio' && obj.type != 'checkbox') {
      if (obj.type != 'button' && obj.type != 'submit') {
        obj.style.color = '#999999';
        obj.style.backgroundColor = '#E0E0E0';
      } else {
        if (obj.className == 'button-secondary') {
          obj.className = 'button-secondary-disabled';
        } else if (obj.type == 'button') {
          obj.className = obj.className.toString() + '-disabled';
        }
      }
    }
  } else if (obj.type == 'button' || obj.type == 'submit') {
    if (obj.className == 'button-secondary-disabled') {
      obj.className = 'button-secondary';
    } else if (obj.type == 'button') {
      obj.className = obj.className.split('-disabled')[0];
    }
  } else {
    obj.style.color = '';
    obj.style.backgroundColor = '';
  }
}

// Set disabled attribute and style for an input element.
function set_enabled(id, enabled, doFocus) {
        var obj = document.getElementById(id);
        if (!obj && document.forms['form'])
                obj = document.forms['form'].elements[id];
        if (obj) {
                if (obj.type == 'radio') {
                        // This fixes a rather annoying javascript bug with radios.
                        // The radio returned by getElementById has no length property.
                        obj = obj.form[obj.id];
                        for (var i=0; i<obj.length; i++)
                                set_obj_enabled(obj[i], enabled);
                }
                else
                        set_obj_enabled(obj, enabled);
                if (enabled && doFocus &&
                   (obj.type == 'text' || obj.type == 'textarea'))
                        obj.focus();
        }
}

// Check a checkbox field by id. Returns true if the checkbox was set.
function set_checkbox(checkboxId) {
        var obj = document.getElementById(checkboxId);
        if (!obj && document.forms['form'])
                obj = document.forms['form'].elements[checkboxId];
        if (obj && !obj.disabled) {
                obj.checked = true;
                return true;
        }
        return false;
}

// Check a checkbox field by id if prerequisite is met.
function set_checkbox_preq(checkboxId, preq) {
        var obj = document.getElementById(preq);
        if (obj && obj.disabled)
                return;
        else {
                obj = document.getElementById(checkboxId);
                if (obj)
                        set_obj_checked(obj);
        }
}

// Check a specific radio field.
function set_radio(obj, index) {
        obj[index].checked = true;
}
// Check a checkbox or radio object.
function set_obj_checked(obj) {
        obj.checked = true;
}

// Enable an input field.
function enable_input(inputId) {
        set_enabled(inputId, true, true);
}

// Disable an input field.
function disable_input(inputId) {
        set_enabled(inputId, false, false);
}

// Enable an input field without setting the focus.
function enable_input_nofocus(inputId) {
        set_enabled(inputId, true, false);
}

// Toggle an input field        enabled/disabled based on checkbox setting.
function toggle_input(inputId, checked) {
        set_enabled(inputId, checked, true);
}

// Toggle an input field without setting the focus.
function toggle_input_nofocus(inputId, checked) {
        set_enabled(inputId, checked, false);
}

// Check all checkboxes for the form.
function check_all(form, checked) {
        var elts = form.elements;
        var len = elts.length;
        for (i = 0; i < len; i++) {
                        e = elts[i];
                        if (e.name=='senders[]')
                                        e.checked = checked;
        }
}

// Sort a select list alphabetically.
function sort_select(sel) {
if (sel.options == null || sel.options.length <= 1)
                return;

        var o = new Array();
        for (var i = 0; i < sel.options.length; i++)
                o[o.length] = new Option(sel.options[i].text,
                                                                 sel.options[i].value,
                                                                 sel.options[i].defaultSelected,
                                                                 sel.options[i].selected);

        // Null-proof sort
        o = o.sort(function(a,b) {
                if ((a.text+"") < (b.text+""))
                        return -1;
                if ((a.text+"") > (b.text+""))
                        return 1;
                return 0;
        });

        for (var i = 0; i < o.length; i++)
                sel.options[i] = new Option(o[i].text, o[i].value,
                                                                                                                                o[i].defaultSelected, o[i].selected);
}

// Takes two select lists, and moves selected items from one to the other.
function select_move(from, to) {
        for (var i = 0; i < from.options.length;) {
                var o = from.options[i];
                if (o.selected) {
                        to[to.length] = new Option(o.text, o.value, false, false);
                        from.options[i] = null;
                }
                else
                        i++;
        }
        sort_select(from);
        sort_select(to);
        return true;
}

// Mark options in a select (multiple) list as selected.
function select_all(sel) {
        if (sel.options == null)
                return true;
        for (i = 0; i < sel.options.length; i++)
                sel.options[i].selected = true;
        return true;
}

function getParentTag(obj, tagName) {
        while (obj.tagName != tagName) {
                obj = obj.parentNode;
        }
        return obj;
}

function getParentID(obj, idName) {
        while (obj.parentNode.id != idName) {
            obj = obj.parentNode;
        }
        return obj;
}
function resetElement(elementId, setting) {
        var obj = getObj(elementId);
        resetElementObj(obj, setting);
}

function resetElementObj(obj, setting) {
    // Recursively resets all form elements inside a span or div element.
    // Setting can be hide, show, disable, enable
    // Used a hack to detect a HTMLSpanElement in IE -
    // name all spans with a prefix of "span_".    Same for table, tbody and tr.
    var n = obj.childNodes.length;
    for(var i=0;i<n;i++) {
        child = obj.childNodes[i];

        if (
                (child.type=='text') || (child.type=='select-one') ||
                (child.type=='button') || (child.type=='textarea') ||
                (child.type=='label') || (child.type=='radio') ||
                (child.type=='checkbox') || (child.type=='file') ||
                (child.type=='password')
            ) {
            switch (setting) {
                case 'reset':
                    if (child.type == 'text' || child.type == 'textarea' ||
                        child.type == 'password') {
                      child.value = '';
                    }
                    else if (child.type == 'checkbox') {
                      child.checked = false;
                    }
                    break;
                case 'hide':
                    hideObj(child);
                    break;
                case 'show':
                    showObj(child);
                    break;
                case 'enable':
                    set_obj_enabled(child,true);
                    break;
                case 'disable':
                    set_obj_enabled(child,false);
                    break;
                case 'clear_err':
                    child.className = '';
                    break;
                }
        }
        else if (child.type=='hidden') {

          switch (setting) {
            case 'disable':
              set_obj_enabled(child,false);
              break;

            case 'enable':
              set_obj_enabled(child,true);
              break;

          }

        }
        else if (setting == 'clear_err' && child.className == 'error') {
                        hideObj(child);
                }
                else if (child.id) {
                        var string = child.id.toString().split("_");
                        if (string[0]=='err' && setting == 'clear_err') {
                                hideObj(child);
                        }
                        else if (string[0]=='td') {
                                hideObj(child);
                                resetElementObj(child, setting);
                        }
                        else if ((string[0]=='tr') || (string[0]=='txt'))
                                hideObj(child);
                        else
                                resetElementObj(child, setting);
                }
                else if (child){
                        if (child.childNodes)
                                resetElementObj(child, setting);
                }
        }
}

function hideObj(obj) {
        if(obj) {
                obj.style.display = 'none';
                obj.style.height='0px';
        }
}

function showObj(obj) {
        if(obj) {
                obj.style.display = '';
                obj.style.height='';
        }
}

function popUp(url, w, h) {
        nw = window.open(url, 'newWin',
                'width=' + w + ',height=' + h + ',menubar=1,resizable=1,scrollbars=1');
        nw.focus();
}


// Make a portion of the page flicker to emphasize that it has changed.
var flicker_yellow = new Array('#eeeeee',
        '#eeeeee','#efefea','#f0f0e6','#f1f1e2',
        '#f2f2de','#f3f3da','#f4f4d6','#f5f5d2',
        '#f6f6ce','#f7f7ca','#f8f8c6','#f9f9c2',
        '#fafabe','#fbfbba','#fcfcb6','#fdfdb2',
        '#fefeae','#ffffaa','#ffffaa');
var flicker_red = new Array('#eeeeee',
        '#eeeeee','#efeaea','#f0e6e6','#f1e2e2',
        '#f2dede','#f3dada','#f4d6d6','#f5d2d2',
        '#f6cece','#f7caca','#f8c6c6','#f9c2c2',
        '#fabebe','#fbbaba','#fcb6b6','#fdb2b2',
        '#feaeae','#ffaaaa','#ffaaaa');
var flicker_colors;
var flicker_end_color;
var flicker_up;
var flicker_loops;
var flicker_id;

function flicker(id, color_choice, end_color) {
        flicker_id = id;
        flicker_end_color = end_color;
        flicker_colors = flicker_yellow;
        if(color_choice == 'red') flicker_colors = flicker_red;
        flicker_loops = 2;
        flicker_up = true;
        flicker_loop(0);
}

function flicker_loop(i) {
        var delay = 40;
        if(flicker_id == '' ) return;
        var flicker_obj = getObj(flicker_id);
        flicker_obj.style.backgroundColor = flicker_colors[i];
        if (flicker_up) {
                if (i++ < flicker_colors.length) {
                        setTimeout("flicker_loop(" + i + ")", delay);
                }
                else {
                        flicker_up = false;
                        flicker_loop(--i);
                }
        }
        else {
                if (i-- > 0) {
                        setTimeout("flicker_loop(" + i + ")", delay);
                }
                else {
                        if (--flicker_loops > 0) {
                                flicker_up = true;
                                flicker_loop(0);
                        }
                        else {
                                flicker_obj.style.backgroundColor = flicker_end_color;
                        }
                }
        }
}

// widget.itable functions
function itable_del(e, id, fieldName, numRows) {
        var tableID = document.getElementById(id);
        var tableRow = itable_get_TRow(e);
        var i = 0;
        for (i = 0; i < tableID.rows.length;++i) {
                if (tableID.rows[i] == tableRow) {
                        break;
                }
        }
        resetElementObj(tableRow, 'reset');
        if (tableID.rows.length > numRows) {
                tableID.deleteRow(i);
        }

        return false;
}

function itable_get_TRow(e) {
        return e.parentNode.parentNode;
}

function itable_addRow(id, group, del) {
        var tableGroup = document.getElementById(group);
        var rowID;
        if (tableGroup.rows.length == 0){
          rowID = 0;
        } else {
          rowID = tableGroup.rows.length;
        }
        //handling special rows
        var row;
        if (rowID.id != id + '-footer')
                newRowPosition = tableGroup.rows.length;
        else
                newRowPosition = tableGroup.rows.length - 1;

        /* tableGroup.insertRow(newRowPosition) crashes IE 6.02 if starting from
        initial conditions:
        <TBODY>  with id='existingRows' is not empty,  <TBODY> with id='newRows'
        is empty
        user has deleted existing row and immediately tries to add a new row.

        Tricky using of function insertAdjacentElement (it is possible only for IE)
        instead of insertRow  fix the problem in IE case.
        For all other browsers function insertRow works correctly.
        (according to bug #17185)  */

        if (typeof(tableGroup.insertAdjacentElement) != 'undefined') {
                row = document.createElement('TR');
                tableGroup.insertAdjacentElement('beforeEnd', row);
        }
        else
                row  = tableGroup.insertRow(newRowPosition);

        row.id = id + '_' + group + '_' + newRowPosition;

        var i;
        var row_idx = itable_next_counter(id);
        for (i in itable_col_defs[id]) {
                var cell = row.insertCell(i)
                cell.setAttribute('class', 'itable-cell');
                cell.setAttribute('className', 'itable-cell');
                var el = document.createElement('input');
                var fld = itable_col_defs[id][i];
                for (j in fld) {
                        if (j == 'id') {
                                var v = id + '['+row_idx+']['+fld[j]+']';
                                el.setAttribute('name', v);
                                el.setAttribute('id', v);
                        } else {
                                el.setAttribute(j, fld[j]);
                        }
                }
                ev = id + '_itable_keypress';
                el.onkeypress = eval(id + '_itable_keypress');
                cell.appendChild(el);
        }
        var cell = row.insertCell(row.childNodes.length);
        cell.setAttribute('align', 'center');
        cell.setAttribute('class', 'itable-delete');
        cell.setAttribute('className', 'itable-delete');
        cell.style.textAlign = "center";
        cell.style.width = "3%";
        var deleteString = del;
        deleteString = deleteString.replace('{v}',v);
        deleteString = deleteString.replace('{id}',id);
        cell.innerHTML = deleteString;
        return false;
}

function itable_next_counter(id) {
        return ++itable_row_counter[id];
}

var itable_col_defs = new Array();
var itable_row_counter = new Array();




function check_row(frm, row, target, targetHead, otherHeads, otherRows) {
  /* this function turns on/off checkboxes in a matrix row,
        for use in pages that use columns of checkboxes with different options,
        but only allow selection of one box per grouping.
  this function supports a variable number of columns, from 1 on up,
        since arguments are passed as comma-delimited strings.
  this function takes care of the row-handling, while the check_cols function
        handles the columns (select all).
  arguments:
          frm [object]: the form the element is found in (usually this.form)
          row [string]: unique identifier of a row of elements (1,2,156,157..)
          target [string]: the unique identifier of the checkbox selected.
                  usually incorporates the row ID (del156, release157)
          targetHead [string]: the name of the header of the column the object is in
          otherHeads [string]: a comma-delimited list of the Header checkboxes,
                  or the checkboxes used for Select All. (delete, releaseAll, etc).
                  these are the header/selectAll checkboxes which will be turned off
                  when the target checkbox is enabled.
          otherRows [string]: a comma-delimited list of the other items in the
                  row of the object selected, usually with unique identifiers
                  (delete168, save130, release27). these are the checkboxes which will
                  be turned off when the target checkbox is enabled.
  design notes:
          passing the otherHeades/otherRows string arguments, rather than
          auto-detecting, allows for greater expandability of this feature.
          since the user controls which boxes are affected, they are allowed to
          interact with only the columns they want - meaning, you could have two
          groups of options, groupA and groupB, each with 3 checkboxes, and have
          groupA's boxes only affect its own, and groupB affect its own, instead
          of automatically having all 6 checkboxes affected.
          so manually passing along strings of affected items is a little bit
          more work than having a "smart" function, but allows for better control.
        */

        var us = frm[target];
        if (otherHeads) var otherHeadsArry = otherHeads.split(",");
        if (otherRows) var otherRowsArry = otherRows.split(",");
        if (otherRows) var themArray = otherRows.split(",");

        //if we're now on, turn off the others in our row
        //then see if all of our column is on; if so, turn on our header
        if (us.checked){
                for (iItem in themArray){
                        getObj(otherRowsArry[iItem] + row).checked = false;
                        getObj(otherHeadsArry[iItem]).checked = false;
                }
        } else {
        //if we're now off, turn off ourself, our header.
                getObj(target).checked = false;
                if (getObj(targetHead))
                        getObj(targetHead).checked = false;
        }
}


function check_cols(frm, target, others) {
  /* this function turns on/off checkboxes in a matrix COLUMN, and allows
  for other columns to have their contents' status changed as a result.
  this function supports a variable number of columns, from 1 on up,
        since arguments are passed as comma-delimited strings.
  requirements:
          header (select all) and child (individual) checkboxes must have similar
          ids. ie, if your array of children is called "delete[]", the header
          row must be "delete" - the header ID must be the name of a child, sans
          the array notation. example:

          <input type="checkbox" name="deleteHeader" id="delete"
          onClick="check_cols(...)">
          ...
          <input type="checkbox" name="delete[] id="del23">

          Note that the *ID* of the header ("Select All") box
                matches the *NAME* of the child element.
  arguments:
          frm [object]: the form the element is found in (usually this.form)
          target [string]: the unique identifier of the column being selected.
                  please make note of the *requirement* above for some of the
                  specifics behind the naming scheme used.
          others [string]: a comma-delimited string of the unique identifiers
                  of the other columns in the matrix.
                  please make note of the *requirement* above for some of the
                  specifics behind the naming scheme used.
        design notes:
          passing the target/others string arguments, rather than
          auto-detecting, allows for greater expandability of this feature.
          since the user controls which columns are affected, they are allowed to
          interact with only the columns they want - meaning, you could have two
          groups of options, groupA and groupB, each with 3 checkboxes, and have
          groupA's boxes only affect its own, and groupB affect its own, instead
          of automatically having all 6 checkboxes affected.
          so manually passing along strings of affected items is a little bit
          more work than having a "smart" function, but allows for better control.
        */

        //turn passed variable into proper strings
        var targetLength = target.length - 2;
        var usName = target.substr(0,targetLength);
        var all_usName = target;

        if (others){
                //set bool and initialize vars
                var them_exists = true;
                var themStr = others;
                var themName = new Array();
                var all_themName = new Array();

                //pull others into array and make new arrays of their contents
                var themArray = themStr.split(",")
                for (iItem in themArray) {
                        themStr = themArray[iItem];
                        othersLength = themStr.length - 2;
                        themName[iItem] = themStr.substr(0,othersLength);
                        all_themName[iItem] = themStr;
                }
        } else {
                var them_exists = false;
        }

        //assign form objects
        var us = frm[usName];
        var all_us = frm[all_usName];
        var them = new Array();
        var all_them = new Array();
        if(them_exists){
                for (iItem in themArray){
                        them[iItem] = frm[themName[iItem]];
                        all_them[iItem] = frm[all_themName[iItem]];
                }
        }

        if(us.checked){
                if(them_exists)
                        for (iItem in themArray){
                                them[iItem].checked = false;
                        }
        } else {
        }

        if(all_us.length) {
                for (i = 0; i < all_us.length; i++) {
                        all_us[i].checked = us.checked;
                        if(us.checked)
                                if (them_exists)
                                        for (iItem in themArray){
                                                all_them[iItem][i].checked = false;
                                        }
                }
        } else {
                all_us.checked = us.checked;
                if(us.checked)
                        if(them_exists)
                                for (iItem in themArray){
                                        all_them[iItem].checked = false;
                                }
                }
        }

/* set Checkbox "Select All" (all_ch - it's a name) unchecked,
  when some item (self_ch) is set to unchecked */

function unCheckAll(self_ch, all_ch) {
    fm = self_ch.form
    if((!self_ch.checked) && fm[all_ch].checked)
        fm.elements[all_ch].checked = false
}

// Toggle the visibility of an element.
function toggleVisibility(id) {
  obj = getObj(id);
  if (obj.style.visibility == "visible") {
    obj.style.visibility = "hidden";
  } else {
    obj.style.visibility = "visible";
  }
}

/* Specific for forms with upload field submit function.
  See bug #23872
  upload_name - the name of fileInput field
  set_value - the value, wich will be submited instead*/
function doClickUploadAction(form, action, upload_name, set_value, sf)
{
  if(document.getElementsByName(upload_name)[0]) {
    if (sf == null) sf = true;
    if (sf) {
      if ((form.onsubmit) || (bypassSubmit)) {
        form.elements['action'].value = action;
        if(navigator.userAgent.indexOf('MSIE 6') != -1 &&
           navigator.platform == 'Win32') {
          try {
            form.submit();
          }
          catch (e) {
            if (e instanceof TypeError && e.number < 1) {
              if (set_value == null) set_value = '';
              var filecontainer = document.getElementById("upload_container");
              filecontainer.innerHTML = '<input type="file" size="40" />' +
              '<input type="hidden" name="' + upload_name + '" value="' +
              set_value + '"/>';
              form.submit();
            } else throw(e)
          }
        } else form.submit();
      } else return false;
    } else return false;
  } else doClickAction(form, action, sf)
}

/* Functions for ResourceChooser widget.*/
function disableSystemGenerated(select){
  var isSG = select.getAttribute('display_system_generated_preview');
  var id = select.id;
  if(isSG == '0' && select.value == ''){
      getObj(id+"_enabled").style.display = 'none';
      getObj(id+"_disabled").style.display = '';
  }else{
      getObj(id+"_enabled").style.display = '';
      getObj(id+"_disabled").style.display = 'none';
  }
}

function enableDisableRC(id, enable){
  var select_ctrl = getObj(id);
  set_obj_enabled(select_ctrl, enable);
  var isSG = select_ctrl.getAttribute('display_system_generated_preview');
  if(isSG=='0' && select_ctrl.value=='') enable = false;
  if(enable){
    getObj(id+"_enabled").style.display = '';
    getObj(id+"_disabled").style.display = 'none';
  }else{
    getObj(id+"_enabled").style.display = 'none';
    getObj(id+"_disabled").style.display = '';
  }
}

function generate_preview(source_id, type, level, default_template,
                          resource_name){
    var url = 'http://mail.fairfield.edu/mail_policies/resource_preview';
  if (default_template){
    url += '?type=' + default_template;
  } else {
    url += '?type=' + type;
  }
  if (resource_name){
    url += '&name=' + resource_name;
  } else {
    var name = getObj(source_id);
    if (name && !name.disabled && name.value != ''){
        url += '&name=' + name.value;
    }
  }

  url += '&level=' + level;
  window.open(url, "", 'width=640, height=480, status=no, toolbar=0,\
          scrollbars=1, menubar=no, statusbar=no, resizable=yes');
}

function escapeHTML(str) {
  return str.replace(/\&lt;/g, '&amp;lt;').replace(/\&gt;/g, '&amp;gt;').replace(/\</g, '&lt;').replace(/\>/g, '&gt;');
}

function escapeStr(str) {
  return str.replace(/'/g, "\\\'");
}

function removeNewlines(str) {
  return str.replace(/\n/g, " ");
}


function applyErrorMsg(obj, errorMsg){
  if (obj) {
    obj.className = 'error';
    if (errorMsg.length > 70){
      var error_arg = removeNewlines(escapeStr(errorMsg));
      errorMsg = errorMsg.substring(0,59) + "...&nbsp;<span class=\"bubble-link-errormsg\" onclick=\"bubbleDialog(this, 'error', 'Error', '"+ error_arg +"'); if (getObj('bubbleParentDiv')) { getObj('bubbleParentDiv').style.zIndex=2000;};\">more</span>"
    }
    var parent = obj.parentNode;
    var divNode = document.createElement("div");
    divNode.setAttribute("id", obj.name + "_error_div");
    var spanNode = document.createElement("span");
    spanNode.setAttribute("id", obj.name + "_error_span");
    divNode.className = 'error'
    divNode.style.paddingLeft = '2px'
    parent.appendChild(divNode);
    divNode.appendChild(spanNode);
    spanNode.innerHTML = errorMsg;
  }
}

function clearErrors(formObj) {
  for (var i = 0; i < formObj.elements.length; i++) {
    if (formObj.elements[i].tagName.toLowerCase() in {"input":1, "select":1}) {
      var obj = formObj.elements[i];
      if (getObj(obj.name + "_error_div")) {
        obj.className = "";
        getObj(obj.name + "_error_div").parentNode.removeChild(getObj(obj.name + "_error_div"));
      }
    }
  }
}


function renameIDsBelowParent(obj, template_string) {
  var child_length = obj.childNodes.length;
  for (var i = 0; i < child_length; i++) {
    child = obj.childNodes[i];
    if (child.attributes) {
      if ( (child.attributes['name'])
      && (child.attributes['name'].value.indexOf(template_string) == 0) ) {
        child.attributes['name'].value =
            child.attributes['name'].value.substr(template_string.length);
      }
      if ( (child.attributes['id'])
      && (child.attributes['id'].value.indexOf(template_string) == 0) ) {
        child.attributes['id'].value =
            child.attributes['id'].value.substr(template_string.length);
      }
      if ( (child.attributes['for'])
      && (child.attributes['for'].value.indexOf(template_string) == 0) ) {
        child.attributes['for'].value =
            child.attributes['for'].value.substr(template_string.length);
      }
    }
    if (child.childNodes.length > 0) {
      renameIDsBelowParent(child, template_string)
    }
  }
}



function extractValuesFromForm(form_obj, array_obj, values_only) {
  if (!array_obj) { // Create local array if necessary.
    var array_obj = new Object;
  }
  for (var i=0; i < form_obj.elements.length; i++) {
    form_element = form_obj.elements[i];
    if ( (form_element.type == 'text') ||
         (form_element.type == 'password') ||
         (form_element.type == 'hidden') ) {
      array_obj[form_element.name] = form_element.value;
    } else if (form_element.type == 'radio') {
      if (form_element.checked) {
        array_obj[form_element.name] = form_element.value;
      }
    } else if (form_element.type == 'checkbox') {
      if (form_element.checked) {
        array_obj[form_element.name] = form_element.value;
      }
    } else if (form_element.type == 'select-one') {
      array_obj[form_element.name] =
        form_element[form_element.selectedIndex].value;
    }
  }
  return array_obj;
}

function applyValuesToForm(value_array, target_form, create_hidden) {
  for (var field_name in value_array) {
    var receiving_field = getFieldByName(target_form, field_name);
    if (receiving_field.length > 0) {
      if (receiving_field.length > 1) { 
        for (var i = 0; i < receiving_field.length; i++) {
          receiving_field_child = receiving_field[i]
          if ( (receiving_field_child.type == 'radio') &&
               (receiving_field_child.value == value_array[field_name]) ){
            receiving_field_child.checked = true;
          }
        }
      } else {
        if (receiving_field[0].type =='checkbox' &&
              receiving_field[0].value == value_array[field_name]) {
          receiving_field[0].checked = true;
        } else if (receiving_field[0].type == 'select-one') {
          for (var select_id = 0; select_id < receiving_field[0].length; select_id++) {
            if (receiving_field[0][select_id].value == value_array[field_name])
              receiving_field[0].selectedIndex = select_id;
          }
        } else {
          receiving_field[0].value = value_array[field_name];
        }
      }
    } else if ((create_hidden) && (field_name.indexOf('{ROW}') == -1)){
      var new_input = document.createElement("input");
      new_input.setAttribute("type", "hidden");
      new_input.setAttribute("name", field_name);
      new_input.setAttribute("id", field_name);
      new_input.setAttribute("value", value_array[field_name]);
      target_form.appendChild(new_input);
    }
  }
}

function getFieldByName(form_obj, field_name) {
  var matches = [];
  for (var i=0; i < form_obj.elements.length; i++) {
    form_element = form_obj.elements[i];
    if (form_element.name == field_name) {
      matches.push(form_element);
    }
  }
  return(matches);
}


function getCookie( check_name ) {
    var a_all_cookies = document.cookie.split( ';' );
    var a_temp_cookie = '';
    var cookie_name = '';
    var cookie_value = '';
    var b_cookie_found = false; // set boolean t/f default f

    for ( i = 0; i < a_all_cookies.length; i++ )
    {
        // now we'll split apart each name=value pair
        a_temp_cookie = a_all_cookies[i].split( '=' );


        // and trim left/right whitespace while we're at it
        cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');

        // if the extracted name matches passed check_name
        if ( cookie_name == check_name )
        {
            b_cookie_found = true;
            // we need to handle case where cookie has no value but exists (no = sign, that is):
            if ( a_temp_cookie.length > 1 )
            {
                cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
            }
            // note that in cases where cookie is initialized but no value, null is returned
            return cookie_value;
            break;
        }
        a_temp_cookie = null;
        cookie_name = '';
    }
    if ( !b_cookie_found )
    {
        return null;
    }
}
