var months = new Array("jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec");
var c_arrMonthNames = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
var c_arrMonthDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var c_arrWeekNames = new Array('firstweek', 'secondweek', 'thirdweek', 'fourthweek', 'fifthweek', 'sixthweek');
var c_arrWeekNamesAbrv = new Array('fsw', 'sdw', 'tdw', 'frw', 'ftw', 'sxw');
var c_arrDataHolidays = new Array();
var c_arrBankHolidays = new Array();
var c_arrpedt = new Array();
var c_arrchkdt = new Array();
var curyear = 0;
var pedt = new Date(); //pay end date in milliseconds
var datediff = 0; //difference between pay end date and check date in days
var ie4 = false;


function getposOffset2(what, offsettype) {
  var totaloffset=(offsettype=="left")? what.offsetLeft : what.offsetTop;
  var parentEl=what.offsetParent;
  while (parentEl!=null){
    totaloffset=(offsettype=="left")? totaloffset+parentEl.offsetLeft : totaloffset+parentEl.offsetTop;
    parentEl=parentEl.offsetParent;
  }
  return totaloffset;
}

function clearbrowseredge2(obj, whichedge, dropmenuobj){
  var edgeoffset=0
  if (whichedge=="rightedge"){
    var windowedge=ie4 && !window.opera? iecompattest().scrollLeft+iecompattest().clientWidth-15 : window.pageXOffset+window.innerWidth-15
    dropmenuobj.contentmeasure=dropmenuobj.offsetWidth
  if (windowedge-dropmenuobj.x < dropmenuobj.contentmeasure)
    edgeoffset=dropmenuobj.contentmeasure-obj.offsetWidth
  }else{
    var topedge=ie4 && !window.opera? iecompattest().scrollTop : window.pageYOffset
    var windowedge=ie4 && !window.opera? iecompattest().scrollTop+iecompattest().clientHeight-15 : window.pageYOffset+window.innerHeight-18
    dropmenuobj.contentmeasure=dropmenuobj.offsetHeight
    if (windowedge-dropmenuobj.y < dropmenuobj.contentmeasure){ 
      edgeoffset=dropmenuobj.contentmeasure+obj.offsetHeight
    if ((dropmenuobj.y-topedge)<dropmenuobj.contentmeasure) 
      edgeoffset=dropmenuobj.y+obj.offsetHeight-topedge
    }
  }
  return edgeoffset
}

/* THE FOLLOWING CODE IS REQUIRED FOR THE CALENDAR TO WORK */

var m_elemCalendar = null;
var m_elemTarget = null;
var m_elemFrame = null;
var m_elemContainer = null;
var m_ownerDocument = null;

function calShowCalendarFrame(elemCalendar, elemTarget, elemContainer, elemFrame, ownerDocument, frameTarget) {
  if (elemTarget.disabled || elemTarget.readOnly) {
    return;
  }

  elemFrame.x=getposOffset2(elemCalendar, "left");
  elemFrame.y=getposOffset2(elemCalendar, "top");
  elemFrame.style.left=elemFrame.x-clearbrowseredge2(elemCalendar, "rightedge", elemFrame)+2 + "px";
  elemFrame.style.top=elemFrame.y-clearbrowseredge2(elemCalendar, "bottomedge", elemFrame)+(elemCalendar.offsetHeight + 2) + "px";
  
  if (elemContainer.calWidth != null) {
    elemFrame.style.width = elemContainer.calWidth;
  }
  if (elemContainer.calHeight != null) {
    elemFrame.style.height = elemContainer.calHeight;
  }
  
  m_elemCalendar = elemCalendar;
  m_elemTarget = elemTarget;
  m_elemFrame = elemFrame;
  m_elemContainer = elemContainer;
  m_ownerDocument = ownerDocument;

  elemFrame.src = frameTarget;
}

/* END CALENDAR CODE */

function InitializeLeapYear(m_nYear) {
  var leapYear = false;
  if ((m_nYear % 4) == 0) {
    if (((m_nYear % 100) != 0) || ((m_nYear % 400) == 0)) {
      leapYear = true;
    }
  }

  if (leapYear == true) { c_arrMonthDays[1] = 29; } else { c_arrMonthDays[1] = 28; }
}

function fix2digityear(millidate){
  var tmpmillidate = new Date();
  var tmpyear = 0;
  tmpmillidate.setTime(millidate);
  tmpyear = tmpmillidate.getFullYear();
  if(tmpyear < 1940){    
    tmpmillidate.setFullYear((tmpyear + 100));
    return tmpmillidate.getTime();
  }
  return millidate;
}

