// POSSE Internet API Functions

function PosseAppendChangesXML(aXML) {
  document.possedocumentchangeform.changesxml.value =
      document.possedocumentchangeform.changesxml.value + aXML;
}

function PosseCanDoLookupAJAX(){
  /* We support Lookup AJAX for all browsers which have an AJAX object
     except the following: Netscape 6 and Safari 2 */
  if (!posseCanDoAJAX) return false;
  if (navigator.userAgent.indexOf("Safari") > -1
        && navigator.userAgent.indexOf("Version/") == -1) return false;
  if (navigator.userAgent.indexOf("Netscape6") > -1) return false;
  return true;
}

function PosseChangeColumn(aObjectID, aColumnName, aValue) {
  PosseAppendChangesXML('<object id="' + aObjectID + '"><column name="' +
      aColumnName + '"><![CDATA[' + aValue + ']]></column></object>');
}

function PosseGetDebugKey() {
  key = prompt("Enter the key given to you by the help desk:", "");
  if (key > "") {
    PosseSetDebugKey(key);
    alert("Debug key has been set; execute the action you wish to debug", "");
  } else if (key != null){
    alert("Blank debug keys are not set.  Try again");
  }
}

function PosseGetElement(aId) {
  var el = PosseGetElementOptional(aId);
  if (!el) {
    alert("This browser does not allow you to find element " + aId + ".");
  }
  return el;
}

function PosseGetElementOptional(aId) {
  var i;
  if (document.getElementById) return document.getElementById(aId);
  var el = PosseGetElementCore(document.links, aId);
  if (el) return el;
  el = PosseGetElementCore(document.images, aId);
  if (el) return el;
  for (i = 0; i < document.forms.length; i++) {
    var f = document.forms[i];
    if ((f.id || f.name) == aId) return f;
    el = PosseGetElementCore(f.elements, aId);
    if (el) return el;
  }
  if (document.all) {
    el = PosseGetElementCore(document.all, aId);
  }
  if (el) return el;
  try {
    el = eval("document." + aId);
    if (el) return el;
  } catch(err) {
    // do nothing
  }
  for (i = 0; i < document.forms.length; i++) {
    var f = document.forms[i];
    try {
      el = eval("f." + aId);
      if (el) return el;
    } catch(err) {
      // do nothing
    }
  }
  return null;
}

function PosseGetXmlHttpRequest() {
  /* Create a new XMLHttpRequest object to talk to the Web server
     there are two ActiveX's in IE, Mozilla uses XMLHttpRequest */
  var xmlHttp = false;
  /*@cc_on @*/
  /*@if (@_jscript_version >= 5)
  try {
    xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e2) {
      xmlHttp = false;
    }
  }
  @end @*/

  if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
    xmlHttp = new XMLHttpRequest();
  }
  return xmlHttp;
}

// posseCanDoAJAX - does the browser support AJAX
// posseCanDoLookupAJAX - does POSSE support using AJAX for lookups
// posseDisableLookupAJAX - config parm, don't use AJAX for lookups

var posseCanDoAJAX = (PosseGetXmlHttpRequest() || false);
var posseCanDoLookupAJAX = PosseCanDoLookupAJAX();
// Note posseDisableLookupAJAX may or may not have been set earlier
// by site code.  Need to declare (the reason for the var) in case it
// has not been set (redeclaration seems to be ignored).
var posseDisableLookupAJAX = (posseDisableLookupAJAX == true);

// Blank page to use when opening the POSSE Pop-up.
var posseBlankPage;

function PosseNavigate(aHRef, aTarget) {
  PosseSubmitLink(aHRef, null, null, null, aTarget);
}

function PossePopup(aAnchor, aURL, aWidth, aHeight, aTarget) {
  var lu = new PossePw();
  lu.xoffset = 0 - (aWidth / 3);
  lu.yoffset = -20;
  lu.width = aWidth;
  lu.height = aHeight;
  if (aURL) lu.href = aURL;
  lu.openPopup(aAnchor, aTarget);
}

function PosseSetChangesXML(aXML) {
  document.possedocumentchangeform.changesxml.value = aXML;
}

function PosseSetDebugKey(aKey) {
  document.cookie = "PosseDebugKey=" + escape(aKey);
}

function PosseSubmit(aHRef, aTarget) {
  PosseSubmitLink(aHRef, 2, null, null, aTarget);
}

function PosseSubmitLink(aHRef, aFunctionDefID, aPaneID, aSortWidget,
    aTarget) {
  if (!PosseValidateNumericEditMasks()) return;

  var tForm = document.possedocumentchangeform;

  if (aHRef > "") {
    tForm.action = aHRef;
  } else {
    tForm.action = window.location.href;
  }

  if (aFunctionDefID == null) {
    aFunctionDefID = 3;
  }
  tForm.functiondef.value = aFunctionDefID;

  if (aPaneID != null) {
    tForm.paneid.value = aPaneID;
  }

  if (aSortWidget > "") {
    var tValue = tForm.sortcolumns.value;
    if (tValue == "") {
      tForm.sortcolumns.value = aSortWidget;
    } else {
      tForm.sortcolumns.value = tValue + "," + aSortWidget;
    }
  }

  if (aTarget > "") {
    tForm.target = aTarget;
  }

  PosseOnRoundTrip();
  PosseOnSubmit();
  tForm.submit();
  tForm.target = "_self";
  tForm.functiondef.value = 3;
}

function PosseToggleDebugKey() {
  var cookies = document.cookie.split(";");
  var debugKey = "";
  for (i=0;i<cookies.length;i++) {
    var ck = cookies[i].split("=");
    if (LTrim(ck[0]) == "PosseDebugKey") {
      debugKey = ck[1];
      break;
    }
  }
  if (debugKey > "") {
    if (confirm('Turn off debug key "' + debugKey + '"?')){
      PosseSetDebugKey("");
    }
  } else {
    PosseGetDebugKey();
  }
}

// POSSE Internet Support Functions
// Note: For original unmodified toolbox version of Calendar Popups
// see www.mattkruse.com

