var MINUTE = 60 * 1000;
var HOUR   = MINUTE * 60;
var DAY    = HOUR * 24;
var WEEK   = DAY * 7;

var monthItem;
var dayItem;
var yearItem;

var objDtL1;
var objDtL2;

var arrDates  = new Array();
var arrMonths = new Array();
var arrDays   = new Array();

var prevMonth;
var prevYear;

var gdtmToday;

function objDateSet(itmY,itmM,itmD,objL1,objL2,blnNoDate) {
  this.itmY      = itmY;
  this.itmM      = itmM;
  this.itmD      = itmD;
  this.objL1     = objL1;
  this.objL2     = objL2;
  this.blnNoDate = blnNoDate;
}

function objMonth(name) {
  this.name = name;
}

function objDay(name) {
  this.name = name;
}

function isNonPeakDay(dtmDate) {
   var arrPeakDates = ["6/29","6/30","7/1","7/2","7/3","7/4","7/5","8/31","9/1","9/2","9/3","9/4","9/5"];

   var mstrDateMonthDay = (dtmDate.getMonth() + 1).toString() + '/' + (dtmDate.getDate()).toString();
   var blnNonPeak = false;

   if (((dtmDate.getDay() == 2) || (dtmDate.getDay() == 3) || (dtmDate.getDay() == 4)) && (dtmDate.getDate() <= 17)) {
      for (var i=0; i < arrPeakDates.length; i++) {
         if (mstrDateMonthDay == arrPeakDates[i]) {
            blnNonPeak = false;
            break;
         }
         else blnNonPeak = true;
      }
   }

   return blnNonPeak;
}

function isHoliday(dtmDate) {
  var mstrChristmasEve = '12/24';
  var mstrChristmasDay = '12/25';
  var mstrNewYearsDay  = '1/1';
  var mstrJuly4th      = '7/4';
  var mdtmTempDate     = new Date(dtmDate);
  var mstrDateMonthDay = (dtmDate.getMonth() + 1).toString() + '/' + (dtmDate.getDate()).toString();

// csm Use switch statement
// http://developer.netscape.com/docs/manuals/communicator/jsref/stmt14.htm#1018610
  if ((dtmDate.getMonth() + 1) == 1) {
    return (mstrNewYearsDay == mstrDateMonthDay);
  }
  else if ((dtmDate.getMonth() + 1) == 5) {
    return isMemorialDay(dtmDate);
  }
  else if ((dtmDate.getMonth() + 1) == 7) {
    return (mstrJuly4th == mstrDateMonthDay);
  }
  else if ((dtmDate.getMonth() + 1) == 9) {
    return isLaborDay(dtmDate);
  }
  else if ((dtmDate.getMonth() + 1) == 11) {
    if (isThanksgiving(dtmDate)) {
      return true;
    }
    else if (dtmDate.getDate() > 1) {
      mdtmTempDate.setDate(dtmDate.getDate() - 1);
      return isThanksgiving(mdtmTempDate);
    }
  }
  else if ((dtmDate.getMonth() + 1) == 12) {
    return ((mstrChristmasDay == mstrDateMonthDay) || (mstrChristmasEve == mstrDateMonthDay));
  }
  return false;
}

function isLeapYear(intYear) {
  return (((intYear % 4 == 0) && (intYear % 100 != 0)) || (intYear % 400 == 0));
}

function getNumDays(intMonth, intYear) {
   if ((intMonth == 4) || (intMonth == 6) || (intMonth == 9) || (intMonth == 11)) {
      return 30;
   }
   else if (intMonth == 2) {
      if (isLeapYear(intYear)) return 29;
      else return 28;
   }
   else return 31;
}

function nthOccurenceOfDay(intDoW, intN, intYear, intMonth) {
  var mDtmTemp;
  var mIntDay;
  var mIntModifier;

  if (intN > 0) {
    mDtmTemp = new Date(intYear, intMonth, 1);
    mIntModifier = 1;
  }
  else {
    mDtmTemp = new Date(intYear, intMonth, getNumDays(intMonth + 1, intYear));
    mIntModifier = -1;
  }

  while (mDtmTemp.getDay() != intDoW) {
    mDtmTemp.setDate(mDtmTemp.getDate() + mIntModifier);
  }
  mIntDay = mDtmTemp.getDate() + ((intN - mIntModifier) * 7);
  if (isNaN(mIntDay)) {
    mIntDay = 0;
  }
  return mIntDay;
}