function show_working(){
  document.getElementById('working').style.visibility = 'visible';
}

function hide_working(){
  document.getElementById('working').style.visibility = 'hidden';
}


function updateCal(){
  document.getElementById("calendar").innerHTML = "Generating Calendars";
  createCookie("freq", document.getElementById("optfreq").value, 365);
  createCookie("pedt", document.getElementById("txtpedt").value, 365);
  createCookie("chkdt", document.getElementById("txtchkdt").value, 365);
  isachkdt__startpos = 0;
  isapedt__startpos = 0;
  isadscholiday__startpos = 0;
  isabankholiday__startpos = 0;
  
  var freq = document.getElementById("optfreq").value;
  pedt = fix2digityear(Date.parse(document.getElementById("txtpedt").value));
  document.getElementById("txtpedtval").style.display = isNaN(pedt) ? "inline" : "none";
  var chkdt = fix2digityear(Date.parse(document.getElementById("txtchkdt").value));
  
  document.getElementById("txtchkdtval").style.display = isNaN(chkdt) ? "inline" : "none";
  datediff = Math.round((chkdt - pedt)/(1000 * 60 * 60 * 24));
  InitializeLeapYear(curyear);
  setupHolidays(curyear);
  
  if(!isNaN(chkdt) && !isNaN(pedt) && freq != ""){
    rollpedt(freq);
  }
  LoadCalendarYear(freq);
  hide_working();
}


function rollpedt(freq){
  var tmpthisyear = Date.parse("1/1/" + curyear);
  var tmpnextyear = Date.parse("1/1/" + (curyear + 1));
  var limit = 0;
  c_arrpedt = new Array();
  c_arrchkdt = new Array();
  
  while(limit < 5000 && (pedt < tmpnextyear || getcurchkdate(freq) < tmpnextyear)){//put a limit on this func
    if(pedt < tmpnextyear && pedt >= tmpthisyear){
      var tmpdate = new Date();
      tmpdate.setTime(pedt);
      c_arrpedt[c_arrpedt.length] = tmpdate;
    }
    if(getcurchkdate(freq) < tmpnextyear && getcurchkdate(freq) >= tmpthisyear){
      var tmpdate = new Date();
      tmpdate.setTime(getcurchkdate(freq));
      c_arrchkdt[c_arrchkdt.length] = tmpdate;
    }
    setnextpedate(freq);
    ++limit;
  }
  if(limit == 5000)
    alert("Please enter a valid 'Pay end date' and 'Check date'");
}

var isapedt__startpos = 0;
function isapedt(curday){
  var i;
  for(i=isapedt__startpos; i<c_arrpedt.length; ++i){
    if(c_arrpedt[i].getFullYear() == curday.getFullYear() && c_arrpedt[i].getMonth() == curday.getMonth() && c_arrpedt[i].getDate() == curday.getDate()){
      isapedt__startpos = i + 1;
      return true;
    }
  }
  return false;
}

var isachkdt__startpos = 0;
function isachkdt(curday){
  var i;
  for(i=isachkdt__startpos; i<c_arrchkdt.length; ++i){
    if(c_arrchkdt[i].getFullYear() == curday.getFullYear() && c_arrchkdt[i].getMonth() == curday.getMonth() && c_arrchkdt[i].getDate() == curday.getDate()){
      isachkdt__startpos = i + 1;
      return true;
    }
  }
  return false;
}

//advances to the next pay end date
//don't advance if the checkdate or pedt is after the curdate
function setnextpedate(freq){
  var myDate=new Date();
  myDate.setTime(pedt);
  if(freq == "weekly"){
    myDate.setDate(myDate.getDate()+7);
    pedt = myDate.getTime();//pedt += 7 * 1000 * 60 * 60 * 24;
  }else if(freq == "biweekly"){
    myDate.setDate(myDate.getDate()+14);
    pedt = myDate.getTime();//pedt += 14 * 1000 * 60 * 60 * 24;
  }else if(freq == "semimonthly"){
    if(getdayfrommilli(pedt) <= 10 || getdayfrommilli(pedt) >= 20 ){
      myDate.setDate(myDate.getDate()+15);
      pedt = myDate.getTime();//pedt += 15 * 1000 * 60 * 60 * 24;  
    }else{// += (LD - 15)
      myDate.setDate(myDate.getDate()+(c_arrMonthDays[getmofrommilli(pedt)] - 15)) ;
      pedt = myDate.getTime();//pedt += (c_arrMonthDays[getmofrommilli(pedt)] - 15) * 1000 * 60 * 60 * 24;  
    }
  }else if(freq == "monthly"){//28+ is LD else add month
    if(getdayfrommilli(pedt)>=28){
      var tmpdate = new Date();
      tmpdate.setTime(pedt);
      tmpdate.setMonth(tmpdate.getMonth() + 1);
      tmpdate.setDate(c_arrMonthDays[tmpdate.getMonth()]);
      pedt = tmpdate.getTime();
    }else{
      myDate.setDate(myDate.getDate()+c_arrMonthDays[getmofrommilli(pedt)]);
      pedt = myDate.getTime();//pedt += c_arrMonthDays[getmofrommilli(pedt)] * 1000 * 60 * 60 * 24;
    }
  }
}