// Posse Document close routine.  Due to an IE bug, calling document.close()
// will cause an infinite loop if IE is asynchronously loading other files
// (e.g. due to a <script src="xxx"> tag).  The problem is intermittent but
// very serious.  IE does not require you to say document.close(), so we only
// want to do it for non-IE browsers.
//
// Detecting IE is problematic, because many browsers set their User Agent to
// be IE for various reasons.  So, we do two checks, one for the browser
// appName, and one for the document readyState property.  "Real" IE will have
// both.
function PosseDocumentClose(doc) {
  if(!window.navigator
      || window.navigator.appName != "Microsoft Internet Explorer"
      || !doc.readyState) {
    doc.close();
  }
  return;
}

// Posse Popup Window setup
var posseDoesPopup = true;
try {
  window.PossePwObj = null;
  window.PossePwRef = null;
  window.PossePwXon = null;
  window.PossePwBeingConstructed = false;
} catch(e) {
  posseDoesPopup = false;
}

// Posse Popup Window global functions
function PossePwRefresh() {
  if (!window.PossePwRef || window.PossePwRef == null
      || window.PossePwRef.closed || window.PossePwObj.content == null) return;
  var doc = window.PossePwRef.document;
  doc.open();
  doc.write(window.PossePwObj.content);
  PosseDocumentClose(doc);
}

function PossePwPostRefresh(){
  if (!window.PossePwRef || window.PossePwRef == null ||
      window.PossePwRef.closed)
    return;
  else if (window.PossePwRef.document && window.PossePwRef.document.body)
    window.setTimeout("PossePwRefresh();", 50);
  else
    window.setTimeout("PossePwPostRefresh();", 50);
}

function PossePwClose(aUnload) {
  if (!posseDoesPopup) return;
  if (!window.PossePwRef || window.PossePwRef == null || window.PossePwRef.closed) {
    window.PossePwRef = null;
    window.PossePwObj = null;
    return true;
  }
  if (!aUnload && window.PossePwObj.dirty) {
    window.PossePwRef.focus();
    if (!window.PossePwRef.confirm(
        'Outstanding changes will be lost. Continue?')) return false;
  }
  window.PossePwRef.close();
  window.PossePwRef = null;
  window.PossePwObj = null;
  return true;
}

function PossePwFocus() {
  if (!window.PossePwRef || window.PossePwRef == null
      || window.PossePwRef.closed) return true;
  window.PossePwRef.focus();
  return false;
}

// Posse Popup Window Constructor
function PossePw() {
  if (!posseDoesPopup) {
    alert("This browser does not support popup windows.");
    return;
  }
  if (!window.listenerAttached) {
    window.listenerAttached = true;
    if (document.layers) {
      document.captureEvents(Event.MOUSEUP);
    }
    window.PossePwXon = document.onmouseup;
    if (window.PossePwXon != null) {
      document.onmouseup = new Function(
          "window.PossePwXon();window.PossePwFocus();");
    } else {
      document.onmouseup = window.PossePwFocus;
    }
  }
  this.xoffset=0;
  this.yoffset=0;
  this.width=100;
  this.height=100;
  this.content = null;
  this.dirty = false;
  if(posseBlankPage){
      this.href = posseBlankPage;
  } else {
      this.href = "posseblankpage.html";
  }
  this.scrollbars = "yes";
  this.resizable = "yes";
  this.status = "no";
  this.features = "toolbar=no, location=no, menubar=no, titlebar=no";
  this.getPosition = PossePwPosition;
  this.openPopup = PossePwOpen;
}

function PossePwOffsetLeft(aEl) {
  if (aEl.offsetParent) return aEl.offsetLeft +
      PossePwOffsetLeft(aEl.offsetParent);
  if (isNaN(window.screenX)) return aEl.offsetLeft + window.screenLeft -
      document.body.scrollLeft;
  return aEl.offsetLeft + window.screenX +
      (window.outerWidth - window.innerWidth) - window.scrollX;
}

function PossePwOffsetTop(aEl) {
  if (aEl.offsetParent) {
    return aEl.offsetTop + PossePwOffsetTop(aEl.offsetParent);
  }
  if (isNaN(window.screenY)) {
    return aEl.offsetTop + window.screenTop - document.body.scrollTop;
  }
  return aEl.offsetTop + window.screenY +
      (window.outerHeight - window.innerHeight) - window.scrollY;
}

// (method of PossePw)
function PossePwPosition(aEl) {
  if (isNaN(aEl.offsetLeft)) {
    this.x = 200;
    this.y = 200;
  } else {
    this.x = PossePwOffsetLeft(aEl);
    this.y = PossePwOffsetTop(aEl);
  }
}

 // (method of PossePw)
function PossePwOpen(aAnchor, aTarget) {
  var vWindowName = aTarget || "PossePopup";
  if (!window.PossePwBeingConstructed) {
    window.PossePwBeingConstructed = true;
    if (window.PossePwFocus()) {
      window.PossePwObj = this;
      this.getPosition(aAnchor);
      this.x += this.xoffset;
      if (this.x<0) {
        this.x=0;
      }
      this.y += this.yoffset;
      if (this.y<0) {
        this.y=0;
      }
      if (screen && screen.availHeight) {
        if ((this.y + this.height) > screen.availHeight) {
          this.y = screen.availHeight - this.height;
          if (this.y<0) {
            this.y=0;
          }
        }
      }
      if (screen && screen.availWidth) {
        if ((this.x + this.width) > screen.availWidth) {
          this.x = screen.availWidth - this.width - 10;
          if (this.x<0) {
            this.x=0;
          }
        }
      }
      window.PossePwRef = window.open(this.href,vWindowName,this.features +
              ",scrollbars = " + this.scrollbars + ",resizable=" +
              this.resizable + ",status=" + this.status + ",width=" +
              this.width + ",height=" + this.height + ",screenX=" + this.x +
              ",left=" + this.x + ",screenY=" + this.y + ",top=" + this.y +
              "");
      // Handle race condition in some browsers (I.E. and Safari)
      if (window.PossePwObj && window.PossePwObj.content){
          PossePwPostRefresh();
      } else {
        window.PossePwRefresh();
      }
      window.setTimeout("window.PossePwFocus()", 10);
    }
    window.PossePwBeingConstructed = false;
  }
}

