////////////////////////////////////////////////////////////////////
// IBCSUtils class
IBCSUtils.CLASS_NAME = "IBCSUtils";
//IBCSUtils.HOST = "dribop100";
//BCSUtils.HOST = "sbopi100";
IBCSUtils.HOST = "ibop2";
IBCSUtils.MY_APPS_BASE_URL = "http://" + IBCSUtils.HOST + "/ibcsWeb/IBCSBase/";
IBCSUtils.MY_WEBS_URL = "http://" + IBCSUtils.HOST + "/ibcsWeb/";

IBCSUtils.PATH_IMAGES = "http://" + IBCSUtils.HOST + "/ibcsWeb/IBCSBase/images/";

// Constants for allowed date range
IBCSUtils.ALLOW_DATE_RANGE_REQ_BOTH    = 1;  // Both dates need to be set
IBCSUtils.ALLOW_DATE_RANGE_REQ_NEITHER = 2;  // Neither date required
IBCSUtils.ALLOW_DATE_RANGE_REQ_START   = 3;  // Only start date required
IBCSUtils.ALLOW_DATE_RANGE_REQ_END     = 4;  // Only end date required

IBCSUtils.ACTION_ARROW_IMG = IBCSUtils.PATH_IMAGES + "icons/actionArrow.gif";

// Constructor
function IBCSUtils() {

}

/////////////////////////////////////////////////////////////////////////////////////
// Static functions
/////////////////////////////////////////////////////////////////////////////////////

IBCSUtils.dispFilters = function() {
  var d = $('filterAreaBtn');
  var text = d.innerHTML;

  var newText = "";
  var filtersStyle = "";
  var searchResultsAreaClass = "";

  switch(text) {
    case 'Hide':
      filtersStyle = "none";
      searchResultsAreaClass = "searchResultsAreaExp";
      newText = "Show";
      break;
    case 'Show':
      filtersStyle = "block";
      searchResultsAreaClass = "searchResultsAreaReg";
      newText = "Hide";
      break;
  }

  $('filtersArea').style.display = filtersStyle;
  $('submitFiltersArea').style.display = filtersStyle;
  $('chooseFiltersArea').style.display = filtersStyle;
  $('recentQueriesArea').style.display = filtersStyle;

  $setCls('searchResultsArea', searchResultsAreaClass);
  $('filterAreaBtn').innerHTML = newText;

}

// Static metho to create a window
IBCSUtils.creWin = function(cfg) {
  var actions = $addParam('Window Actions', 'a', cfg);
  var body = $addParam('Window Body', 'b', cfg);
  var id = $addParam('', 'id', cfg);
  var title = $addParam('Window Title', 't', cfg);
  var closeWinBtn = $addParam(true, 'x', cfg);

  // Create the div
  var div = document.createElement('div');
  div.className = 'win';
  div.id = id;

  var cell;
  var row;

  // Create the table
  var tbl = document.createElement('table');
  tbl.className = 'win';
  div.appendChild(tbl);

  // Create the window title
  row = tbl.insertRow(0);
  var winTitle = row.insertCell(0);
  winTitle.className = 'infoTblTop';
  winTitle.innerHTML = '<div class="infoTblTitle">' + title + '</div>';

  // Create the window body
  row = tbl.insertRow(1);
  var winBody = row.insertCell(0);
  winBody.className = 'infoTblMiddle';
  winBody.innerHTML = '<div class="infoTblMiddle"><div class="infoTblInner">' + body + '</div></div>';

  // Create the window actions
  row = tbl.insertRow(2);
  var winActions = row.insertCell(0);
  winActions.className = 'infoTblBottom';
  winActions.innerHTML = '<div style="float: center;">' + actions + '</div>';


  return div;
}


// Static method to logout of a tool
IBCSUtils.logoutOfApp = function(cls) {
  var doIt = confirm("Are you sure you want to logout of " + cls.APP_NAME);
  if (doIt) {
    var url = IBCSUtils.MY_WEBS_URL + cls.APP_URL + "?action=Logout";
    window.location.href = url;
  } 
}

