
  var imagePath="images/";

  var ie=document.all;
  var docGeid=document.getElementById;
  var ns4=document.layers;
  var bShow=false;
  var textCtl; // "bogus" form field?? what is this for???
  
  var debugging=false; // for use in logging.

  function setTimePicker(t) {
    textCtl.value=t;
    validateDatePicker(textCtl);
    closeTimePicker();
  }

  function nearestTime(n) {
    if (debugging) logger("nearestTime");
    var t = new Object();
    t.value = n;
    // t is not a screen object, so call vDP2. vDP itself expects to be given a reference to a textbox.
    validateDatePicker2(t);
    
    // time is now validated; should be in xx:xx am/pm format.
    var arr = t.value.split(":");
    var a2=arr[1].split(" ");
    var mn=parseInt(a2[0],10);
    var ampm=a2[1];
    
    // get nearest minute boundary, within 15 mins.
    var nMin= parseInt((mn+7)/15, 10)*15;
    
    return arr[0]+":"+padZero(nMin)+" "+ampm;
       
  }

  function refreshTimePicker(mode, tm) {

    if (tm===undefined) { // is ===undefined an error, or is this correct javascript syntax?
        if (mode==0)
          { 
            suffix="am"; 
          }
        else
          { 
            suffix="pm"; 
          }
    } else {
      tm = nearestTime(tm); // get time to nearest 15 min. interval.
      suffix=tm.split(" ")[1];
      if (suffix=="am") 
        mode = 0; 
      else 
        mode = 1;
    }

    if (mode==0) {
        document.getElementById("iconAM").src= imagePath + "am1.gif";
        document.getElementById("iconPM").src= imagePath + "pm2.gif";
    } else {
        document.getElementById("iconAM").src= imagePath + "am2.gif";
        document.getElementById("iconPM").src= imagePath + "pm1.gif";
    }

    sHTML = "<table><tr><td><table cellpadding=3 cellspacing=0 bgcolor='#FFFFFF'>";
    for (i=0;i<12;i++) {

      sHTML+="<tr align=right style='font-family:arial;font-size:11px;color:#000000;'>";

      if (i==0) {
        hr = 12;
      }
      else {
        hr=i;
      }  

      for (j=0;j<4;j++) {
        var thisTime=hr+":"+padZero(j*15)+" " + suffix;
        var bgcolor = "";
        if (thisTime==tm) {bgcolor="bgcolor='#18689D'";}
        
        sHTML+="<td " + bgcolor + "width=57 style='cursor:hand;font-family:arial;font-size:11px;' onmouseover='this.style.backgroundColor=\"#1973AD\"' onmouseout='this.style.backgroundColor=\"\"' onclick='setTimePicker(\""+ hr + ":" + padZero(j*15) + "&nbsp;" + suffix 
        + "\")'><a style='text-decoration:none;color:#000000' href='javascript:setTimePicker(\""+ hr + ":" + padZero(j*15) + "&nbsp;" + suffix + "\")'>" + hr + ":"+padZero(j*15) +"&nbsp;"+ "<font color=\"#808080\">" + suffix + "&nbsp;</font></a></td>";

      }

      sHTML+="</tr>";
    }
    sHTML += "</table></td></tr></table>";
    document.getElementById("timePickerContent").innerHTML = sHTML;
  }

  if (docGeid){
    document.write ("<div id='timepicker' style='z-index:9;position:absolute;visibility:hidden;'><table style='border-width:3px;border-style:solid;border-color:#2A536F' bgcolor='#ffffff' cellpadding=0><tr bgcolor='#2A536F'><td><table cellpadding=0 cellspacing=0 width='100%' background='" + imagePath + "titleback.gif'><tr valign=bottom height=21><td style='font-family:arial;font-size:11px;color:#ffffff;padding:3px' valign=center><B>&nbsp;Select&nbsp;Time </B></td><td><img id='iconAM' src='" + imagePath + "am1.gif' onclick='document.getElementById(\"iconAM\").src=\"" + imagePath + "am1.gif\";document.getElementById(\"iconPM\").src=\"" + imagePath + "pm2.gif\";refreshTimePicker(0)' style='cursor:hand'></td><td><img id='iconPM' src='" + imagePath + "pm2.gif' onclick='document.getElementById(\"iconAM\").src=\"" + imagePath + "am2.gif\";document.getElementById(\"iconPM\").src=\"" + imagePath + "pm1.gif\";refreshTimePicker(1)' style='cursor:hand'></td><td align=right valign=center>&nbsp;<img onclick='closeTimePicker()' src='" + imagePath + "close2.gif'  STYLE='cursor:hand'>&nbsp;</td></tr></table></td></tr><tr><td colspan=2><span id='timePickerContent'></span></td></tr></table></div>");
    refreshTimePicker(0);
  }

  var crossobj=(docGeid)?document.getElementById("timepicker").style : ie? document.all.timepicker : document.timepicker;
  var currentCtl;

  // get absolute position of a control. use with overlays, dropdowns, etc.
  function getAbsPos(ctl) {
    var leftpos=0
    var toppos=0
    var aTag = ctl
    do {
      aTag = aTag.offsetParent;
      leftpos  += aTag.offsetLeft;
      toppos += aTag.offsetTop;
    } while(aTag.tagName!="BODY");
    
    var o= new Object();
    o.left=leftpos
    o.top = toppos;
    return o;
  }    

  // show time picker. ctl is the timepicker button (image) pressed. ctl2 is the text element to be populated with the time.
  function selectTime(ctl,ctl2) {
    if (debugging) logger("selectTime:"+ctl2.id);

    textCtl=ctl2;

    if ((currentCtl != ctl) && (currentCtl != null)) {// not the same
        currentCtl.src=imagePath + "timepicker.gif"; // prev button in released state
    }
    currentCtl = ctl;
    currentCtl.src=imagePath + "timepicker2.gif"; // curr button pressed state

    if (ctl2.value!="") {
        var res=validateDatePicker2(ctl2);
        if (res)
            refreshTimePicker(0, ctl2.value);
        else
            refreshTimePicker(0);
    }
    
    aPos = getAbsPos(ctl);
    
    crossobj.left =  ctl.offsetLeft  + aPos.left;
    crossobj.top = ctl.offsetTop +  aPos.top + ctl.offsetHeight +  2 
    crossobj.visibility=(docGeid||ie)? "visible" : "show"
    hideElement( 'SELECT', document.getElementById("timepicker") );
    hideElement( 'APPLET', document.getElementById("timepicker") );

    curtain.show();
    
    bShow = true;
  }

  // hides <select> and <applet> objects (for IE only)
  function hideElement( elmID, overDiv ){
    if( ie ){
      for( i = 0; i < document.all.tags( elmID ).length; i++ ){
        obj = document.all.tags( elmID )[i];
        if( !obj || !obj.offsetParent ){
            continue;
        }
          // Find the element's offsetTop and offsetLeft relative to the BODY tag.
          objLeft   = obj.offsetLeft;
          objTop    = obj.offsetTop;
          objParent = obj.offsetParent;
          while( objParent.tagName.toUpperCase() != "BODY" )
          {
          objLeft  += objParent.offsetLeft;
          objTop   += objParent.offsetTop;
          objParent = objParent.offsetParent;
          }
          objHeight = obj.offsetHeight;
          objWidth = obj.offsetWidth;
          if(( overDiv.offsetLeft + overDiv.offsetWidth ) <= objLeft );
          else if(( overDiv.offsetTop + overDiv.offsetHeight ) <= objTop );
          else if( overDiv.offsetTop >= ( objTop + objHeight + obj.height ));
          else if( overDiv.offsetLeft >= ( objLeft + objWidth ));
          else
          {
          obj.style.visibility = "hidden";
          }
      }
    }
  }
     
  //unhides <select> and <applet> objects (for IE only)
  function showElement( elmID ){
    if( ie ){
      for( i = 0; i < document.all.tags( elmID ).length; i++ ){
        obj = document.all.tags( elmID )[i];
        if( !obj || !obj.offsetParent ){
            continue;
        }
        obj.style.visibility = "";
      }
    }
  }

  function closeTimePicker() {
    bShow=false;
    crossobj.visibility="hidden"
    showElement( 'SELECT' );
    showElement( 'APPLET' );
    currentCtl.src=imagePath + "timepicker.gif"
    
    curtain.hide();
  }

  document.onkeypress = function(e) {
    var keynum;
    if (window.event) // IE
      keynum=window.event.keyCode;
    else // Netscape/Firefox/Opera
      keynum = e.keyCode; 
      
    if (keynum == 27) 
      if (bShow)
        closeTimePicker();
  }

  function isDigit(c) {
    
    return ((c=='0')||(c=='1')||(c=='2')||(c=='3')||(c=='4')||(c=='5')||(c=='6')||(c=='7')||(c=='8')||(c=='9'))
  }

  function isNumeric(n) {
    
    num = parseInt(n,10);

    return !isNaN(num);
  }

  function padZero(n) {
    v="";
    if (n<10){ 
      return ('0'+n);
    }
    else
    {
      return n;
    }
  }

   // if the hour is between 9 to 11, assume it is AM. if it is between 12-8, assume it is PM
  function amOrPm(hr) {
    if ((parseInt(hr,10)>=9) && (parseInt(hr)<=11))
         return "am"
    else
        return "pm"
  }

    // validate whether the contents of a textbox represent a valid time.
   function validateDatePicker(ctl) {
        if (debugging) logger("validateDatePicker");
        var res=validateDatePicker2(ctl);
        if (res!=true)
            ctl.style.color="#FF0000";
        else
            ctl.style.color="#000000";
        return res;
   }

  // validate the time
  function validateDatePicker2(ctl) {
    if (debugging) logger("validateDatePicker2");
    t=ctl.value.toLowerCase();
    t=t.replace(" ","");
    t=t.replace(".",":");
    t=t.replace("-","");

    if ((isNumeric(t))&&(t.length==4))
    {
      t=t.charAt(0)+t.charAt(1)+":"+t.charAt(2)+t.charAt(3);
    }

    var t=new String(t);
    tl=t.length;

    if (tl==1 ) {
      if (isDigit(t)) {
        if (t=="0") 
            ctl.value="12:00 am";
        else
            ctl.value=t+":00" +amOrPm(t);
      }
      else {
        return false;
      }
    }
    else if (tl==2) {
      if (isNumeric(t)) {
        if (parseInt(t,10)<13){
          if (t.charAt(1)!=":") {
            ctl.value= t + ':00' + amOrPm(t);
          }
          else {
            if (t.charAt(0)=="0")
                ctl.value="12:00 am";
            else
                ctl.value= t + '00' + amOrPm(t);
          }
        }
        else if (parseInt(t,10)==24) {
          ctl.value= "12:00 am";
        }
        else if (parseInt(t,10)<24) {
          if (t.charAt(1)!=":") {
            ctl.value= (t-12) + ':00 pm';
          } 
          else {
            ctl.value= (t-12) + '00 pm';
          }
        }
        else if (parseInt(t,10)<=60) {
          ctl.value= '0:'+padZero(t)+' am';
        }
        else {
          ctl.value= '1:'+padZero(t%60)+' am';
        }
      }
      else
           {
        if ((t.charAt(0)==":")&&(isDigit(t.charAt(1)))) {
          ctl.value = "0:" + padZero(parseInt(t.charAt(1),10)) + " am";
        }
        else {
          return false;
        }
      }
    }
    else if (tl>=3) {

        // 3-digit time modification by MV, 5/2007
        if ((tl==3) && (!isNumeric(t))) return false;
        if ((tl==3) && (isNumeric(t))) {
            // time is in format, say 330, for 330 am or pm
            var tHour=t.charAt(0);
            var tMin=t.charAt(1)+t.charAt(2);
            hr=parseInt(tHour,10);
            mn=parseInt(tMin,10);
            if (isNaN(mn)) mn=0; // e.g. if "7qq" is entered, this becomes 7:00pm
            if ((mn<0) || (mn>59))
                return false;
            if (hr==0) {
                hr=12;
                mode="am";
            } else
                mode=amOrPm(tHour);            
            
            ctl.value=hr+":"+padZero(mn)+" "+mode;
            return true;
        }

      // now tl>3
      var arr = t.split(":");
      if (t.indexOf(":") > 0)
      {
        hr=parseInt(arr[0],10);
        mn=parseInt(arr[1],10);

        if (t.indexOf("pm")>0)
          mode="pm";
        else if (t.indexOf("am")>0)
          mode="am";
        else
          mode=amOrPm(hr);

        if (isNaN(hr)) {
          return false;
          hr=0;
        } else {
          if (hr>24) {
            return false;
          }
          else if (hr==24) {
            mode="am";
            hr=0;
          }
          else if (hr>12) {
            mode="pm";
            hr-=12;
          }
        }
      
        if (isNaN(mn)) {
          mn=0;
        }
        else {
          if (mn>60) {
            mn=mn%60;
            hr+=1;
          }
        }
      } else {

        hr=parseInt(arr[0],10);

        if (isNaN(hr)) {
          return false;
          // hr=0;
        } else {
          if (hr>24) {
            return false;
          }
          else if (hr==24) {
            mode="am";
            hr=0;
          }
          else if (hr>12) {
            mode="pm";
            hr-=12;
          }
        }

        mn = 0;
      }
      
      if (hr==24) {
        hr=0;
        mode="am";
      }
      ctl.value=hr+":"+padZero(mn)+" "+mode;
    }
    return true;
  }

