var now = new Date();
var RDate_defaultStringFormat="%#m/%#d/%Y";
var RDate_defaultParseFormat="%#m %#d, %Y";
var RDate_currentYear=now.getFullYear()	;
var RDate_currentMonth=now.getMonth()+1;
var RDate_currentDay=now.getDay();


/*****
  RDate
*****/
function RDate(day,month,year)
{
  // Initialize properties
  this.day=null;
  this.month=null;
  this.year=null;
  this.stringFormat=new String(RDate_defaultStringFormat);

  // Initialize methods
  this.copy=RDate_copy;
  this.set=RDate_set;
  this.setNull=RDate_setNull;
  this.isNull=RDate_isNull;
  this.getAbsoluteDay=RDate_getAbsoluteDay;
  this.getDaysInMonth=RDate_getDaysInMonth;
  this.getDayOfWeek=RDate_getDayOfWeek;
  this.getDayOfWeekName=RDate_getDayOfWeekName;
  this.getDay=RDate_getDay;
  this.getMonth=RDate_getMonth;
  this.getYear=RDate_getYear;
  this.difference=RDate_difference;
  this.compare=RDate_compare;
  this.compareRDates=RDate_compareRDates;
  this.getMonthName=RDate_getMonthName;
  this.setStringFormat=RDate_setStringFormat;
  this.parse=RDate_parse;
  this.parseWithFormat=RDate_parseWithFormat;
  this.getString=RDate_getString;
  this.getStringWithFormat=RDate_getStringWithFormat;
  this.clientNow=RDate_clientNow;

  this.set(day,month,year);
}
function RDate_copy()
{
  var d=new RDate(this.day,this.month,this.year);
  return d;
}
function RDate_getAbsoluteDay()
{
  var totalDays=this.year*365+((this.year-1)>>2)+this.day;
  for (i=this.month-1;i>=1;i--)
    totalDays+=RDate_monthDays[i-1];
  if (this.year%4==0 && this.month>2)
    totalDays++;
  return totalDays;
}
function RDate_getDaysInMonth()
{
  var days=RDate_monthDays[this.month-1];
  if (this.month==2 && this.year%4==0)
    days++;
  return days;
}
function RDate_getDayOfWeek()
{
  return (this.getAbsoluteDay()+5)%7;
}
function RDate_getDayOfWeekName()
{
  return RDate_dayOfWeekList[this.getDayOfWeek()];
}
function RDate_getDay()
{
  return this.day;
}
function RDate_getMonth()
{
  return this.month;
}
function RDate_getYear()
{
  return this.year;
}
function RDate_difference(d)
{
  return this.getAbsoluteDay()-d.getAbsoluteDay();
}
function RDate_set(day,month,year)
{
  if (month!=null)
  {
    this.day=day;
    this.month=month;
    this.year=year;
  }
  else if (day!=null)
    this.parse(day);
}
function RDate_setNull()
{
  this.day=null;
}
function RDate_isNull()
{
  return (this.day==null);
}
function RDate_compare(a)
{
  if (this.year<a.year)
    return -1;
  if (this.year>a.year)
    return 1;
  if (this.month<a.month)
    return -1;
  if (this.month>a.month)
    return 1;
  if (this.day<a.day)
    return -1;
  if (this.day>a.day)
    return 1;
  return 0;
}
function RDate_compareRDates(a,b)
{
  if (a.year<b.year)
    return -1;
  if (a.year>b.year)
    return 1;
  if (a.month<b.month)
    return -1;
  if (a.month>b.month)
    return 1;
  if (a.day<b.day)
    return -1;
  if (a.day>b.day)
    return 1;
  return 0;
}
function RDate_getMonthName()
{
  return RDate_monthList[this.month-1];
}
function RDate_setMonthNameList(m)
{
  RDate_monthList=m;
}
function RDate_getMonthNameList()
{
  return RDate_monthList;
}
function RDate_setParseFormatList(l)
{
  RDate_parseFormatList=l;
  RDate_createMonthParseList();
}
function RDate_getParseFormatList()
{
  return RDate_parseFormatList;
}
function RDate_setStringFormat(f)
{
  this.stringFormat=f;
}
var RDate_monthList=new Array('January','February','March','April','May','June','July','August','September','October','November','December');
var RDate_monthParseList=new Array();
var RDate_dayOfWeekList=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
var RDate_monthDays=new Array(31,28,31,30,31,30,31,31,30,31,30,31);
var RDate_defaultParseFormatList=new Array("%b %d %y","%b %y %d","%d %b %y","%m %d %y","%y %m %d","%y %b %d","%b %d","%m %d","%d %b","%d %m","%d");
var RDate_parseFormatList=new Array();
var RDate_defaultParseFormat;