var vDoingLookup = false;

function PosseExtractJavaScript(aText){
  if (!aText) return null;
  var startTag = "<!--POSSEONLYJSSTART-->";
  var startPos = aText.indexOf(startTag);
  if (startPos >= 0) {
    var endPos = aText.indexOf("<!--POSSEONLYJSEND-->");
    return aText.substring(startPos + startTag.length + 1, endPos - 1);
  }
  return null;
}

function PosseLookup(aAnchor, aLookupURL, aWidth, aHeight) {
  if (vDoingLookup) return;
  var doAJAX = (!posseDisableLookupAJAX) && posseCanDoLookupAJAX;
  try {
    vDoingLookup = true;
    if (doAJAX) {
      aLookupURL += "&PosseUsingAJAX=1";
      var xmlHttp = PosseGetXmlHttpRequest();
      var vPost = "datachanges=" +
          escape(this.document.possedocumentchangeform.datachanges.value);
      xmlHttp.open("POST", aLookupURL, false);
      xmlHttp.setRequestHeader("Content-Type",
          "application/x-www-form-urlencoded");
      xmlHttp.send(vPost);
      if (xmlHttp.status == 200) {
        var retValue = xmlHttp.responseText;
        var script = PosseExtractJavaScript(retValue);
        if (script) {
          var escaped = escape('var vPosseWindow = this;\n' + script);
          var scriptString = "eval(unescape('" + escaped + "'))";
          window.setTimeout(scriptString + ';vDoingLookup = false', 10);
          return;
        }
      } else {
        this.document.write("<h3>Lookup Failed</h3>");
        this.document.write("When processing the function call:<br>");
        this.document.write("URL=" + aLookupURL + "<br>");
        this.document.write("Received the following error from the server:<br>");
        this.document.write(xmlHttp.responseText);
        PosseDocumentClose(this.document);
        return;
      }
    }
    var lu = new PossePw();
    lu.xoffset = 0 - (aWidth / 3);
    lu.yoffset = -20;
    lu.width = aWidth;
    lu.height = aHeight;
    if (doAJAX) {
      lu.content = retValue;
    } else {
      lu.href = aLookupURL;
    }
    lu.openPopup(aAnchor);
    vDoingLookup = false;
  }
  catch(err) {
    vDoingLookup = false;
    throw err;
  }
}

function PosseGetIFrameDoc(aIFrame){
  // DOM 2
  if (aIFrame.contentDocument) return aIFrame.contentDocument;
  // IE 5.5 and up
  if(aIFrame.contentWindow) return aIFrame.contentWindow.document;
  // Safari 2
  for (i=0; i< window.frames.length; i++){
      if (window.frames[i].name == "posseiframe") return window.frames[i].document;
  }
  // IE 5.0
  if(document.frames && document.frames["posseiframe"])
    return document.frames["posseiframe"].document;
  return null;
}

function PosseLookupReturn(aFromObjectHandle, aFromRelationshipHandle,
        aEndPointId, aToObjectId, aPaneId, aMappedItemInstanceId,
        aRoundTripOnChange, aLookupReturnUrl) {
  var vIFrame = PosseGetElementOptional("posseiframe");
  var doAJAX = (!posseDisableLookupAJAX) && posseCanDoLookupAJAX;
  if(aRoundTripOnChange || !doAJAX && !vIFrame) {
    PosseRelChanged(aFromObjectHandle, aEndPointId, aToObjectId);
    PosseNavDelayed();
  } else {
    var vUrl = aLookupReturnUrl + "?PosseFromObjectHandle=" +
          aFromObjectHandle +
          "&PosseFromRelationshipHandle=" + aFromRelationshipHandle +
          "&PosseEndPointId=" + aEndPointId +
          "&PosseToObjectId=" + aToObjectId + "&PossePaneId=" + aPaneId +
          "&PosseMappedItemInstanceId=" + aMappedItemInstanceId +
          "&PosseCanDoLookupAJAX=" + doAJAX;
    if (doAJAX) {
      var xmlHttp = PosseGetXmlHttpRequest();
      var vPost = "datachanges=" +
          escape(this.document.possedocumentchangeform.datachanges.value);
      xmlHttp.open("POST", vUrl, false);
      xmlHttp.setRequestHeader("Content-Type",
          "application/x-www-form-urlencoded");
      xmlHttp.send(vPost);
      if (xmlHttp.status == 200) {
        var jsCommands = PosseExtractJavaScript(xmlHttp.responseText);
        var vPosseWindow = this;
        eval(jsCommands);
      } else {
        this.document.write(xmlHttp.responseText);
        PosseDocumentClose(this.document);
      }
    } else {
      var vDoc = PosseGetIFrameDoc(vIFrame);
      if (!vDoc){
        // Don't know how to get vDoc so force a round trip instead
        PosseRelChanged(aFromObjectHandle, aEndPointId, aToObjectId);
        PosseNavDelayed();
        return;
      }
      var vHTML = vDoc.createElement('html');
      var vBODY = vDoc.createElement('body');
      var vForm = vDoc.createElement('form');
      vForm.setAttribute('name', 'posseiframeform');
      vForm.setAttribute('id', 'posseiframeform');
      vForm.setAttribute('method', 'post');
      vForm.setAttribute('action', vUrl);
      var vInput = vDoc.createElement('input');
      vInput.setAttribute('name', 'datachanges');
      vInput.setAttribute('id', 'datachanges');
      vInput.setAttribute('type', 'Text');
      vInput.setAttribute('value',
          this.document.possedocumentchangeform.datachanges.value);
      vForm.appendChild(vInput);
      vBODY.appendChild(vForm);
      vHTML.appendChild(vBODY);
      try {
        if (vDoc.firstChild)
          vDoc.firstChild.appendChild(vHTML);
        else
          vDoc.documentElement.appendChild(vHTML);
        // Beware: submit terminates the PosseLookupReturn function in
        // IE 6 if it is inside html script written to the document,
        // so we call it from here.
        vForm.submit();
      } catch (e) {alert(e.message); throw e; }
    }
  }
}