//returns date in milli
function getcurchkdate(freq){
  var myDate = new Date();
  myDate.setTime(pedt);
  myDate.setDate(myDate.getDate() + datediff);
  var chkdtfrompedt = myDate.getTime();//  var chkdtfrompedt = pedt + (datediff * 1000 * 60 * 60 * 24);
  while(!validCheckDate(chkdtfrompedt)){
    myDate.setDate(myDate.getDate() - 1);
    chkdtfrompedt = myDate.getTime();//chkdtfrompedt -= 1000 * 60 * 60 * 24; //step back 1 day
  }
  return chkdtfrompedt;
}

//xdate is date in milli
function getmofrommilli(xdate){
  var tmpDate = new Date();
  tmpDate.setTime(xdate);
  return tmpDate.getMonth();
}

//xdate is date in milli
function getdayfrommilli(xdate){
  var tmpDate = new Date();
  tmpDate.setTime(xdate);
  return tmpDate.getDate();
}

function getyearfrommilli(xdate){
  var tmpDate = new Date();
  tmpDate.setTime(xdate);
  return tmpDate.getFullYear();
}

function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

function doCookieStuff(){
  if(readCookie("freq"))
    document.getElementById("optfreq").value = readCookie("freq");
  if(readCookie("pedt"))
    document.getElementById("txtpedt").value = readCookie("pedt");
  if(readCookie("chkdt"))
    document.getElementById("txtchkdt").value = readCookie("chkdt");
}

function LoadCalendar() {
  jQuery("input[type='text']").datepicker();
  doCookieStuff();
  curyear = (new Date()).getYear();
  if(curyear < 2000) { curyear = curyear + 1900; }
  updateCal();
}

function prevYear(){
  --curyear;
  updateCal();
}

function nextYear(){
  ++curyear;
  updateCal();
}

var isadscholiday__startpos = 0;
function DSCHoliday(curDay, quickver){
  var i;
  for(i=(quickver ? isadscholiday__startpos : 0); i<c_arrDataHolidays.length; i+=3){
    if(c_arrDataHolidays[i+1] == curDay.getMonth() && c_arrDataHolidays[i+2] == curDay.getDate()){
      holidayname = c_arrDataHolidays[i]
      if(quickver)
        isadscholiday__startpos = i + 3;
      return true;
    }      
  }
  return false;
}

var holidayname = "";
var isabankholiday__startpos = 0;
function BankHoliday(curDay, quickver){
  var i;
  for(i=(quickver ? isabankholiday__startpos : 0); i<c_arrBankHolidays.length; i+=3){
    if(c_arrBankHolidays[i+1] == curDay.getMonth() && c_arrBankHolidays[i+2] == curDay.getDate()){
      holidayname = c_arrBankHolidays[i]
      if(quickver)
        isabankholiday__startpos = i + 3;
      return true;
    }
  }
  return false;
}