function RDate_setDefaultParseFormat(parseFormat)
{
  function dateFormat(l)
  {
    for (var o="",i=0;i<l.length;i++)
    {
      if (i>0)
        o+=' ';
      o+='%'+l.charAt(i);
    }
    return o;
  }
  function replace(s,a,b){var i=s.indexOf(a);return (i<0?s:s.substring(0,i)+b+s.substring(i+a.length,s.length));}
  var l=new Array();
  var s=parseFormat.toLowerCase();
  var f="";
  for (var i=0;i<s.length;i++)
  {
    var c="";
    for (;i<s.length;i++)
      if (s.charAt(i)=='%')
        break;
    for (i++;i<s.length;i++)
    {
      c=s.charAt(i);
      if (c=='b' || c=='m' || c=='d' || c=='y')
        break;
    }
    if (i<s.length)
      f+=c;
  }
  var a=f;
  if ((i=a.indexOf("b"))>=0)
    a=replace(a,"b","m");
  else if ((i=a.indexOf("m"))>=0)
    a=replace(a,"m","b");
  l[l.length]=dateFormat(f);
  l[l.length]=dateFormat(a);
  f=replace(f,"y","");
  a=replace(a,"y","");
  l[l.length]=dateFormat(f);
  l[l.length]=dateFormat(a);
  for (var i=0;i<RDate_defaultParseFormatList.length;i++)
    l[l.length]=RDate_defaultParseFormatList[i];
  RDate_setParseFormatList(l);
}
function RDate_setDefaultStringFormat(format) {RDate_defaultStringFormat=format;}

if (RDate_defaultParseFormat)
  RDate_setDefaultParseFormat(RDate_defaultParseFormat);

function RDate_createMonthParseList()
{
  var monthParseList=RDate_monthParseList;
  var monthList=RDate_monthList;
  monthParseList.length=0;
  for (var i=0;i<monthList.length;i++)
  {
    var month=monthList[i];
    for (var j=1;j<month.length;j++)
    {
      var minMonth=month.substring(0,j);
      for (var k=0;k<monthList.length;k++)
        if (k!=i)
          if (monthList[k].substring(0,j)==minMonth)
            break;
      if (k==monthList.length)
        break;
    }
    monthParseList[i]=month.substring(0,j).toLowerCase();
  }
}
function RDate_parse(s)
{
  for (var i=0;i<RDate_parseFormatList.length;i++)
    if (this.parseWithFormat(s,RDate_parseFormatList[i]))
      break;
  if (i==RDate_parseFormatList.length)
    this.setNull();
}
function RDate_parseWithFormat(s,f)
{
  var error=false;
  var c;
  var day=0,month=RDate_currentMonth,year=RDate_currentYear;
  var i=0;
  for (var fi=0;fi<f.length;fi++)
  {
    for (;i<s.length;i++)
    {
      c=s.charAt(i);
      if ((c>='0'&&c<='9')||(c>='A'&&c<='Z')||(c>='a'&&c<='z'))
        break;
    }
    c=f.charAt(fi);
    if (!((c>='0'&&c<='9')||(c>='A'&&c<='Z')||(c>='a'&&c<='z')||(c=='%')))
      continue;
    if (c=='%')
    {
      fi++;
      if (fi==f.length)
      {
        error=true;
        break;
      }
      c=f.charAt(fi);
      switch (c)
      {
        case 'd':
        {
          day=0;
          for (;i<s.length;i++)
          {
            c=s.charAt(i);
            if (c>='0'&&c<='9')
              day=day*10+s.charCodeAt(i)-String('0').charCodeAt(0);
            else
              break;
          }
          break;
        }
        case 'm':
        {
          var month=0;
          for (;i<s.length;i++)
          {
            c=s.charAt(i);
            if (c>='0'&&c<='9')
              month=month*10+s.charCodeAt(i)-String('0').charCodeAt(0);
            else
              break;
          }
          break;
        }
        case 'y':
        case 'Y':
        {
          var year=null;
          for (;i<s.length;i++)
          {
            c=s.charAt(i);
            if (c>='0'&&c<='9')
              year=year*10+s.charCodeAt(i)-String('0').charCodeAt(0);
            else
              break;
          }
          if (year!=null)
            if (year<100)
            {
              year+=1900;
              if (year<1980)
                year+=100;
            }
          break;
        }
        case 'b':
        case 'B':
        {
          var monthName="";
          for (;i<s.length;i++)
          {
            c=s.charAt(i);
            if ((c>='A'&&c<='Z')||(c>='a'&&c<='z'))
              monthName+=c;
            else
              break;
          }
          month=0;
          for (var j=0;j<RDate_monthParseList.length;j++)
            if (RDate_monthParseList[j]==monthName.toLowerCase().substring(0,RDate_monthParseList[j].length))
              month=j+1;
          break;
        }
      }
    }
  }
  var maxDays=0;
  if (month<1 || month>RDate_monthList.length)
    error=true;
  else
    maxDays=RDate_monthDays[month-1];
  if (month==2)
    if (year%4==0)
      maxDays++;
  if (day<1 || day>maxDays)
    error=true;
  if (year<1980 || year>2079 || year==null)
    error=true;
  if (!error)
  {
    this.day=day;
    this.month=month;
    this.year=year;
  }
  return !error;
}
function RDate_getString()
{
  return this.getStringWithFormat(this.stringFormat);
}
function RDate_getStringWithFormat(f)
{
  var s="";
  if (!this.day)
    return s;
  for (var i=0;i<f.length;i++)
  {
    var c=f.charAt(i);
    if (c=='%')
    {
      i++;
      if (i==f.length)
        break;
      c=f.charAt(i);
      var z=true;
      if (c=='#')
      {
        i++;
        if (i==f.length)
          break;
        c=f.charAt(i);
        z=false;
      }
      switch(c)
      {
        case 'y':
          var smallY=this.year%100;
          if (smallY<10)
            s+='0';
          s+=smallY;
          break;
        case 'Y':
          s+=this.year;
          break;
        case 'm':
          if (z&&this.month<10)
            s+='0';
          s+=this.month;
          break;
        case 'b':
          s+=this.getMonthName().substring(0,3);
          break;
        case 'B':
          s+=this.getMonthName();
          break;
        case 'd':
          if (z&&this.day<10)
            s+='0';
          s+=this.day;
          break;
        case 'w':
          s+=this.getDayOfWeek();
          break;
        case 'A':
          s+=this.getDayOfWeekName();
          break;
      }
    }
    else
      s+=c;
  }
  return s;
}
function RDate_clientNow()
{
  var d=new Date();
  this.set(d.getDate(),d.getMonth()+1,d.getFullYear());
  return this;
}