function PosseUpload(aEl, aUploadURL, aObjectDefId, aTitle, aWidth, aHeight) {
  var vHRef;
  vHRef = aUploadURL;
  if(vHRef.indexOf("?") >= 0) {
    vHRef += '&';
  } else {
    vHRef += '?';
  }
  vHRef += "Title=" + escape(aTitle) + "&PosseUniqueId=" +
          aEl.id + "&PosseObjectDefId=" + aObjectDefId;
  if (aWidth == null) {aWidth = 500;}
  if (aHeight == null) {aHeight = 200;}
  var ul = new PossePw();
  ul.xoffset = 0 - (aWidth / 3);
  ul.yoffset = -20;
  ul.width = aWidth;
  ul.height = aHeight;
  ul.scrollbars = "no";
  ul.resizable = "yes";
  ul.status = "yes";
  ul.href = vHRef;
  ul.openPopup(aEl);
}

function PosseNote(aAnchor, aNoteURL, aObjectId, aTitle, aWidth, aHeight) {
  var vHRef;
  vHRef = aNoteURL + "?Title=" + escape(aTitle) + "&PosseObjectId=" +
      aObjectId;
  if (aWidth == null) {aWidth = 300;}
  if (aHeight == null) {aHeight = 200;}
  var ul = new PossePw();
  ul.xoffset = 0 - (aWidth / 3);
  ul.yoffset = -20;
  ul.width = aWidth;
  ul.height = aHeight;
  ul.scrollbars = "yes";
  ul.resizable = "yes";
  ul.status = "no";
  ul.href = vHRef;
  ul.openPopup(aAnchor);
}

function PosseAlert(aMsg, aEl) {
  var vEl = "document." + aEl.form.name + "." + aEl.name;
  alert(aMsg);
  eval(vEl + ".focus()");
  window.setTimeout(vEl + ".select()", 10);
}

function LTrim(str) {
  var i;
  i = 0;
  while (str.substr(i,1) == " ") {
    i++;
  }
  if (i > 0) {
    str = str.substr(i);
  }
  return str;
}

function RTrim(str) {
  var i;
  i = str.length - 1;
  while (str.substr(i,1) == " " && i > -1) {
    i--;
  }
  str = str.substr(0, i + 1);
  return str;
}

function Trim(str) {
  return LTrim(RTrim(str));
}

function RepeatChr(aChr, aNum){
 var i, retVal = "";
 for(i=0; i < aNum; i++) retVal = retVal + aChr;
 return retVal;
}

function PosseAddDataChanges(aChange) {
  if (document.possedocumentchangeform.datachanges.value == "") {
    document.possedocumentchangeform.datachanges.value = aChange;
  } else {
    document.possedocumentchangeform.datachanges.value += ("," + aChange);
  }
}

function PosseDelete(aHRef, aObjectID) {
  PosseAddDataChanges("('D','" + aObjectID + "')");
  PosseSubmitLink(aHRef, 3,
      document.possedocumentchangeform.currentpaneid.value);
}

function PosseFindOption(aId, aObjectId) {
  var vReturn = -1;
  var vLength = aId.options.length;
  var vValues = "";

  for (var vIndex = 0; vIndex < vLength; vIndex ++) {
    vValues = aId.options[vIndex].value.split("\t");
    if (aObjectId == vValues[0] ||
        (aObjectId == "" && vValues[0] == " ") ) {
      vReturn = vIndex;
    }
  }
  if (vReturn == -1) vReturn = vLength - 1;
  return vReturn;
}

function PosseProcessRoundTripClicked(aHRef, aPaneId, aWidgetName,
    aMappedItemInstanceId, aRowObjectHandle, aRelObjectHandle, aTarget) {
  PosseAddDataChanges("('B'," + aPaneId + ",'" + aWidgetName + "'," +
      aMappedItemInstanceId + ",'" + aRowObjectHandle + "','" +
      aRelObjectHandle + "')");
  PosseSubmitLink(aHRef, 6,
      document.possedocumentchangeform.currentpaneid.value, null, aTarget);
}

function PosseValidateDate(aEl, aObjectId, aColumnDefId, aFormat) {
  if (aEl.value == "") {
    PosseDataChanged(aObjectId, aColumnDefId, "", 0);
    return true;
  }
  var rDate = PosseReadDate(aEl.value, aFormat);
  if (rDate ==  null) {
    PosseAlert("Invalid date. Try using '" + aFormat + "' format.", aEl);
    return false;
  }
  PosseSetDate(aEl, aObjectId, aColumnDefId, aFormat, rDate.getFullYear(),
      rDate.getMonth()+1, rDate.getDate());
  return true;
}

function PosseReadDate(aDateVal, aFormat) {
  var d = 0, m = 0, y = 0, i = 0, l;
  var i = 0, l;
  var prevGood = false;
  var newString = "";
  var badChars = "., -/\\";
  l = aDateVal.length;
  var str;
  while (i < l) {
    str = aDateVal.substr(i,1);
    if (badChars.indexOf(str) > -1) {
      if (prevGood) {
        newString += "/";
        prevGood = false;
      }
    } else {
      prevGood = true;
      newString += str;
    }
    i++;
  }
  while (newString.substr(newString.length - 1) == "/") {
    newString = newString.substr(0, newString.length - 1);
  }
  aDateVal = newString;

  var parts = aDateVal.split("/");
  for (part in parts) {
    if (m == 0) {
      var pos = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC".indexOf(
              parts[part].substr(0,3).toUpperCase());
      if (pos >= 0) {
        m = pos / 3 + 1;
      }
    }
  }

  var i = 0;
  var pts = new Array();
  for (part in parts) {
    var p = parts[part];
    if (! isNaN(Number(p))) {
      if (p == 0) {
        // User explicitly set a year of "00" with no century.
        y = 2000;
      } else if (p > 31) {
        y = p;
      } else {
        pts[i] = p;
        i ++;
      }
    }
  }
  aFormat = aFormat.toUpperCase();

  var p=0, f=0, c = "";
  if (pts.length == 1 || m > 0 && y > 0) {
    d = pts[p];
  } else {
    while (f < aFormat.length) {
      c = aFormat.charAt(f);
      if (p >= pts.length) {
        break;
      }
      if (c == "Y" && y == 0) {
        y = pts[p]; p++;
      } else if (c == "M" && m == 0) {
        m = pts[p]; p++;
      } else if (c == "D" && d == 0) {
        d = pts[p]; p++;
      }
      f++;
    }
  }

  var today = new Date();
  if (y == 0) {
    y = today.getFullYear();
  } else if (y < 1000) {
    y = 2000 + (y * 1);
  } else if (y > 3999) {
    return null;
  }
  if (m == 0) {
    m = today.getMonth() + 1;
  }

  var rDate = new Date(y, m - 1, d);
  if (rDate.getFullYear() != y || rDate.getMonth() != m - 1 ||
          rDate.getDate() != d) {
    rDate = null;
  }
  return rDate;
}