function isThanksgiving(dtmDate) {
  if ((dtmDate.getMonth() + 1) == 11) {
    if ((dtmDate.getDate() == nthOccurenceOfDay(4, 4, y2kFmt(dtmDate.getYear()), dtmDate.getMonth())) ||
       (dtmDate.getDate() == nthOccurenceOfDay(5, 4, y2kFmt(dtmDate.getYear()), dtmDate.getMonth())) ||
       (dtmDate.getDate() == nthOccurenceOfDay(6, 4, y2kFmt(dtmDate.getYear()), dtmDate.getMonth()))) {
       return true;
    }
    else return false;
  }
  return false;
}

function isMemorialDay(dtmDate) {
  if ((dtmDate.getMonth() + 1) == 5) {
    return (dtmDate.getDate() == nthOccurenceOfDay(1, -1, y2kFmt(dtmDate.getYear()), dtmDate.getMonth()));
  }
  return false;
}

function isLaborDay(dtmDate) {
  if ((dtmDate.getMonth() + 1) == 9) {
    return (dtmDate.getDate() == nthOccurenceOfDay(1, 1, y2kFmt(dtmDate.getYear()), dtmDate.getMonth()));
  }
  return false;
}

function initMonthList() {
  arrMonths[0]  = new objMonth('January');
  arrMonths[1]  = new objMonth('February');
  arrMonths[2]  = new objMonth('March');
  arrMonths[3]  = new objMonth('April');
  arrMonths[4]  = new objMonth('May');
  arrMonths[5]  = new objMonth('June');
  arrMonths[6]  = new objMonth('July');
  arrMonths[7]  = new objMonth('August');
  arrMonths[8]  = new objMonth('September');
  arrMonths[9]  = new objMonth('October');
  arrMonths[10] = new objMonth('November');
  arrMonths[11] = new objMonth('December');
}


function initDayList() {
  arrDays[0] = new objDay('Sunday');
  arrDays[1] = new objDay('Monday');
  arrDays[2] = new objDay('Tuesday');
  arrDays[3] = new objDay('Wednesday');
  arrDays[4] = new objDay('Thursday');
  arrDays[5] = new objDay('Friday');
  arrDays[6] = new objDay('Saturday');
}

function initEmptyDayList() {
  arrDays[0] = new objDay('');
  arrDays[1] = new objDay('');
  arrDays[2] = new objDay('');
  arrDays[3] = new objDay('');
  arrDays[4] = new objDay('');
  arrDays[5] = new objDay('');
  arrDays[6] = new objDay('');
}


function initDate(seq,yr,mn,dy,dysL1,dysL2,blnBusinessDays,blnWeekends,bln1stWeekend,blnSaturday,blnSunday) {
  var objDtNow = new Date(gdtmToday);
  objDtL1 = null;
  objDtL2 = null;
  objDtL1 = dateFromDays(y2kFmt(objDtNow.getYear()),(objDtNow.getMonth()+1),objDtNow.getDate(),dysL1, blnBusinessDays);
  objDtL2 = dateFromDays(y2kFmt(objDtNow.getYear()),(objDtNow.getMonth()+1),objDtNow.getDate(),dysL2, blnBusinessDays);
  //Nick Testing
  //objDtL1 = dateFromDays(y2kFmt(2009),2,15,dysL1, blnBusinessDays);
  //objDtL2 = dateFromDays(y2kFmt(2009),2,15,dysL2, blnBusinessDays);

  arrDates[seq].objL1 = objDtL1;
  arrDates[seq].objL2 = objDtL2;

  if ((yr == 0)||(mn == 0)||(dy == 0)) {
    setListDate(seq,y2kFmt(objDtNow.getYear()),(objDtNow.getMonth()+1),objDtNow.getDate(),blnWeekends,true,bln1stWeekend,blnSaturday,blnSunday);
  }
  else {
    setListDate(seq,yr,mn,dy,blnWeekends,true,bln1stWeekend,blnSaturday,blnSunday);
  }

  if (arrDates[seq].blnNoDate) { setDateFirst(seq); }
}