/**********************************************************************************************
  Curtain object & methods. Throw a translucent curtain on screen objects.
 **********************************************************************************************/

  var Curtain = function(id){
    document.write("<div id='"+id+"' style='z-index:8;visibility:hidden;background: #333; opacity: 0.10; filter: alpha(opacity=10); position: absolute; top:0; left:0; width: 100%; height: 100%;'>&nbsp;</div>");
    this.id=id;
  };
  
  Curtain.prototype.show = function () {
    this._scrn().style.visibility="visible";
    this._autoResize();
  }

  Curtain.prototype.hide = function() {
    this._scrn().style.visibility="hidden";
  }
  
  // Modal overlay screen element
  Curtain.prototype._scrn = function() {
      return document.getElementById(this.id);
       
  }
 
  // set gray overlay screener size to document size, including scrollbars
  Curtain.prototype._autoResize = function() {
    // try to set to 0, so that the overlay does not influence the document size. this may or may not work...
    // seems to work in firefox, but the height does not readjust in IE6.
    this._scrn().style.width=0;
    this._scrn().style.height=0;
    if (ie) {
        this._scrn().style.width=document.body.scrollWidth;
        this._scrn().style.height=document.body.scrollHeight;
    } else {
        this._scrn().style.width=document.body.scrollWidth;
        this._scrn().style.height=document.documentElement.scrollHeight;
    }
  }

  // capture window onresize, so that curtain can be resized. 
  window.onresize = function() { curtain._autoResize(); }
  
  curtain = new Curtain();