function PosseSetDate(aEl, aObjectId, aColumnDefId, aFormat, aYear, aMonth,
    aDay) {
  var yyyy, yy, y, m, mm, mmm, mmmm, d, dd;
  yyyy = aYear + "";
  yy = yyyy.substr(2,2);
  y =  yyyy.substr(3,1);
  m = aMonth + "";
  mm = "0" + m;
  mm = mm.substr(mm.length - 2);
  var mths = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep",
      "Oct","Nov","Dec");
  var mthx = new Array("January","February","March","April","May","June",
      "July","August","September","October","November","December");
  mmm = mths[m-1];
  mmmm = mthx[m-1];
  d = aDay + "";
  dd = "0" + d;
  dd = dd.substr(dd.length - 2);

  PosseDataChanged(aObjectId, aColumnDefId, "" + yyyy + "-" + mm + "-" + dd +
      " 00:00:00", 0);

  var dic = new Object();
  dic["YYYY"] = yyyy;
  dic["YY"] = yy;
  dic["Y"] = y;
  dic["MMMM"] = mmmm;
  dic["MMM"] = mmm;
  dic["MM"] = mm;
  dic["M"] = m;
  dic["DD"] = dd;
  dic["D"] = d;

  aFormat = aFormat.toUpperCase();

  var token, f = 0, c = "", val = "";
  while (f < aFormat.length) {
    c = aFormat.charAt(f);
    token = "";
    while ((aFormat.charAt(f) == c) && (f < aFormat.length)) {
      token += aFormat.charAt(f);
      f++;
    }
    if (dic[token] != null) {val = val + dic[token];}
    else {val = val + token;}
  }
  aEl.value = val;
  return true;
}

// Create Posse Calendar
function PosseCalendar(aAnchor, aEl, aObjectId, aColumnDefId, aFormat,
    aRoundTrip) {
  var cal = new PosseCal();
  cal.objectId = aObjectId;
  cal.columnDefId = aColumnDefId;
  cal.format = aFormat;

  var d = PosseReadDate(aEl.value, aFormat);
  if (d != null) {
    cal.startyear = d.getFullYear();
    cal.startmonth = d.getMonth()+1;
    cal.startdate = d.getDate();
  }
  cal.openCalendar(aAnchor, aEl, aRoundTrip);
}

// Refresh Posse Calendar
function PosseCalendarRefresh(aRoundTrip) {
  var c = window.PossePwObj;
  if (arguments.length > 1) {
    c.content = c.getCalendar(aRoundTrip, arguments[1],arguments[2]);
  } else {
    c.content = c.getCalendar(aRoundTrip);
  }
  PossePwRefresh();
}

// Return value from Posse Calendar
function PosseCalendarReturn(aYear, aMonth, aDate, aRoundTrip) {
  PosseSetDate(window.PossePwObj.returnField, window.PossePwObj.objectId,
      window.PossePwObj.columnDefId, window.PossePwObj.format, aYear, aMonth,
      aDate);
  if (aRoundTrip) {
    PosseNavigate();
  } else {
    PosseRefreshJavaScriptWidgets();
  }
}

// Posse Calendar Constructor
function PosseCal() {
  var pc = new PossePw();
  var sd = new Date();
  pc.width = 135;
  pc.height = 135;
  pc.xoffset = 0;
  pc.yoffset = 0;
  pc.scrollbars = "no";
  pc.resizable = "no";
  pc.startyear = sd.getFullYear();
  pc.startmonth = sd.getMonth()+1;
  pc.startdate = sd.getDate();
  pc.months = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep",
      "Oct","Nov","Dec");
  pc.days = new Array("S","M","T","W","T","F","S");
  pc.wkstartday = 0;
  pc.returnField = null;
  pc.openCalendar = PosseCalOpen;
  pc.getCalendar = PosseCalHTML;
  return pc;
}

// (method of PosseCal)
function PosseCalOpen(aAnchor, aEl, aRoundTrip) {
  this.returnField = aEl;
  this.content = this.getCalendar(aRoundTrip);
  this.openPopup(aAnchor, "PosseCalendarPopup");
}