// Format a website string
IBCSUtils.formatWebsite = function(site) {
  if (site == "") {
    return "";
  }
  var siteStrip = site;
  if (/^http:\/\//.test(site)) {
    siteStrip = siteStrip.replace("/^http:\/\//", "")
  } else if (/^https:\/\//.test(site)) {
    siteStrip = siteStrip.replace("/^https:\/\//", "")
  } else {
    site = "http://" + site;
  }
  return '<a href="' + site + '" target="_new">' + siteStrip + '</a>';
}

// Static function to popup an alert if the errors or warnings are not empty
IBCSUtils.checkErrorsWarnings = function(errors, warnings) {
  var popupWarning = "";

  if (errors != "") {
    popupWarning += "ERRORS:\n" + errors + "\n";
  }
  if (warnings!= "") {
    popupWarning += "WARNINGS:\n" + warnings;
  }
  if (popupWarning != "") {
    alert(popupWarning);
    return false;
  }
  return true;
}

// Static function to validate the search form
IBCSUtils.validateSearchForm = function() {
  var errors = "";
  var searchVal = $('searchBox').value;
  if (searchVal == "") {
    errors += "Cannot search an empty string!\n";
    IBCSUtils.resetSearchForm();
  }

  return IBCSUtils.checkErrorsWarnings(errors, ""); 
}       

// Static function to clear the search form
IBCSUtils.clearSearchForm = function() {
  $('searchBox').value = '';
}

// Static function to clear the search form
IBCSUtils.resetSearchForm = function() {
  $('searchBox').value = 'Search Google';
}

// Static method to launch the applicatin log
IBCSUtils.launchAppLog = function(logName) {
  var url = IBCSUtils.MY_WEBS_URL + 'AppLog/php/index.php?action=ShowAppLogWebFilters&logFile=' + logName;
  var win = IBCSUtils.openWin(url,'appLog',1000,800,'center','front');
}

// Static method to open a new window
IBCSUtils.openWin = function(mypage, myname, w, h, pos, infocus) {
  if (pos == "center") {
    myleft = (screen.width) ? (screen.width-w) / 2:100;
    mytop = (screen.height) ? (screen.height-h) / 2:100;
  } else if ((pos !='center' && pos != "random") || pos == null) {
    myleft = 0; mytop = 20
  }

  switch(ActionObj.OPEN_WIN_STYLE) {
    case ActionObj.OPEN_WIN_STYLE_BROWSER_DEFAULT:
      win = window.open(mypage, myname);
      break;

    case ActionObj.OPEN_WIN_STYLE_POPUP:
      var settings = "width=" + w + ", height=" + h + ",top=" + mytop + ",left=" + myleft + ", scrollbars=yes, location=no, directories=no, status=no, menubar=no, toolbar=no, resizable=yes";
      win = window.open(mypage, myname, settings);
      break;

    default:
      alert("Unknown open window style: " + ActionObj.OPEN_WIN_STYLE);
      return;
  }

  win.focus();
  return win;
}

// Static method to set the Submit button active
IBCSUtils.submitBtnActive = function() {
  var submitBtn = $('submitBtn');
  $setCls('submitBtn', 'btnSpin');

  $('searchResultsArea').innerHTML = '<b><font color=red>Searching ...</font></b>';
  $('resultCountArea').innerHTML = '';
  $('resultTm').innerHTML = '';
}

// Static method to set the Submit button active
IBCSUtils.submitBtnInactive = function() {
  var submitBtn = $('submitBtn');
  $setCls('submitBtn', 'btn');
  submitBtn.value = "Submit";

  $('resultCountArea').innerHTML = '';
  $('resultTm').innerHTML = '';
}

// Static method to set the main content
IBCSUtils.setMainContent = function(html) {
  $('searchResultsArea').innerHTML = html;
}

// Calls submitSearch when button is pushed
IBCSUtils.refreshAllObjs = function(cls) {
  if (cls.validateGet) {
    var noErrors = IBCSUtils.checkErrorsWarnings(cls.validateGet(), "");
    if (!noErrors) {
      return false;
    }
  }

  if (cls.onRefresh) {
    cls.onRefresh();
  }

  ActionObj.startFromZero(cls);
  return false;
}