function setupHolidays(year){
  var tmpDate = new Date();
  c_arrDataHolidays = new Array();
  c_arrBankHolidays = new Array();
  
  tmpDate.setFullYear(year, 0, 1);
  c_arrBankHolidays[c_arrBankHolidays.length] = "Martin Luther King, Jr. Day";
  c_arrBankHolidays[c_arrBankHolidays.length] = 0;
  c_arrBankHolidays[c_arrBankHolidays.length] = ((16 - tmpDate.getDay()) < 15 )? (16 - tmpDate.getDay()) + 7 : (16 - tmpDate.getDay()); //third monday in jan
  tmpDate.setFullYear(year, 1, 1);
  c_arrBankHolidays[c_arrBankHolidays.length] = "President's Day";
  c_arrBankHolidays[c_arrBankHolidays.length] = 1;
  c_arrBankHolidays[c_arrBankHolidays.length] = ((16 - tmpDate.getDay()) < 15 )? (16 - tmpDate.getDay()) + 7 : (16 - tmpDate.getDay()); //third monday in feb
  tmpDate.setFullYear(year, 9, 1);
  c_arrBankHolidays[c_arrBankHolidays.length] = "Columbus Day";
  c_arrBankHolidays[c_arrBankHolidays.length] = 9;
  c_arrBankHolidays[c_arrBankHolidays.length] = ((9 - tmpDate.getDay()) < 8 )? (9 - tmpDate.getDay()) + 7 : (9 - tmpDate.getDay()); //second monday in oct
  tmpDate.setFullYear(year, 10, 11);
  c_arrBankHolidays[c_arrBankHolidays.length] = "Veteran's Day";
  c_arrBankHolidays[c_arrBankHolidays.length] = 10;
  c_arrBankHolidays[c_arrBankHolidays.length] = (tmpDate.getDay() == 0) ? 12 : (tmpDate.getDay() == 6) ? 10 : 11; //nov 11 or nearest wkdy
  
  tmpDate.setFullYear(year, 0, 1);
  if(tmpDate.getDay() != 6){
    c_arrDataHolidays[c_arrDataHolidays.length] = "New Years";
    c_arrDataHolidays[c_arrDataHolidays.length] = 0;
    c_arrDataHolidays[c_arrDataHolidays.length] = (tmpDate.getDay() == 0) ? 2 : 1; 
  }
  tmpDate.setFullYear(year, 4, 31);
  c_arrDataHolidays[c_arrDataHolidays.length] = "Memorial Day";
  c_arrDataHolidays[c_arrDataHolidays.length] = 4;
  c_arrDataHolidays[c_arrDataHolidays.length] = (tmpDate.getDay() != 0) ? 31 - (tmpDate.getDay() - 1): 25; //last mon in may
  tmpDate.setFullYear(year, 6, 4);
  c_arrDataHolidays[c_arrDataHolidays.length] = "Independence Day";
  c_arrDataHolidays[c_arrDataHolidays.length] = 6;
  c_arrDataHolidays[c_arrDataHolidays.length] = (tmpDate.getDay() == 0) ? 5 : (tmpDate.getDay() == 6) ? 3 : 4; 
  tmpDate.setFullYear(year, 8, 1);
  c_arrDataHolidays[c_arrDataHolidays.length] = "Labor Day";
  c_arrDataHolidays[c_arrDataHolidays.length] = 8;
  c_arrDataHolidays[c_arrDataHolidays.length] = ((2 - tmpDate.getDay()) < 1 )? (2 - tmpDate.getDay()) + 7 : (2 - tmpDate.getDay()); //first monday in sep
  tmpDate.setFullYear(year, 10, 1);
  c_arrDataHolidays[c_arrDataHolidays.length] = "Thanksgiving";
  c_arrDataHolidays[c_arrDataHolidays.length] = 10;
  c_arrDataHolidays[c_arrDataHolidays.length] = ((26 - tmpDate.getDay()) < 22 )? (26 - tmpDate.getDay()) + 7 : (26 - tmpDate.getDay()); //first monday in sep
  tmpDate.setFullYear(year, 11, 25);
  c_arrDataHolidays[c_arrDataHolidays.length] = "Christmas";
  c_arrDataHolidays[c_arrDataHolidays.length] = 11;
  c_arrDataHolidays[c_arrDataHolidays.length] = (tmpDate.getDay() == 0) ? 26 : (tmpDate.getDay() == 6) ? 24 : 25; 
  tmpDate.setFullYear(year+1, 0, 1);
  if(tmpDate.getDay() == 6){
    c_arrDataHolidays[c_arrDataHolidays.length] = "New Years";
    c_arrDataHolidays[c_arrDataHolidays.length] = 11;
    c_arrDataHolidays[c_arrDataHolidays.length] = 31; 
  }
  
}

function LoadCalendarYear(freq){
  addCals();
  document.getElementById("prevyear").innerHTML = "&lt;-- " + (curyear-1);
  document.getElementById("curyear").innerHTML = (curyear);
  document.getElementById("nextyear").innerHTML = (curyear+1) + " --&gt;";
  for(mos=0; mos<12; ++mos){
    LoadCalendarMonth(mos, curyear, freq);
  }
}

