//////////////////////////////////////////////////////////////////
// Anuko Software Ltd. Confidential Property
// Copyright 2009, Anuko Software Ltd. 
//
// FileName:   calendar.js
//
//////////////////////////////////////////////////////////////////
// Description: Calendar widget version 0.8
//
//////////////////////////////////////////////////////////////////
// Creation Date:     2009-04-25
//
// Revision history:
//
//   Date        Author         Description
// 2009-04-25    A. Guts        initial version
// 2009-05-14    A. Guts        added time formatters
//
//////////////////////////////////////////////////////////////////

function wrcCalendarShiftDate(date, days) {
  date.setTime( date.getTime() + days*86400000);
}

function wrcCalendar(date, varRef) {
  this.date = new Date(date);
  this.today = new Date();
  this.varRef = varRef;      // this instance variable reference
  this.container = null;     // HTML container object for the calendar, for example div
  this.dayNames = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
  this.monthNames = ['January','February','March','April','May','June','July','August','September','October','November','December'];

  this.attrs = new Object();
  this.attrs.table = 'style="border: 2px solid gray" cellpadding="3" cellspacing="1" ';    // calendar table attributes

  this.attrs.sunday = 'style="color: red"';

  this.attrs.day = 'style="border: 1px solid gray; font-style: italic" ';
  this.attrs.listedDay = 'style="border: 1px solid gray; font-weight: bold"';
  this.attrs.today = 'style="border: 1px solid red"';
  this.attrs.empty = 'style="border: 1px solid #e0e0e0"';

  this.attrs.todayLink = 'style="color: red; font-weight: bold"';

  // Calendar arrows, HTML
  this.prevYSign = '&#171;&nbsp;';
  this.nextYSign = '&nbsp;&#187;';
  this.prevMSign = '&nbsp;&#8249;';
  this.nextMSign = '&#8250;&nbsp;';
 
  this.listedDates = null; // array of special dates
  // Day cell URL (use %dd %MMM %yyyy, etc. as the formatters for respective fields);
  this.dayLink = null;
  this.listedDayLink = null;
  this.todayLink = null;
  this.todayWordLink = null;

  // Methods
  this.render = wrcCalendarRender;
  this.renderTable = wrcCalendarRenderTable; 
  this.formatLink = wrcCalendarFmtLink;
  this.scroll = wrcCalendarScroll;
  this.reset = wrcCalendarReset;
  this.setDatesList = wrcCalendarSetDatesList;
}

function wrcCalendarScroll(months) {
  while (months > 0) {
    var m = this.date.getMonth();
    if (m < 11) this.date.setMonth(m+1);
    else { this.date.setMonth(0); this.date.setFullYear(this.date.getFullYear()+1); }
    months--;
  }
  while (months < 0) {
    var m = this.date.getMonth();
    if (m > 0) this.date.setMonth(m-1);
    else { this.date.setMonth(11); this.date.setFullYear(this.date.getFullYear()-1); }
    months++;
  }
  if (this.container == null) return false;
  this.container.innerHTML = this.render();
  return false;
}

function wrcInt2Str(val, digits) {
  var s = String(val);
  if (val >= 0)
    while (s.length < digits) s = '0'+s;
  else
    while (s.length < digits+1) s = '-0'+s.slice(1);
  return s;
}

function wrcCalendarFormat(str, day) {
  var s = str.replace(/%dd/, wrcInt2Str(day.getDate(), 2));
  s = s.replace(/%MM/, wrcInt2Str(day.getMonth()+1, 2));
  s = s.replace(/%yyyy/, wrcInt2Str(day.getFullYear(), 4));
  s = s.replace(/%HH/, wrcInt2Str(day.getHours(), 2));
  s = s.replace(/%mm/, wrcInt2Str(day.getMinutes(), 2));
  s = s.replace(/%ss/, wrcInt2Str(day.getSeconds(), 2));
  return s;
}

function wrcCalendarReset() {
  this.date.setTime(this.today.getTime());
  if (this.container == null) return false;
  this.container.innerHTML = this.render();
  return false;
}

function wrcCalendarDatesEqual(d1, d2) {
  return d1.getDate() == d2.getDate() && d1.getMonth() == d2.getMonth() && d1.getFullYear() == d2.getFullYear();
}