// Static method to reset the main form
IBCSUtils.resetMainForm = function(cls) {
  $('searchResultsArea').innerHTML = '';
  $('itemSelectCount').innerHTML = '&nbsp;';
  $('menuBarActions').innerHTML = '&nbsp;';
  $('resultCountArea').innerHTML = '&nbsp;';
  $('resultTm').innerHTML = '&nbsp;';

  ActionObj.checkedTotal = 0;
  ActionObj.clearClass(cls);
  FormFilter.clearAll();
}

// Static method to refresh xml objects via ajax
IBCSUtils.submitSearch = function(cls) {
  ActionObj.cancelEdit();

  ActionObj.curClass = cls;
  var url = ActionObj.getAjaxURL({'cls':cls,'action':ActionObj.ACTION_GET_OBJS});
  url += "&dbSortBy="+ActionObj.sortBy+"&dbSortDir="+ActionObj.sortDir+"&dbStartFrom="+ActionObj.DB_QUERY_START;

  for (var c in ActionObj.htLoadedClasses.hash) {
    eval("var c2 = " + c);
    ActionObj.clearClass(c2);
  }
  ActionObj.htLoadedClasses.clear();
  ActionObj.htLoadedClasses = new Hashtable();

  IBCSUtils.submitBtnActive();
  ActionObj.setCheckTotal(0);

  // Create and send xml call for non-shorts
  vars = new Array();
  vars.abortFunction = AJAXConn.abortedAjaxQuery;
  vars.desc = cls.CLASS_NAME;
  vars.functionToCall = ActionObj.cacheAjaxObjects;
  vars.objType = cls;
  vars.timeout = 60000;
  vars.url = url;

  AJAXConn.getXML(vars);
}

// Static method to update the display when something has changed 
IBCSUtils.refreshView = function() {
  if (typeof IBCSUtils.currentClass.getObjs == 'function') {
    IBCSUtils.currentClass.getObjs();
  } else {
    alert("use standard retrieve method");
  } 
}

// Static method to validate login
IBCSUtils.validateLoginForm = function() {
  var password = $('csrPassword').value;
  var username = $('csrUsername').value;

  var errorText = "";

  if (username == "") {
    errorText += "Please enter a username!\n";
  }
  if (password == "") {
    errorText += "Please enter a password!\n";
  }

  return IBCSUtils.checkErrorsWarnings(errorText, "");
}

// Calculate a ratio
IBCSUtils.calcRatio = function(n, d, md) {
  n = n.replace(/,/g, "");
  d = d.replace(/,/g, "");
  n = Math.abs(parseFloat(n));
  d = Math.abs(parseFloat(d));

  if (md) {
    d *= 1000000;
  }

  var r = 100*(n/d);
  r = IBCSUtils.roundNum(r, 2);
  return r;
}