function setListDate(seq,yr,mn,dy,blnWeekends,blnFromCal,bln1stWeekend,blnSaturday,blnSunday) {
  var idx    = 0;
  var idxSet = 0;
  var objDtDay;
  var intBegin;
  var intEnd;
  var intWkndDays = 0;
  var intTempCnt = 0;
  var intC1 = dateComp(yr,mn,dy,y2kFmt(arrDates[seq].objL1.getYear()),(arrDates[seq].objL1.getMonth()+1),arrDates[seq].objL1.getDate());
  var intC2 = dateComp(yr,mn,dy,y2kFmt(arrDates[seq].objL2.getYear()),(arrDates[seq].objL2.getMonth()+1),arrDates[seq].objL2.getDate());
  var blnDaySet = false;
  var objDtNow = new Date(gdtmToday);
  var datediff = 0;

  if (bln1stWeekend == undefined) bln1stWeekend = blnWeekends;
  if (blnSaturday == undefined) blnSaturday = blnWeekends;
  if (blnSunday == undefined) blnSunday = blnWeekends;

  if (intC1 < 0) {
    while ((arrDates[seq].objL1.getDay() == 0) || (arrDates[seq].objL1.getDay() == 6) || isHoliday(arrDates[seq].objL1)) {
       arrDates[seq].objL1.setDate(arrDates[seq].objL1.getDate() + 1);
    }
    yr = y2kFmt(arrDates[seq].objL1.getYear());
    mn = arrDates[seq].objL1.getMonth()+1;
    dy = arrDates[seq].objL1.getDate();
  }

  if (intC2 > 0) {
    while ((arrDates[seq].objL2.getDay() == 0) || (arrDates[seq].objL2.getDay() == 6) || isHoliday(arrDates[seq].objL2)) {
       arrDates[seq].objL2.setDate(arrDates[seq].objL2.getDate() + 1);
    }
    yr = y2kFmt(arrDates[seq].objL2.getYear());
    mn = arrDates[seq].objL2.getMonth()+1;
    dy = arrDates[seq].objL2.getDate();
  }

  // Set year:
  idx    = 0;
  idxSet = 0;

  arrDates[seq].itmY.options.length = 0;

  if (arrDates[seq].blnNoDate) {
    arrDates[seq].itmY.options[idx] = new Option("- - - -","");
    idx++;
  }

  for (var y = y2kFmt(arrDates[seq].objL1.getYear()); y < (y2kFmt(arrDates[seq].objL2.getYear())+1); y++) {
    arrDates[seq].itmY.options[idx] = new Option(y,y);
    if (y == yr) { idxSet = idx};
    idx++;
  }
  arrDates[seq].itmY.options[idxSet].selected = true;

  // Set month:
  idx    = 0;
  idxSet = 0;

  arrDates[seq].itmM.options.length = 0;

  if (arrDates[seq].blnNoDate) {
    arrDates[seq].itmM.options[idx] = new Option("- - -","");
    idx++;
  }

  if (yr == y2kFmt(arrDates[seq].objL1.getYear())) { intBegin = arrDates[seq].objL1.getMonth();}
  else { intBegin = 0;}

  if (yr == y2kFmt(arrDates[seq].objL2.getYear())) { intEnd = arrDates[seq].objL2.getMonth();}
  else { intEnd = 11;}

  for (var m = intBegin; m < (intEnd+1); m++) {
    arrDates[seq].itmM.options[idx] = new Option(arrMonths[m].name.substring(0,3),m+1);
    if (m == (mn-1)) { idxSet = idx;}
    idx++;
  }
  arrDates[seq].itmM.options[idxSet].selected = true;

  // Set day:
  idx    = 0;
  idxSet = 0;

  arrDates[seq].itmD.options.length = 0;

  if (arrDates[seq].blnNoDate) {
    arrDates[seq].itmD.options[idx] = new Option("- - - - -","");
    idx++;
  }

  if ((yr == y2kFmt(arrDates[seq].objL1.getYear())) && (mn == (arrDates[seq].objL1.getMonth()+1))) { intBegin = arrDates[seq].objL1.getDate();}
  else { intBegin = 1;}

  if ((yr == y2kFmt(arrDates[seq].objL2.getYear())) && (mn == (arrDates[seq].objL2.getMonth()+1))) { intEnd = arrDates[seq].objL2.getDate();}
  else { intEnd = lastDay(yr,mn);}

  prevMonth = mn;
  prevYear  = yr;

   for (var d = intBegin; d < (intEnd+1); d++) {
      objDtDay = new Date(yr,mn-1,d);
      intTempCnt += 1;

      if (!isHoliday(objDtDay)) {
         //count the first two weekend days
         if (!bln1stWeekend && intWkndDays <= 2){
            if (objDtDay.getDay() == 0 || objDtDay.getDay() == 6) {
               intWkndDays += 1;
               datediff = Math.ceil((objDtDay - objDtNow)/86400000); //86400000 = number of milliseconds in one day
               //if we are past the 6th day then we have already past the first weekend
               if (datediff >= 6) intWkndDays = 3;
            }
         }
         if ((blnWeekends && (bln1stWeekend || intWkndDays > 2) && (blnSaturday || objDtDay.getDay() != 6) && (blnSunday || objDtDay.getDay() != 0)) || ((objDtDay.getDay() != 0) && (objDtDay.getDay() != 6))) {
            arrDates[seq].itmD.options[idx] = new Option(d + " " + arrDays[objDtDay.getDay()].name.substring(0,3),d);
            if (blnFromCal) {
               if (d == dy) idxSet = idx;
            }
            else if (!blnDaySet) {
               if (isNonPeakDay(objDtDay)) {
                  idxSet = idx;
                  blnDaySet = true;
               }
            }
            idx++;
         }
      }
   }
   arrDates[seq].itmD.options[idxSet].selected = true;
}