//xdate is in milli
function validCheckDate(xdate){
  var tmpdate = new Date();
  var curMonth = getmofrommilli(xdate);
  var curDay = getdayfrommilli(xdate);
  tmpdate.setTime(xdate);
  
  return !(tmpdate.getDay() == 0 || tmpdate.getDay() == 6 || BankHoliday(tmpdate, false) || DSCHoliday(tmpdate, false))
}

function LoadCalendarMonth(month, year, freq){
  var tmpdate = new Date();
  tmpdate.setFullYear(year, month, 1);
  days = tmpdate.getDay();
  for(i=1; i<=days; ++i){
    document.getElementById(months[month] + i).className = "blankdays";
    document.getElementById(months[month] + i).innerHTML = "&nbsp;";
  }
  
  for(i=1; i<=c_arrMonthDays[month]; ++i){
    var holidaytext = "";
    var alttext = "";
    var curday = new Date();
    curday.setFullYear(year, month, i);
    ++days;
    var cell = document.getElementById(months[month] + days);
    cell.innerHTML = "" + i;
    cell.className += " activeday";
    if(BankHoliday(curday, true)){
      cell.title = holidayname;
      cell.className += " holiday";
      holidaytext = c_arrMonthNames[month] + " " + i + " is a bank holiday";
    }else if(DSCHoliday(curday, true)){
      cell.title = holidayname;
      cell.className += " dscday";
      holidaytext = c_arrMonthNames[month] + " " + i + " is a bank and DSC holiday";
    }
    if(freq != "" && isapedt(curday)){
      cell.className += " pedate";
      alttext = (holidaytext.length == 0)? c_arrMonthNames[month] + " " + i + " is a pay ending date." : holidaytext + ", and a pay ending date.";
      cell.innerHTML = "<img src='/site/images/pedate.gif' alt='" + alttext + "' />";
    }
    if(freq != "" && isachkdt(curday)){
      cell.className += " chkdate";
      alttext = (holidaytext.length == 0)? c_arrMonthNames[month] + " " + i + " is a check date." : holidaytext + ", and a check date.";
      cell.innerHTML = "<img src='/site/images/chkdate.gif' alt='" + alttext + "' />";
    }
    
    if(cell.className.indexOf("chkdate") > -1 && cell.className.indexOf("pedate") > -1){
      cell.className += " chkdtpedt";
      cell.innerHTML = "<img src='/site/images/chkpedate.gif' alt='" + c_arrMonthNames[month] + " " + i + " is a pay ending date and a check date.' />";
    }
    
    tmpdate.setFullYear(year, month, i);
  }
  
  blankrow = false;
    
  for(i=days+1; i<=42; ++i){
    if(!blankrow && (i == 29 || i ==36))
      blankrow = true;
    if(blankrow && i == 29)
      document.getElementById(months[month] + "ftw").style.display = "none";
    if(blankrow && i == 36)
      document.getElementById(months[month] + "sxw").style.display = "none";
    document.getElementById(months[month] + i).className = (blankrow) ? "blankrow" : "blankdays";  
    document.getElementById(months[month] + i).innerHTML = "&nbsp;";
  }
}

function addCals(){
  var c_arrWeekDayNames = new Array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat');
  var c_arrWeekDayNamesAbrv = new Array('S', 'M', 'T', 'W', 'T', 'F', 'S');
  calDiv = document.getElementById("calendar");
  tmpstr = ""
  for(i=0; i<12; ++i){
    tmpstr += '<div class="monthbox"><div class="month" id="' + months[i] + '">';
    tmpstr += '<div class="monthtitle">' + c_arrMonthNames[i] + '</div>';
    tmpstr += '<table class="daystable" cellspacing="0" >';
    tmpstr += '<tr class="dayheader">';
    for(j=0; j<7; ++j){
      tmpstr += '<th class="' + months[i] + ' dayheader">' + c_arrWeekDayNamesAbrv[j] + '</th>';
    }
    tmpstr += '</tr>';    
    boxcount = 1;
    for(j=0; j<6; ++j){
      tmpstr += '<tr class="' + c_arrWeekNames[j] + '" id="' + months[i] + c_arrWeekNamesAbrv[j] + '">';
      for(k=0; k<7; ++k){
        tmpstr += '<td class="' + months[i] + ' ' + c_arrWeekDayNames[k] + '" id="' + months[i] + boxcount + '">&nbsp;</td>';
        ++boxcount;
      }
      tmpstr += '</tr>';
    }
    tmpstr += '</table></div></div>';
  }
  calDiv.innerHTML = tmpstr;
}