function wrcCalendarDateListed(date, dates) {
  if (dates == null) return null;
  for (var i = 0; i < dates.length; i++)
    if (wrcCalendarDatesEqual(dates[i], date)) return dates[i];
  return null;
}

function wrcCalendarFmtLink(link, day, isToday, isListed) {
  var s = '';
  var fmt = null;
  var attrs = '';
  if (isToday && this.todayLink != null) {
    fmt = this.todayLink; attrs = this.attrs.todayLink;
  } else 
  if (isListed && this.listedDayLink != null) fmt = this.listedDayLink; else 
  if (this.dayLink != null) fmt = this.dayLink; 

  if (fmt != null) {
    var s = wrcCalendarFormat(fmt, day);
    s = '<a '+attrs+' href="'+s+'">'+link+'</a>';
    return s;
  } else 
   return link;
}

function wrcCalendarRenderTable() {
  var m = this.date.getMonth();
  var d = new Date(this.date.getTime());
  var today = false;
  wrcCalendarShiftDate(d, 1-d.getDate());
  wrcCalendarShiftDate(d, -d.getDay());

  // Navidation and today link
  var s = '<tr><th><a title="Previous year" style="text-decoration: none" href="" '+
    'onclick="return '+this.varRef+'.scroll(-12)">'+this.prevYSign+'</a>'+
    '</th><th><a title="Previous month" style="text-decoration: none" href="" '+
    'onclick="return '+this.varRef+'.scroll(-1)">'+this.prevMSign+'</a></th><th colspan="3">'+
    '<a title="'+this.monthNames[this.today.getMonth()]+
    ' '+this.today.getDate()+', '+this.today.getFullYear()+'" ';

  if (this.todayWordLink != null) {
    var l = wrcCalendarFormat(this.todayWordLink, this.today);
    s = s+'href="'+l+'"';
  } else 
    s = s+'href="" onclick="return '+this.varRef+'.reset()"';
  s = s +'>Today'+'</a></th>'+
    '<th><a title="Next month" style="text-decoration: none" href=""'+
    'onclick="return '+this.varRef+'.scroll(1)">'+this.nextMSign+'</a>'+
    '</th><th><a title="Next year" style="text-decoration: none" href=""'+
    'onclick="return '+this.varRef+'.scroll(12)">'+this.nextYSign+'</a></th></tr>\r\n';

  // Day names
  s = s+'<tr><th '+this.attrs.sunday+'>'+this.dayNames[0]+'</th>';
  for (var i= 1; i < 7; i++) s = s+'<th>'+this.dayNames[i]+'</th>';
  s = s+'</tr>';

  for (var r = 0; r < 6; r++) {
    s = s+'<tr>';
    for (var c = 0; c < 7; c++) {
      if (d.getMonth() == m) {
         today = wrcCalendarDatesEqual(d, this.today);
         var dl = wrcCalendarDateListed(d, this.listedDates)
         if (dl != null)
           s = s+'<td '+(today ? this.attrs.today : this.attrs.listedDay)+' align="center">'+
               this.formatLink(d.getDate(), dl, today, true)+'</td>';
         else
           s = s+'<td '+(today ? this.attrs.today : this.attrs.day)+' align="center">'+
               this.formatLink(d.getDate(), d, today, false)+'</td>';
      } else
         s = s+'<td '+this.attrs.empty+'>&nbsp;</td>';
      wrcCalendarShiftDate(d, 1);
    }
    s = s+'</tr>\r\n';
  }

  return s;
}

function wrcCalendarRender() {
  var s = '<table '+this.attrs.table+'>'+
    '<colgroup><col width="15%"><col width="14%"><col width="14%"><col width="14%">'+
    '<col width="14%"><col width="14%"><col width="15%"></colgroup>\r\n'+
    '<tr><th colspan="7">'+
    this.monthNames[this.date.getMonth()]+' '+this.date.getFullYear()+'</th></tr>\r\n';
  s = s+this.renderTable()+'</table>\r\n';
  return s;
}

function wrcCalendarSetDatesList(dateList) {
  if (dateList == null) { this.listedDates = null; return; }
  this.listedDates = new Array();
  for (var i = 0; i < dateList.length; i++) this.listedDates[i] = new Date(dateList[i]);
}