function chkYear(seq,weekends,bln1stWeekend,blnSaturday,blnSunday) {
  if (arrDates[seq].itmY.options[arrDates[seq].itmY.options.selectedIndex].value == "") {
    setDateFirst(seq);
  }
  else {
    updateDate(seq,true,false,weekends,bln1stWeekend,blnSaturday,blnSunday);
  }
}


function chkMonth(seq,weekends,bln1stWeekend,blnSaturday,blnSunday) {
  if (arrDates[seq].itmM.options[arrDates[seq].itmM.options.selectedIndex].value == "") {
    setDateFirst(seq);
  }
  else {
    updateDate(seq,false,false,weekends,bln1stWeekend,blnSaturday,blnSunday);
  }
}


function chkDay(seq,weekends,bln1stWeekend,blnSaturday,blnSunday) {
  if (arrDates[seq].itmD.options[arrDates[seq].itmD.options.selectedIndex].value == "") {
    setDateFirst(seq);
  }
  else if (arrDates[seq].itmY.options[arrDates[seq].itmY.options.selectedIndex].value == "") {
    	updateDate(seq,false,true,weekends,bln1stWeekend,blnSaturday,blnSunday);
  }
}


function updateDate(seq,blnYr,blnDay,blnWeekends,bln1stWeekend,blnSaturday,blnSunday) {
   if (blnDay) {
	   var intY = prevYear;
		var intM = prevMonth;
		var intD = arrDates[seq].itmD.options[arrDates[seq].itmD.options.selectedIndex].value;
   }
	else {
      if (arrDates[seq].blnNoDate) {
			var intY = (!blnYr)? arrDates[seq].itmY.options[1].value : arrDates[seq].itmY.options[arrDates[seq].itmY.options.selectedIndex].value;
		}
      else {
		   var intY = arrDates[seq].itmY.options[arrDates[seq].itmY.options.selectedIndex].value;
		}
	   var intM = (blnYr)? 1 : arrDates[seq].itmM.options[arrDates[seq].itmM.options.selectedIndex].value;
		var intD = 1;
	}

   setListDate(seq,intY,intM,intD,blnWeekends,false,bln1stWeekend,blnSaturday,blnSunday);
}


function setDateFirst(seq) {
  arrDates[seq].itmY.options[0].selected = true;
  arrDates[seq].itmM.options[0].selected = true;
  arrDates[seq].itmD.options[0].selected = true;
}


function buildDateOps(sz) {
  var strX = "XXXXXXXXXXXXXXXXXXXX";
  var sText = "";

  for (var z = 0; z < 10; z++) {
    sText += "<option>"+strX.substring(0,sz)+"</option>";
  }
  return sText;
}