// (method of PosseCal)
function PosseCalHTML(aRoundTrip) {
  if (arguments.length > 1) {
    var month = arguments[1];
  } else {
    var month = this.startmonth;
  }

  if (arguments.length > 2) {
    var year = arguments[2];
  } else {
    var year = this.startyear;
  }

  var daysinmonth= new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
  if (((year%4 == 0) && (year%100 != 0)) || (year%400 == 0)) {
    daysinmonth[2] = 29;
  }

  var current_month = new Date(year, month - 1, 1);
  var display_year = year;
  var display_month = month;
  var display_date = 1;
  var weekday= current_month.getDay();
  var offset = 0;

  if (weekday >= this.wkstartday) {
    offset = weekday - this.wkstartday;
  } else {
    offset = 7 - this.wkstartday+weekday;
  }

  if (offset > 0) {
    display_month--;
    if (display_month < 1) {
      display_month = 12;
      display_year--;
    }
    display_date = daysinmonth[display_month] - offset + 1;
  }

  var next_month = month + 1;
  var next_month_year = year;
  if (next_month > 12) {
    next_month = 1;
    next_month_year++;
  }

  var last_month = month - 1;
  var last_month_year = year;

  if (last_month < 1) {
    last_month = 12;
    last_month_year--;
  }

  var date_class;
  var result =
      '<html><head><title>Calendar&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' +
      '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' +
      '&nbsp;&nbsp;&nbsp;</title>\n' +
      "<style>\n" +
      "body         {background-color: seashell;}\n" +
      "a               {text-decoration: none; color: blue;}\n" +
      ".pcheader {font-family: sans-serif; font-size: 8pt; " +
      "background-color: silver; font-weight: bold;}\n" +
      ".pcline      {border-color: gray; border-top-width: 1px; " +
      "border-bottom-width: 0px; border-left-width: 0px; " +
      "border-right-width: 0px; border-style: solid;}\n" +
      ".pcbody    {font-family: sans-serif; font-size: 8pt;}\n" +
      "th.pcbody {font-weight: normal;}\n" +
      "a.pcthismonth {color: black;}\n" +
      "a.pcothermonth{color: silver;}\n" +
      "a.pcstartdate {color: red;}\n" +
      "a.pctodaylink {text-decoration: underline;}\n" +
      "</style>\n</head>\n" +
      '<body leftmargin=0 topmargin=0 rightmargin=0 bottommargin=0 ' +
      'marginwidth=0 marginheight=0>\n' +
      '<table border=0 cellspacing=0 cellpadding=0 width="100%"><tr>\n' +
      '<td class="pcheader" align=center width="100%">\n' +
      '<a class="pcheader" href="javascript: ' +
      'window.opener.PosseCalendarRefresh(' + aRoundTrip + ',' + last_month +
      ',' + last_month_year + ');">&lt;&lt;</A>&nbsp;&nbsp;' +
      this.months[month-1] + '&nbsp;&nbsp;<A CLASS="pcheader" ' +
      'HREF="javascript:window.opener.PosseCalendarRefresh(' + aRoundTrip +
      ',' + next_month + ',' + next_month_year + ');">&gt;&gt;</a>\n' +
      '&nbsp;&nbsp;&nbsp;' +
      '<a class="pcheader" href="javascript:' +
      'window.opener.PosseCalendarRefresh(' + aRoundTrip + ',' + month + ',' +
      (year-1) + ');">&lt;&lt;</A>&nbsp;&nbsp;' + year +
      '&nbsp;&nbsp;<A CLASS="pcheader" HREF="javascript:' +
      'window.opener.PosseCalendarRefresh(' + aRoundTrip + ',' + month + ',' +
      (year+1) + ');">&gt;&gt;</a></td>' +
      '</tr></table>\n' +
      "<center>\n" +
      '<table border=0 cellspacing=0 cellpadding=0 width=120><tr>\n' +
      ' <th class="pcbody" align=right width="14%">' +
      this.days[(this.wkstartday)%7] + '</td>\n' +
      ' <th class="pcbody" align=right width="14%">' +
      this.days[(this.wkstartday+1)%7] + '</td>\n' +
      ' <th class="pcbody" align=right width="14%">' +
      this.days[(this.wkstartday+2)%7] + '</td>\n' +
      ' <th class="pcbody" align=right width="14%">' +
      this.days[(this.wkstartday+3)%7]+'</td>\n' +
      ' <th class="pcbody" align=right width="14%">' +
      this.days[(this.wkstartday+4)%7]+'</td>\n' +
      ' <th class="pcbody" align=right width="14%">' +
      this.days[(this.wkstartday+5)%7]+'</td>\n' +
      ' <th class="pcbody" align=right width="14%">' +
      this.days[(this.wkstartday+6)%7]+'</td>\n' +
      '</tr><tr><td colspan=7 vlign=top><div class="pcline">' +
      '<img width=120 height=1></div></td></tr>\n';
  for (var row=1; row<=6; row++) {
    result += '<tr>\n';
    for (var col=1; col<=7; col++) {
      if ((display_month == this.startmonth) &&
          (display_date==this.startdate) &&
          (display_year==this.startyear)) {
        date_class = "pcstartdate";
      } else if (display_month == month) {
        date_class = "pcthismonth";
      } else {
        date_class = "pcothermonth";
      }

      result += ' <td class="pcbody" align=right>' +
          '<a href="javascript:window.opener.PosseCalendarReturn(' +
          display_year + ',' + display_month + ',' + display_date +
          ',' + aRoundTrip + ');window.opener.PossePwClose();" class="' +
          date_class + '">' + display_date + '</a></td>\n';
      display_date++;
      if (display_date > daysinmonth[display_month]) {
        display_date = 1;
        display_month++;
      }
      if (display_month > 12) {
        display_month = 1;
        display_year++;
      }
    }
    result += '</tr>';
  }
  result += '<tr><td colspan=7><div class="pcline"><img width=120 height=1>' +
      '</div></td></tr>\n' +
      '<tr><td class="pcbody" colspan=7 align=center>\n';
  var now = new Date();
  result += ' <a class="pctodaylink" href="javascript:' +
      "window.opener.PosseCalendarReturn('" + now.getFullYear() +
      "','" + (now.getMonth()+1) + "','" + now.getDate() +
      '\',' + aRoundTrip + ');window.opener.PossePwClose();">Today</a>\n' +
      '</td></tr></table></center></body></html>\n';
  return result;
  }