/*****
  RDateRange
*****/
function RDateRange(startDate,endDate)
{
  // Initialize properties
  this.startDate=startDate.copy();
  this.endDate=endDate.copy();

  // Initialize methods
  this.copy=RDateRange_copy;
  this.getStartDate=RDateRange_getStartDate;
  this.getEndDate=RDateRange_getEndDate;
  this.setStartDate=RDateRange_setStartDate;
  this.setEndDate=RDateRange_setEndDate;
  this.setStartDateAndEndDate=RDateRange_setStartDateAndEndDate;
  this.within=RDateRange_within;
}
function RDateRange_copy()
{
  return new RDateRange(this.startDate,this.endDate);
}
function RDateRange_setStartDateAndEndDate(startDate,endDate)
{
  this.startDate=startDate.copy();
  this.endDate=endDate.copy();
}
function RDateRange_setStartDate(startDate)
{
  this.startDate=startDate.copy();
}
function RDateRange_setEndDate(endDate)
{
  this.endDate=endDate.copy();
}
function RDateRange_within(checkDate)
{
  return (checkDate.compare(this.startDate)>=0 && checkDate.compare(this.endDate)<=0)
}
function RDateRange_getStartDate()
{
  return this.startDate;
}
function RDateRange_getEndDate()
{
  return this.endDate;
}



/*****
  RDateRangeList
*****/
function RDateRangeList()
{
  // Initialize properties
  this.startDate=new Array();
  this.endDate=new Array();

  // Initialize methods
  this.copy=RDateRangeList_copy;
  this.clear=RDateRangeList_clear;
  this.add=RDateRangeList_add;
  this.within=RDateRangeList_within;
  this.getListLength=RDateRangeList_getListLength;
  this.getDateRange=RDateRangeList_getDateRange;
  this.getStartDate=RDateRangeList_getStartDate;
  this.getEndDate=RDateRangeList_getEndDate;
  this.overlaps=RDateRangeList_overlaps;
  
  for (var i=0;i<RDateRangeList.arguments.length;i++)
    if (RDateRangeList.arguments[i])
      this.add(RDateRangeList.arguments[i]);
}
function RDateRangeList_copy()
{
  var d=new RDateRangeList();
  var i;
  for (i=0;i<this.startDate.length;i++)
  {
    d.startDate[i]=this.startDate[i].copy();
    d.endDate[i]=this.endDate[i].copy();
  }
  return d;
}
function RDateRangeList_clear()
{
  this.startDate.length=0;
  this.endDate.length=0;
}
function RDateRangeList_add(dateRange)
{
  var i=this.startDate.length;
  this.startDate[i]=dateRange.getStartDate().copy();
  this.endDate[i]=dateRange.getEndDate().copy();
}
function RDateRangeList_within(checkDate)
{
  for (var i=0;i<this.startDate.length;i++)
    if (checkDate.compare(this.startDate[i])>=0 && checkDate.compare(this.endDate[i])<=0)
      return true;
  return false;
}
function RDateRangeList_getListLength()
{
  return this.startDate.length;
}
function RDateRangeList_getDateRange(i)
{
  return new RDateRange(this.startDate[i],this.endDate[i]);
}
function RDateRangeList_getStartDate(i)
{
  return this.startDate[i];
}
function RDateRangeList_getEndDate(i)
{
  return this.endDate[i];
}
function RDateRangeList_overlaps(dateRange)
{
  for (var i=0;i<this.startDate.length;i++)
    if (dateRange.getStartDate().compare(this.endDate[i])<=0 && dateRange.getEndDate().compare(this.startDate[i])>=0)
      return true;
  return false;
}