function buildDate(seq,fName,yName,mName,dName,blnCal,blnNoDate,intSD,intED,blnColors,blnSqueeze,blnWeekends,bln1stWeekend,blnSaturday,blnSunday,blnSqueezeWide) {
   var sdate  = 'document.' + fName + '.' + mName + '.options[document.' + fName + '.' + mName + '.selectedIndex].value';
   var strColors = (blnColors) ? 'Y' : '';
   var strWeekends = (blnWeekends) ? 'Y' : '';
   var str1stWeekend = (bln1stWeekend) ? 'Y' : 'N';
   var strSaturday = (blnSaturday) ? 'Y' : 'N';
   var strSunday = (blnSunday) ? 'Y' : 'N';
   var sText = "";
   if (bln1stWeekend == undefined) str1stWeekend = strWeekends;
   if (blnSaturday == undefined) strSaturday = strWeekends;
   if (blnSunday == undefined) strSunday = strWeekends;

   sdate += '+ \'/\' + document.' + fName + '.' + dName + '.options[document.' + fName + '.' + dName + '.selectedIndex].value';
   sdate += '+ \'/\' + document.' + fName + '.' + yName + '.options[document.' + fName + '.' + yName + '.selectedIndex].value';
   sText = '<table border="0" cellpadding="0" cellspacing="0"><tr>';
   if (blnSqueezeWide) {
      yCol = 60;
      mCol = 55;
      dCol = 50;
   }
   else if (blnSqueeze) {
      yCol = 55;
      mCol = 50;
      dCol = 45;
   }
   else {
      yCol = 70;
      mCol = 65;
      dCol = 75;
   }

   sText += '<td width="' + yCol + '" NOWRAP="NOWRAP">';
   sText += '<select name="' + yName + '" id="' + yName + '" size="1" onchange="chkYear(' + seq + ',' + blnWeekends + ',' + bln1stWeekend + ',' + blnSaturday + ',' + blnSunday + ');">';
   sText += buildDateOps(4);
   sText += '</select></td>';

   sText += '<td width="' + mCol + '" NOWRAP="NOWRAP">';
   sText += '<select name="' + mName + '" id="' + mName + '" size="1" onchange="chkMonth(' + seq + ',' + blnWeekends + ',' + bln1stWeekend + ',' + blnSaturday + ',' + blnSunday + ')">';
   sText += buildDateOps(3);
   sText += '</select></td>';

   sText += '<td width="' + dCol + '" NOWRAP="NOWRAP">';
   sText += '<select name="' + dName + '" id="' + dName + '" size="1" onchange="chkDay(' + seq + ',' + blnWeekends + ',' + bln1stWeekend + ',' + blnSaturday + ',' + blnSunday + ')">';
   if (!blnSqueeze) sText += buildDateOps(6);
   else sText += buildDateOps(2);
   sText += '</select></td>';

   if (blnCal) {
      sText += '<td NOWRAP="NOWRAP">';
      if (!blnSqueeze) sText += '&nbsp;';
      sText += '<a href="javascript:upWinXY(\'calWin\',\'/calwin.asp?seq=' + seq + '&wknd=' + strWeekends + '&wknd1=' + str1stWeekend + '&sat=' + strSaturday + '&sun=' + strSunday + '&cg=' + strColors + '&sdays=' + intSD + '&edays=' + intED + '&sd=\' + ' + sdate + ',340,290,false);">';
      sText += '<img src="/images/cal.jpg" alt="Click to select date..." title="Click to select date..." align="CENTER" width="16" height="14" border="0" name="cal' + seq + '" id="cal' + seq + '" /></a></td>';
   }
   sText += '</tr>';
   sText += '</table>';

   document.writeln(sText);

   yearItem  = null;
   monthItem = null;
   dayItem   = null;

   eval('yearItem = document.' + fName + '.' + yName);
   eval('monthItem = document.' + fName + '.' + mName);
   eval('dayItem = document.' + fName + '.' + dName);

   arrDates[seq] = new objDateSet(yearItem,monthItem,dayItem,null,null,blnNoDate);
}


function dateFromDays(yr,mn,dy,intDays,blnBusinessDays) {
   var mn2 = mn - 1;

   var objDate1 = new Date(yr,mn2,dy,12,0,0);
   var objDate2 = new Date(gdtmToday);
   if (blnBusinessDays) {
      for (var i = 0; i <= intDays; i++) {
         if ((objDate2.getDay() == 0) || (objDate2.getDay() == 6) || (isHoliday(objDate2))) {
            intDays++;
         }
         objDate2.setTime(objDate2.getTime() + DAY);
      }
   }
   objDate2.setTime(objDate1.getTime() + (intDays * DAY));

   return objDate2;
}


function y2kFmt(yr) {
  return (yr < 2000)? (yr + 1900) : yr;
}


function dateComp(yr1,mn1,dy1,yr2,mn2,dy2) {
  mn1--;
  mn2--;

  var objDt1 = new Date(yr1,mn1,dy1);
  var objDt2 = new Date(yr2,mn2,dy2);

  objDt1.setHours(0);
  objDt1.setMinutes(0);
  objDt1.setSeconds(0);

  objDt2.setHours(0);
  objDt2.setMinutes(0);
  objDt2.setSeconds(0);

  var int1 = Date.parse(objDt1.toGMTString());
  var int2 = Date.parse(objDt2.toGMTString());

   if ((int1 - int2) == 0) {
      return 0;
   }
   else {
      if ((int1 - int2) > 0) return 1;
      else return -1;
   }
}

function lastDay(yr,mn) {
   var lDay;
   var objDt = new Date(yr,(mn-1),28);

   for (var d = 28; d < 32; d++) {
      objDt.setDate(d);
      if (objDt.getMonth()+1 == mn) lDay = d;
   }
   return lDay;
}

function isDate(year, month, day) {
   if (!isInteger(year) || !isInteger(month) || !isInteger(day)) return false;
   return true;
}