// Date to int
IBCSUtils.dateToInt = function(d) {
  var d = d.replace(/\//g, "").replace(/\s*/g, "").replace(/-/g, "");
  d = parseInt(d);
  return d;
}

// Round a number to a certain number of decimals
IBCSUtils.roundNum = function(n, d) {
  var r = Math.round(n*Math.pow(10,d))/Math.pow(10,d);
  return r;
}

// Function to make sure the start date is before the end date
IBCSUtils.validateDateRange = function(sd, ed, rangeType) {
  sd = IBCSUtils.dateToInt(sd);
  ed = IBCSUtils.dateToInt(ed);

  var errorText = "";

  switch(rangeType) {
    case IBCSUtils.ALLOW_DATE_RANGE_REQ_BOTH:
      if (isNaN(sd)) {
        errorText += "Start date is not a valid date!\n";
      }
      if (isNaN(ed)) {
        errorText += "End date is not a valid date!\n";
      }
      break;
    case IBCSUtils.ALLOW_DATE_RANGE_REQ_NEITHER:
      break;
    case IBCSUtils.ALLOW_DATE_RANGE_REQ_START:
      if (isNaN(sd)) {
        errorText += "Start date is not a valid date!\n";
      }
      break;
    case IBCSUtils.ALLOW_DATE_RANGE_REQ_END:
      if (isNaN(ed)) {
        errorText += "End date is not a valid date!\n";
      }
      break;
  }

  // Make sure end date is greater then start date
  if (!isNaN(sd) && !isNaN(ed) && ed<sd) {
    errorText += "End date must be after start date!\n";
  }

  return errorText;
}

// Display selection end
///////////////////////////////////////////////////////////

// Small implementation of document.getElementById(id)
function $(id) {
  if (typeof(id) != "string") {
    return id;
  }
  if (document.getElementById) {
    return document.getElementById(id);
  } else if (document.all) {
    return document.all(id);
  } else {
    alert("Unsupported browser for $ method");
  }
}

IBCSUtils.getWinPos = function() {
  var l = '';
  var t = '';
  var w = '';
  var h = '';
  if (document.all) {      // IE
    l = window.screenLeft;
    t = window.screenTop;
    w = window.innerWidth;
    h = window.innerHeight;
  } else {                 // Mozilla
    l = window.screenX;
    t = window.screenY;
    w = document.body.offsetWidth;
    h = document.body.offsetHeight;
  }
  return {'l':l,'t':t,'w':w,'h':h};
}

function $findPos(divId) {
  var obj = $(divId);
  var curleft = curtop = curwidth = curheight = 0;
//  alert("divId: " + divId + ", obj: " + obj);

  if (obj == null) {
    alert("Cannot find divId: " + divId + ", obj: " + obj);
    return {};
  }

  if (obj.offsetParent) {
    curleft = obj.offsetLeft-obj.scrollLeft;
    curtop = obj.offsetTop-obj.scrollTop;
    curwidth = obj.offsetWidth;
    curheight = obj.offsetHeight;
    while (obj = obj.offsetParent) {
      curleft += obj.offsetLeft-obj.scrollLeft;
      curtop += obj.offsetTop-obj.scrollTop;
    }
  }
  return {x:curleft,y:curtop,w:curwidth,h:curheight};
}

// Small implementation of xml.getAttribute(attr)
function $attr(xml, attr) {
  try {
    return xml.getAttribute(attr);
  } catch (e) {
    return '';
  }
}

// Get elem 0
function $elem0(xml, elem) {
  if (xml == null) {
    return '';
  }
  return xml.getElementsByTagName(elem)[0];
}

// Get a node value
function $nodeVal(xml, elem) {
  if (xml == null) {
    return '';
  }
  return xml.getElementsByTagName(elem)[0].childNodes[0].nodeValue;
}

///////////////////////////////////////////////////////////
// Table functions - start

// Add an attribute only if it is not an empty string
function $addMapDiv(vars) {
  var id = $addParam('', 'id', vars);
  var style = $addParam('height:200px; border: 1px solid black; padding: 2px; background-color:white;', 'style', vars);
  var t = '<tr><td colspan=2><div id="' + id + '" style="' + style + '"></div></td></tr>';
  return t;
}

// Table Maker functions - end
///////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
// Form functions - start

String.prototype.trim = function() {
  return this.replace(/^\s*/, "").replace(/\s*$/, "");
}

// setAction
function $sA(a) {
  $('action').value = a;
}

// Set a hidden form value
function $sHFV(id, v) {
  $(id).value = v;
}

function $vldTxt(id, name) {
  try {
    var txt = $(id).value;
    if (txt == "") {
      return name + " cannot be empty!\n";
    }
  } catch(e) {
    alert("problem on i: " + id + ", name: " + name + ", e: " + e);
  }
  return "";
}

var checkFlag = true;
function $checkAll(field) {

  checkFlag = !checkFlag;
  var cbs = document.getElementsByName(field);

  var numCb = cbs.length;

  for (i=0; i<numCb; i++) {
    cbs[i].checked = !checkFlag;
  }
}

function $getRBVal(id) {
  var grp = document.getElementsByName(id);
  var len = grp.length;
  for (var i=0; i<len; i++) {
    var item = grp[i];
    if (item.checked) {
      return item.value; 
    }
  }
  return null;
}

IBCSUtils.chgRadioHL = function(id) {
  var grp = document.getElementsByName(id);
  var len = grp.length;
  for (var i=0; i<len; i++) {
    var item = grp[i];
    var cls = 'btnGrey';
    if (item.checked) {
      cls = 'btn';
    }
    var spanID = item.id + "Div";
    $setCls(spanID, cls);
  }
}


IBCSUtils.mkRdBtn = function(cfg) {
  var checked = cfg.chk;
  var labelText = cfg.lt;
  var onchange = cfg.onc;
  var name = cfg.n;
  var radioID = cfg.n + cfg.v;
  var radioVal = cfg.v;

  var divID = cfg.n + cfg.v + "Div";
  var cls = "btnGrey";
  if (checked != '') {
    cls = "btn";
  }

  var onchangeStr = 'IBCSUtils.chgRadioHL(\'' + name + '\');';
  if (onchange != null == onchange != '') {
    onchangeStr += onchange;
  }

  var t = '<div id="' + divID + '" class="' + cls + '">' +
          '<input type="radio" name="' + name + '" id="' + radioID + '"' + checked + ' value="' + radioVal + '" onchange="' + onchangeStr + '">' + 
          '<label for="' + radioID + '">' + labelText + '</label></div>';
  return t; 
}

IBCSUtils.mkRdBtnGrp = function(cfg) {
  var arrBtns = cfg.b;
  var name = cfg.n;
  var onchange = cfg.onc;

  var t = "";

  var len = arrBtns.length;
  for (var i=0; i<len; i++) {
    var btnInfo = arrBtns[i];

    var checked = btnInfo.chk;
    var labelText = btnInfo.lt;
    var radioVal = btnInfo.v;

    var radioID = name + radioVal;
    var divID = name + radioVal + "Div";

    var cls = "btnGrey";
    if (checked != '') {
      cls = "btn";
    }

    var onchangeStr = 'IBCSUtils.chgRadioHL(\'' + name + '\');';
    if (onchange != null && onchange != '') {
      onchangeStr += onchange;
    }

    t += '<div id="' + divID + '" class="' + cls + '">' +
         '<input type="radio" name="' + name + '" id="' + radioID + '"' + checked + ' value="' + radioVal + '" onchange="' + onchangeStr + '">' +
         '<label for="' + radioID + '">' + labelText + '</label></div>';

  }

  return t;
}

function $addChkFlt(id, fn) {
  var filt = "";
  var vals = "";
  var chkBxGrp = document.getElementsByName(id);
  var len = chkBxGrp.length;
  for (var i=0; i<len; i++) {
    var chkBx = chkBxGrp[i];
    if (chkBx.checked) {
      vals += chkBx.value + ",";
    }
  }
  if (vals != "") {
    vals = vals.substr(0,vals.length-1);
    return "&" + fn + "=" + vals;
  }
  return "";
}

function $addOptFlt(id, fn) {
  var filt = "";
  var val = $(id).value;
  if (val != -1) {
    filt = "&" + fn + "=" + val;
  }
  return filt;
}

// Add a text filter
function $addTxtFlt(id, fn) {
  var filt = "";
  var txt = $(id).value;
  if (txt != "") {
    filt = "&" + fn + "=" + txt;
  }
  return filt;
}

// Sets the form's text value to default
function setFormTextValue(id, type, text, status_text) {
  var obj = document.getElementById(id);
  var bgColor = "#ffffff";
 
  if (type == "yes") {
    window.status=status_text;
    if (obj.value == text) {
      obj.value = "";
    }
  } else if (type == "default") {
    bgColor="#fffccc";
    obj.value=text;
  } else {
    window.status=window.defaultStatus;
    if (obj.value == "") {
      bgColor="#fffccc";
      obj.value = text;
    }
  }
  obj.style.backgroundColor=bgColor;
}

// Form functions - end
///////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
// Style methods - start

// Close window
function $cW() {
  window.close();
}

// Hide element
function $hdElm(id) {
  try {
    $(id).style.display = 'none';
  } catch(e) { $logErr('$hdElm', id, e) }
}

// Show element
function $shElm(id) {
  try {
    $(id).style.display = 'block';
  } catch(e) { $logErr('$shElm', id, e) }
}

// Inner HTML
function $elmInHtml(id, t) {
  try {
    $(id).innerHTML = t;
  } catch(e) { $logErr('$elmInHtml', id, e) }
}

// Set background color
function $setBgCol(id, c) {
  try {
    $(id).style.backgroundColor = c;
  } catch (e) {};
}

// Get class
function $getCls(id) {
  try {
    return $(id).className;
  } catch (e) { }
}

// Set class
function $setCls(id, cls) {
  try {
    $(id).className = cls;
  } catch(e) { /* $logErr('$setCls', id, e) */ }
}

// Log an error
function $logErr(m, t, e) {
  alert("Error in method: " + m + "\n" + t + "\n" + e);
}

// Highlight a radio button group item
function $hlgtRBGrp(f, grpName) {
  var form = document[f];
  var grp = form[grpName];
  var len = grp.length;
  for (var i=0; i<len; i++) {
    var rb = grp[i];
    var id2 = rb.id+"label";
    var cls = null;
    if (rb.checked) {
      cls = 'ckbxHL';
    }
    $setCls(id2, cls);
  }
}

// Highlight a checkbox
function $hlgtCB(id) {
  var e = $(id);
  var id2 = id+"label";
  var cls = null;
  if (e.checked) {
    cls = 'hlghtChk'; 
  }
  $setCls(id2, cls);
}

// Create a form begin row
function $mkFrmBgnRow(config) {
  var id = config.id;
  var text = '<tr><td colspan=2><form id="' + id + '" name="' + id + '"></td></tr>';
  return text;
}

// Create a table row for a button
function $mkBtn(config) {
  var onClk = "";
  if (config.clk) {
    onClk = ' onclick="ActionMenu.closeNew();' + config.clk + '"';
  }
 
  var text = '<input type="button" class="btn" value="' + config.val + '"' + onClk + '> ';
  return text;
}

// Create a table row for a button
function $mkWideRow(t, cs) {
  var text = '<tr><td colspan="' + cs + '">' + t + '</td></tr>';
  return text;
}

// Create a table row for a button
function $mkAOBtn(cfg, ao) {
  var vars = "{'actionObjID':'" + ao.id + "'}";
  var text = '<div class="btn" onclick="' + cfg.f + '(' + vars + ')">' + cfg.n + '</div>';
  return text;
}

// Create a table row
function $mkTblRow(data1, data2) {
  if (data2 == undefined) {
    data2 = "&nbsp;";
  }
  var text = "<tr><td width=1%><b>" + data1 + "</td><td>" + data2 + "</td></tr>";
  return text;
}

// Create a table header
function $mkTblRowHd(cfg, ao) {
  var colSpan = $addParam('2', 'cs', cfg)
  var title = $addParam('Row Header', 'n', cfg)
  var btnTxt = "";
  if (cfg.btns != undefined) {
    var btns = cfg.btns;
    for (var b in btns) {
      var bi = btns[b];
      btnTxt += $mkAOBtn(bi, ao);
    }
    btnTxt = $mkWideRow(btnTxt, 2);
  }

  var text = '<tr class=colhead><th colspan="'+colSpan+'">' + title + '</th></tr>' + btnTxt;
  return text;
}

// Create a checkbox
function $mkCB(cfg) {
  var id = $addParam('', 'id', cfg)
  var text = $addParam('DefaultText', 'text', cfg);
  var value = $addParam('', 'value', cfg);
  var checked = "";
  var cls = "";
  if (cfg.defaultChk != undefined && cfg.defaultChk === true) {
    checked = " checked";
//    cls = ' class="hlghtChk"';
  } else if (cfg.chk != undefined && (cfg.chk == "Y" || cfg.chk == "yes")) {
    checked = " checked";
//    cls = ' class="hlghtChk"';
  }
  var id2 = id + "label";
  var disabled = "";
  if (cfg.dis != undefined && cfg.dis != "") {
    disabled = " disabled";
  }

  var fldTxt = '<input type="checkbox" id="' + id + '" name="' + id + '" value="' + value + '"' + checked + disabled + ' onChange="$hlgtCB(\'' + id + '\')"><label for="' + id  + '" id="' + id2 + '"' + cls + '>' + text + '</label>';
  return fldTxt;
}

// Create a group of checkboxes
function $mkCBGrp(cfg) {
  var text = "";
  var ht = cfg.ht;
  for (var k in ht.hash) {
    var obj = ht.get(k);
    text += $mkCB({'id':cfg.idRoot+obj.id,'name':cfg.name,'text':obj.text,'value':obj.value,'chk':obj.chk,'dis':cfg.dis});
  }
  return text;
}

// Create a radio button
function $mkRB(cfg) {
  var id = $addParam('', 'id', cfg)
  var form = $addParam('', 'form', cfg);
  var name = $addParam('', 'name', cfg);
  var text = $addParam('DefaultText', 'text', cfg);
  var value = $addParam('', 'value', cfg);
  var checked = "";
  var cls = "";
  if (cfg.chk != undefined && (cfg.chk == value)) {
    checked = " checked";
    cls = ' class="hlghtChk"';
  }
  var id2 = id + "label";
  var disabled = "";
  if (cfg.dis != undefined && cfg.dis != "") {
    disabled = " disabled";
  }
  var fldTxt = '<input type="radio" id="' + id + '" name="' + name + '" value="' + value + '"' + checked + disabled + ' onChange="$hlgtRBGrp(\'' + form + '\',\'' + name + '\')"><label for="' + id  + '" id="' + id2 + '"' + cls + '>' + text + '</label>';
//  alert(fldTxt);
  return fldTxt;
}

// Create a select option
function $mkSel(cfg) {
  var ht = cfg.ht;

  var cls = $addParam('editBox', 'cls', cfg);
  var dis = $addParam('', 'dis', cfg)
  var id = cfg.id;
  var name = cfg.name; 
  var sel = cfg.sel;

  if (dis != '') {
    dis = 'disabled';
  }

  var text = '<select id="' + id + '" name="' + name + '" class="' + cls + '" ' + dis + '>';
  for (var k in ht.hash) {
    var obj = ht.get(k);
    if (obj==null) {
      continue;
    }
    var id = obj.getID();
    var selected = "";
    if (sel == id) {
      selected = "selected ";
    }
    text += '<option ' + selected + 'value="' + id + '">' + obj.toString();
  }
  text += "</select>";

  return text;
}

// Create a text area
function $mkTA(cfg) {
  var cls = $addParam('editBox', 'cls', cfg);
  var id = $addParam('', 'id', cfg)
  var name = $addParam('', 'name', cfg);  
  var style = $addParam('height:100px;', 'style', cfg);
  var value = $addParam('', 'value', cfg);
  if (style != '') {
    style = ' style="' + style + '"';
  }
  var text = '<textarea id="' + id + '" name="' + name + '" class="' + cls + '"' + style + '>' + value + '</textarea>';
  return text;
}

// Create a text field
function $mkTF(cfg) {
  var cls = $addParam('editBox', 'cls', cfg);
  var clk = $addParam('', 'clk', cfg);
  var dis = $addParam('', 'dis', cfg);
  var id = $addParam('', 'id', cfg);
  var name = $addParam('', 'name', cfg);  
  var ro = $addParam('', 'ro', cfg);
  var style = $addParam('', 'style', cfg);
  var value = $addParam('', 'value', cfg);
  if (style != '') {
    style = ' style="' + style + '"';
  }
  if (clk != '') {
    clk = ' onclick="' + clk + '"';
  }     
  if (dis != '') {
    dis = ' disabled ';
  }
  if (ro != '') {
    ro = ' readonly ';
  }     
  var text = '<input type="text" ' + ro + dis + clk + ' id="' + id + '" name="' + name + '" class="' + cls + '" value="' + value + '"' + style + '>';
  return text;
}

// Replace a div content with a text field
// Used in editing tables
function $mkTxtFld(elm, fieldId, defaultVal) {
  var text = "<input type=\"text\" id=\"" + fieldId + "\" class=\"editBox\" value=\"" + defaultVal + "\">";
  elm.innerHTML = text;
}

function $addParam(def, param, config) {
  var retVal = def;

  if (config != null && config[param] != undefined && config[param] != "") {
    retVal = config[param];
  }
  return retVal;
}

function $elmVal(id) {
  return $(id).value; 
}

function $zeroPad(n) {
  if (n<=9) {
    n = "0"+n;
  }
  return n;
}

/////////////////////////////////////////////////////////////////////////////////////
// Date functions
/////////////////////////////////////////////////////////////////////////////////////

/*
 * Date Format 1.2.2
 * (c) 2007-2008 Steven Levithan <stevenlevithan.com>
 * MIT license
 * Includes enhancements by Scott Trenda <scott.trenda.net> and Kris Kowal <cixar.com/~kris.kowal/>
 *
 * Accepts a date, a mask, or a date and a mask.
 * Returns a formatted version of the given date.
 * The date defaults to the current date/time.
 * The mask defaults to dateFormat.masks.default.
 */
var dateFormat = function () {
  var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
  timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
  timezoneClip = /[^-+\dA-Z]/g,
  pad = function (val, len) {
    	      val = String(val);
       	      len = len || 2;
     	      while (val.length < len) {
                val = "0" + val;
              }
       	      return val;
  	    };

	// Regexes and supporting functions are cached through closure
	return function (date, mask, utc) {
		var dF = dateFormat;

		// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
		if (arguments.length == 1 && (typeof date == "string" || date instanceof String) && !/\d/.test(date)) {
			mask = date;
			date = undefined;
		}

		// Passing date through Date applies Date.parse, if necessary
		date = date ? new Date(date) : new Date();
		if (isNaN(date)) {
		  throw new SyntaxError("invalid date");
                }

		mask = String(dF.masks[mask] || mask || dF.masks["default"]);

		// Allow setting the utc argument via the mask
		if (mask.slice(0, 4) == "UTC:") {
			mask = mask.slice(4);
			utc = true;
		}

		var	_ = utc ? "getUTC" : "get",
			d = date[_ + "Date"](),
			D = date[_ + "Day"](),
			m = date[_ + "Month"](),
			y = date[_ + "FullYear"](),
			H = date[_ + "Hours"](),
			M = date[_ + "Minutes"](),
			s = date[_ + "Seconds"](),
			L = date[_ + "Milliseconds"](),
			o = utc ? 0 : date.getTimezoneOffset(),
			flags = {
				d:    d,
				dd:   pad(d),
				ddd:  dF.i18n.dayNames[D],
				dddd: dF.i18n.dayNames[D + 7],
				m:    m + 1,
				mm:   pad(m + 1),
				mmm:  dF.i18n.monthNames[m],
				mmmm: dF.i18n.monthNames[m + 12],
				yy:   String(y).slice(2),
				yyyy: y,
				h:    H % 12 || 12,
				hh:   pad(H % 12 || 12),
				H:    H,
				HH:   pad(H),
				M:    M,
				MM:   pad(M),
				s:    s,
				ss:   pad(s),
				l:    pad(L, 3),
				L:    pad(L > 99 ? Math.round(L / 10) : L),
				t:    H < 12 ? "a"  : "p",
				tt:   H < 12 ? "am" : "pm",
				T:    H < 12 ? "A"  : "P",
				TT:   H < 12 ? "AM" : "PM",
				Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
				o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
				S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
			};

		return mask.replace(token, function ($0) {
			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		});
	};
}();

// Some common format strings
dateFormat.masks = {
	"default":      "ddd mmm dd yyyy HH:MM:ss",
	shortDate:      "m/d/yy",
	mediumDate:     "mmm d, yyyy",
	longDate:       "mmmm d, yyyy",
	fullDate:       "dddd, mmmm d, yyyy",
	shortTime:      "h:MM TT",
	mediumTime:     "h:MM:ss TT",
	longTime:       "h:MM:ss TT Z",
	isoDate:        "yyyy-mm-dd",
	isoTime:        "HH:MM:ss",
	isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n = {
	dayNames: [
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
	],
	monthNames: [
		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
	]
};

// For convenience...
Date.prototype.format = function (mask, utc) {
	return dateFormat(this, mask, utc);
};

