
// variant of string.replace() that works globally
// bwm 2006/7/6: the g flag on RegExp seems not to work in FF.
function sreplace(inStr, inRe, inReplacement) {
    cn = inStr;
    var ncn = inStr.replace(inRe, inReplacement);
    while (ncn != cn) {
        cn = ncn;
        ncn = cn.replace(inRe, inReplacement);
    }
    return ncn;
}

// Convert inElemID to a DOM Element
// allow functions below to take either a DOM Element or an id attribute name
function to_element(inElemID) {
    var elem = null;
    elem = is_object(inElemID)?inElemID:document.getElementById(inElemID);

    if (!is_object(elem)) {
        if (window.error) {
            window.error('invalid element id: '+inElemID);
        }
        return false;
    }
    return elem;
} // to_element

// find and remove any occurrences of inOldClass and inNewClass
// in inElem.className.  Append inNewClass to inElem.className
function replace_class(inElem, inOldClass, inNewClass) {
    var elem = null;
    elem = to_element(inElem);

    if (!is_object(elem)) {
        if (window.error) {
            window.error('replace_class('+inOldClass + ', ' + inNewClass+'): invalid element' + elem);
        }
        return false;
    }
    if (window.debug) {
        window.debug('replace_class('+inOldClass + ', ' + inNewClass+')');
    }
    var cn = elem.className;
    var re_hyphen = new RegExp('\\-', 'g');
    var oldClass = sreplace(inOldClass, re_hyphen, '\\-');
    var re_old = new RegExp('(^|\\s)' + oldClass + '(\\s|$)', 'ig');

    var newClass = sreplace(inNewClass, re_hyphen, '\\-');
    var re_new = new RegExp('(^|\\s)' + newClass + '(\\s|$)', 'ig');

    cn = sreplace(cn, re_old, ' ');
    cn = sreplace(cn, re_new, ' ');

    cn = ''+ cn + ' ' + inNewClass;
    if (window.info) {
        window.info('  replacing "' + elem.className + '" with "' + cn +'".');
    }
    elem.className = cn;
} // replace_class


/*
   Written by Jonathan Snook, http://www.snook.ca/jonathan
   Add-ons by Robert Nyman, http://www.robertnyman.com
 */
// find all elements like <strTagName class="... strClassName ...">
function getElementsByClassName(inElm, strTagName, strClassName){
    var oElm = to_element(inElm);
    var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(var i=0; i<arrElements.length; i++){
        oElement = arrElements[i];
        if(oRegExp.test(oElement.className)){
            arrReturnElements.push(oElement);
        }
    }
    return (arrReturnElements)
} // getElementsByClassName

// Master reset button.
// do form.reset() on every form on this page.
function revert_forms() {
    var form_nodes = window.document.getElementsByTagName('form');
    var i = 0;
    var len = form_nodes.length;
    for(i = 0; i < len; i++) {
        if (form_nodes[i]) {
            form_nodes[i].reset();
        }
    }
} // revert_forms

// Find the first form element with substring inAliasName somewhere
// under the inRecord element.  Search is case insensitive.
function get_form_field(inRecord, inAliasName) {
    var record = to_element(inRecord);

    var candidates = getElementsByTagNames('input,select,textarea', record);
    var ic = candidates.length;
    var cn = '';
    var alias = inAliasName.toLowerCase();
    var found = null;
    for(var i = 0; i < ic; i++) {
        cn = candidates[i].name.toLowerCase();
        if (cn.indexOf(alias) > -1) {
            found = candidates[i];
            break;
        }
    }
    if (!found) {
        warn('cannot find ' + inAliasName + ' under ' + inRecord);
    }
    return found;
} // get_form_field


// Find elements by multiple tag names, return them in
// document order (when possible).
// taken from
// http://www.quirksmode.org/dom/getElementsByTagNames.html
function getElementsByTagNames(list,obj) {
 if (!obj) var obj = document;
 var tagNames = list.split(',');
 var resultArray = new Array();
 for (var i=0;i<tagNames.length;i++) {
  var tags = obj.getElementsByTagName(tagNames[i]);
  for (var j=0;j<tags.length;j++) {
   resultArray.push(tags[j]);
  }
 }
 var testNode = resultArray[0];
 if (!testNode) return [];
 if (testNode.sourceIndex) {
  resultArray.sort(function (a,b) {
    return a.sourceIndex - b.sourceIndex;
  });
 }
 else if (testNode.compareDocumentPosition) {
  resultArray.sort(function (a,b) {
    return 3 - (a.compareDocumentPosition(b) & 6);
  });
 }
 return resultArray;
} // getElementsByTagNames

// return ancestor element with name inTag that
// contains inElem
function getAncestorByTag(inElem, inTag) {
    var current = to_element(inElem);
    var tag = inTag.toLowerCase();
    while (current && (current.tagName.toLowerCase() != tag)) {
        if (current.parentNode) {
            current = current.parentNode;
        } else {
            current = null;
        }
    }
    return current;
} // getAncestorByTag

// return ancestor element of inElem with CSS class inClass
function getAncestorByClass(inElem, inClass) {
    var current = to_element(inElem);
    var find_class = inClass.replace(/\-/g, "\\-");
    var re = new RegExp("(^|\\s)" + find_class + "(\\s|$)");
    while (current && (!re.test(current.className)) ) {
        if (current.parentNode) {
            current = current.parentNode;
        } else {
            current = null;
        }
    }
    return current;
} // getAncestorByClass

// return form element with name attribute matching inRe
function getElementMatchingName(inElem, inRe) {
    var current = inElem?to_element(inElem):document;

    // find elements under current that are allowed to have name attr
    var list = 'input,select,textarea';
    var tagNames = list.split(',');
    var resultArray = new Array();
    for (var i=0;i<tagNames.length;i++) {
        var tags = current.getElementsByTagName(tagNames[i]);
        if (inRe instanceof RegExp) {
            // regex based search
            for (var j=0;j<tags.length;j++) {
                if (tags[j].name && inRe.test(tags[j].name)) {
                    window.debug('getElementMatchingName found regexp '+tags[j].name);
                    return tags[j];
                }
            }
        } else {
            // string based search
            for (var j=0;j<tags.length;j++) {
                if (tags[j].name && (tags[j].name.indexOf(inRe) > -1)) {
                    window.debug('getElementMatchingName found substring '+tags[j].name);
                    return tags[j];
                }
            }
        }
    }
    return false;
} // getElementMatchingName