function PosseValidateNumber(aEl, aObjectId, aColumnDefId, aMin, aMax, aSize,
    aScale, aGranularity) {
  if (aEl.value == "") {
    PosseDataChanged(aObjectId, aColumnDefId, "", 0);
    return true;
  }
  var val = aEl.value;
  var ok = true;
  var i = 0;

  nbr = val;
  i = nbr.indexOf(",");
  while (i >= 0) {
    nbr = nbr.substr(0,i) + nbr.substr(i + 1);
    i = nbr.indexOf(",");
  }

  if (isNaN(Number(nbr))) {
    ok = false;
  } else {
    if (aGranularity == null || aGranularity == 0) {
      if (aScale > -1 && aScale != null) {
        var pos = nbr.indexOf(".");
        if (pos > -1) {
          if (nbr.substr(pos + 1).length > aScale) ok = false;
        }
      }
    } else {
      nbr = Math.round(nbr / aGranularity) * aGranularity;
      var strGran = "" + aGranularity;
      var pos = strGran.indexOf(".");
      if (pos >= 0) {
        var precision = strGran.length - pos - 1;
      } else {
        var precision = 0;
      }
      var pwr = Math.pow(10, precision);
      nbr = Math.round(nbr * pwr) / pwr;
    }
    if(ok && aMin == null && aSize != null && aScale != null){
      if (aScale > 0){
        aMin = "-" + RepeatChr("9", aSize - aScale) +
            "." + RepeatChr("9", aScale);
      } else {
        aMin = "-" + RepeatChr("9", aSize);
      }
      aMin = aMin * 1; // change to a number...
    }

    if(ok && aMax == null && aSize != null && aScale != null){
      if (aScale > 0){
        aMax = RepeatChr("9", aSize - aScale) + "." + RepeatChr("9", aScale);
      } else {
        aMax = RepeatChr("9", aSize);
      }
      aMax = aMax * 1; // change to a number...
    }
    if (ok) {
      nbr = nbr * 1; // change to a number...
      if (nbr < aMin && aMin != null) {
        ok = false;
      } else {
        if (nbr > aMax && aMax != null) ok = false;
      }
    }
  }
  if (ok) {
    aEl.value = nbr;
    PosseDataChanged(aObjectId, aColumnDefId, "" + nbr, 0);
    return true;
  } else {
    var msg = "You must enter a number";
    if (aMin != null && aMax != null) {
      msg += " between " + aMin + " and " + aMax;
    } else {
      if (aMin != null) {
        msg += " greater than or equal to " + aMin;
      } else {
        if (aMax != null) {
          msg += " less than or equal to " + aMax;
        }
      }
    }
    if (aScale == 0) {
      msg += " without decimal places";
    } else {
      if (aScale > 0) {
        msg += " with no more than " + aScale + " decimal places";
      }
    }
    if (aGranularity > 0) {
      msg += ".  The number will be rounded to the nearest " + aGranularity;
    }
    msg += ".";

    PosseAlert(msg, aEl);
    return false;
  }
}

function PosseValidateEditMask(aEl, aMask) {
  var val = aEl.value;
  var mask = aMask;
  var ok = true;
  var checkedval = "";
  var numerics = "0123456789";
  var alphas = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +
      numerics;

  if (val == "") return true;

  while (val > "" && mask > "") {
    var c = val.substr(0, 1);
    val = val.substr(1);
    var msk = mask.substr(0, 1);
    mask = mask.substr(1);

    if (msk == "A" && !(alphas.indexOf(c) >= 0) || (msk == "#" || msk == "0")
        && !(numerics.indexOf(c) >= 0)) {
      ok = false;
      break;
    } else {
      if (msk == "!") {
        checkedval += "" + c.toUpperCase();
      } else {
        if (msk == "^") {
          checkedval += "" + c.toLowerCase();
        } else {
          checkedval += "" + c;
        }
      }
    }
  }

  if (val > "" || mask > "") ok = false;

  if (ok) {
    aEl.value = checkedval;
    return true;
  } else {
    var msg = "You must enter a value that is in the format " + aMask +
        " where";
    mask = aMask;
    first = true;
    ADone = false;
    XDone = false;
    NumberDone = false;
    UpperDone = false;
    LowerDone = false;

    while (mask > "") {
      msk = mask.substr(0, 1);
      mask = mask.substr(1);
      switch (msk) {
        case "A":
          if (!ADone) {
            if (first) first = false; else msg += ", and";
            msg += "\n    A is an alphanumeric character (A-Z, a-z, " +
                "or 0-9, but no special characters)";
            ADone = true;
          }
          break;
        case "X":
          if (!XDone) {
            if (first) first = false; else msg += ", and";
            msg += "\n    X is any character, including special characters";
            XDone = true;
          }
          break;
        case "#":
          if (!NumberDone) {
            if (first) first = false; else msg += ", and";
            msg += "\n    # or 0 is a number (0-9)";
            NumberDone = true;
          }
          break;
        case "0":
          if (!NumberDone) {
            if (first) first = false; else msg += ", and";
            msg += "\n    # or 0 is a number (0-9)";
            NumberDone = true;
          }
          break;
        case "!":
          if (!UpperDone) {
            if (first) first = false; else msg += ", and";
            msg += "\n    ! is any character (will be changed to upper case)";
            UpperDone = true;
          }
          break;
        case "^":
          if (!LowerDone) {
            if (first) first = false; else msg += ", and";
            msg += "\n    ^ is any character (will be changed to lower case)";
            LowerDone = true;
          }
          break;
      }
    }
    PosseAlert(msg + ".", aEl);
    return false;
  }
}

function PosseEscapeData(aValue) {
  var tPos = aValue.indexOf("\\");
  while (tPos >= 0) {
    aValue = aValue.substr(0, tPos) + "\\" + aValue.substr(tPos);
    tPos = aValue.indexOf("\\",tPos + 2);
  }

  var tPos = aValue.indexOf("\"");
  while (tPos >= 0) {
    aValue = aValue.substr(0, tPos) + "\\" + aValue.substr(tPos);
    tPos = aValue.indexOf("\"",tPos + 2);
  }

  var tPos = aValue.indexOf("'");
  while (tPos >= 0) {
    aValue = aValue.substr(0, tPos) + "\\" + aValue.substr(tPos);
    tPos = aValue.indexOf("'",tPos + 2);
  }

  var tPos = aValue.indexOf("\r");
  while (tPos >= 0) {
    aValue = aValue.substr(0, tPos) + aValue.substr(tPos + 1);
    tPos = aValue.indexOf("\r");
  }
  var tPos = aValue.indexOf("\n");
  while (tPos >= 0) {
    aValue = aValue.substr(0, tPos) + "\\n" + aValue.substr(tPos + 1);
    tPos = aValue.indexOf("\n");
  }
  return aValue;
}

function PosseLengthCheck(aValue, aLength) {
  if (aLength > 0 && aValue.length > aLength) {
    alert("You have entered " + aValue.length + " characters.  Only " +
        aLength + " are allowed.");
    return false;
  }
  return true;
}

function PosseDataChanged(aObjectID, aColumnDefID, aValue, aLength) {
  if (aObjectID == null) return true;
  if (PosseLengthCheck(aValue, aLength)) {
    aValue = PosseEscapeData(aValue);
    PosseAddDataChanges("('C','" + aObjectID + "'," + aColumnDefID + ",'" +
        aValue + "')");
    return true;
  } else {
    return false;
  }
}

function PosseRelChanged(aObjectId, aEndPointId, aToObjectId) {
  if (aObjectId == null) return true;
  PosseAddDataChanges("('R','" + aObjectId + "'," + aEndPointId + ",'" +
      aToObjectId + "')");
  return true;
}

function PosseViolationSelected(aObjectHandle, aCodeSectionId, aSelected) {
  PosseAddDataChanges("('V','" + aObjectHandle + "'," + aCodeSectionId +
      ",'" + aSelected + "')");
  return true;
}

function PosseAddClause(aElement, aObjectID, aColumnDefId, aClause) {
  var tValue = aElement.value;
  if (tValue > "") {tValue = tValue + " ";}
  tValue = tValue + aClause;
  if (PosseDataChanged(aObjectID, aColumnDefId, tValue, 32000)) {
    aElement.value = tValue;
    return true;
  } else {
    return false;
  }
}

function PosseSetMaskValues(aWidgetRef, aValues){
  var i;
  for(i=0; i<aValues.length; i++){
    PosseGetElement(aWidgetRef + "_" + (i + 1)).value = aValues[i];
  }
}

function PosseRepeatChar(aChar, aNum){
  var i, val = "";
  for (i=0; i<aNum; i++) val += aChar;
  return val;
}

var vPosseNumericEditMasks = new Array();

function PosseNumericEditMaskValue(aArr){
  var i, tEl, tHasValue = false, tReturn = "";
  for(i=0; i<aArr.length; i++) {
    tEl = aArr[i];
    if (tEl.value && tEl.value.length > 0) {
      tHasValue = true;
      tReturn += tEl.value;
    } else if(tHasValue) {
      tReturn += PosseRepeatChar("0", tEl.size);
    }
  }
  tHasValue = false;
  for(i=0; i<vPosseNumericEditMasks.length; i++) {
   if(vPosseNumericEditMasks[i][0] == aArr[0]) {
     tHasValue = true;
     break;
   }
  }
  if (!tHasValue) {
    vPosseNumericEditMasks[vPosseNumericEditMasks.length] = aArr;
  }
  return tReturn;
}

function PosseValidateNumericEditMasks() {
  var i, j, tArr, tIsNull, tIndex;
  for(i=0; i<vPosseNumericEditMasks.length; i++) {
    tArr = vPosseNumericEditMasks[i];
    tIsNull = tArr[0].value == "";
    tIndex = -1;
    for (j=1; j<tArr.length; j++) {
      if (tIsNull && tArr[j].value) {
        tIndex = j - 1;
      } else if (!tIsNull && !tArr[j].value) {
        tIndex = j;
      }
      if (tIndex > -1){
        alert("Incomplete entry.");
        tArr[tIndex].focus();
        return false;
      }
    }
  }
  return true;
}

var vPosseglobalVersion = "2009-03-05";

function PosseShowHideErrorDetails(seqNum) {
  var el = PosseGetElement("posseerrordetailsshowhide_" + seqNum);
  var tbl = PosseGetElement("posseerrordetails_" + seqNum);
  if (tbl.style.display == "none") {
    tbl.style.display = "block";
    el.innerHTML = "Hide&nbsp;Details";
  } else {
    tbl.style.display = "none";
    el.innerHTML = "Show&nbsp;Details";
  }
}

function PosseGetElementCore(coll, aId) {
  var i;
  for (i = 0; i < coll.length; i ++) {
    var el = coll[i];
    if ((el.id || el.name) == aId) return el;
  }
}

function PosseSetFocus(aId, scrollLeft, scrollTop) {
  var el = PosseGetElementOptional(aId);
  if (!el) return false;
  try {
    el.focus();
  } catch (e) {
    return false;
  }
  if (scrollLeft) document.body.scrollLeft = scrollLeft;
  if (scrollTop) document.body.scrollTop = scrollTop;
  return true;
}

function PosseNavDelayed() {
  window.setTimeout("window.PosseNavigate()", 10);
}

var posseFocusWidget = "";

function PosseOnSubmit() {
  var scrollLeft = 0;
  var scrollTop = 0;
  if (document.body) {
    if (document.body.scrollLeft) scrollLeft = document.body.scrollLeft;
    if (document.body.scrollTop) scrollTop = document.body.scrollTop;
  }
  if (document.activeElement) posseFocusWidget = document.activeElement.id;
  PosseAddDataChanges("('F','" +
      posseFocusWidget + "\'," +
      scrollLeft + "," + scrollTop + ")");
  return true;
}

function PosseGetEventTarget(evt) {
  // In Mozilla, use the argument; in IE, use window.event
  var e = evt ? evt : window.event;
  if (!e) return null;
  var el = null;
  if (e.target) {
    el = e.target;
  } else if (e.srcElement) {
    el = e.srcElement;
  }
  if (!el) return null;
  if (el.nodeType == 3) { // defeat Safari bug
    el = el.parentNode;
  }
  return el;
}

function PosseRecordFocus(evt) {
  var el = PosseGetEventTarget(evt);
  if (!el) return;
  if (el.id) posseFocusWidget = el.id;
}

function PosseAddEventListeners(el) {
  if (el.id && el.tabIndex) {
    if (el.attachEvent) {
      el.attachEvent("onfocus", PosseRecordFocus);
    } else if (el.addEventListener) {
      el.addEventListener("focus", PosseRecordFocus, false);
    }
  }
}

function PosseSetEventHandlers() {
  if (document.activeElement) return;
  var i, j, frm, el;
  for (i = 0; i < document.forms.length; i++) {
    frm = document.forms[i];
    for (j = 0; j < frm.elements.length; j++) {
      PosseAddEventListeners(frm.elements[j]);
    }
  }
  for (i = 0; i < document.links.length; i++) {
    PosseAddEventListeners(document.links[i]);
  }
  for (i = 0; i < document.images.length; i++) {
    PosseAddEventListeners(document.images[i]);
  }
}
