/*
  -------------------------------------------------------------------------------------------------

  : popframecalendar.js
  : ben miller : ben@hyl.co.uk : http://digital.hyl.co.uk
  : 06 July 2005

  - many thanks to Matt Kruse <http://www.mattkruse.com> for the disabled dates idea.

  - requires:

  utils.js
  popframe.js
  datedropdown_client.js

  -------------------------------------------------------------------------------------------------
*/

/*
  -- Calendar Collection methods ------------------------------------------------------------------
*/
var __aPFCalendars = [];

function __initPFCalendars()
{
  for(var i=0;i<__aPFCalendars.length;i++)
  {
    __aPFCalendars[i].Load();
  }
}

AEL(window, 'load', __initPFCalendars, false);

/*
  returns calendar with id of parameter _id
*/
function __getPFCalendar(_id)
{
  for(var i=0;i<__aPFCalendars.length;i++)
  {
    if(__aPFCalendars[i].id == _id)
    {
      return __aPFCalendars[i];
    }
  }
  return false;
}

/*
  - loops through calendar collection hiding each one
*/
function __hidePFCalendars()
{
  for(var i=0;i<__aPFCalendars.length;i++)
  {
    if((arguments.length>0) && (parseInt(arguments[0])==i)) { continue; }
    __aPFCalendars[i].Hide();
  }
}

AEL(document, 'click', __hidePFCalendars, false);

/*
  -- Calendar Constructor inherits popframe -------------------------------------------------------
*/
PFCalendar.prototype = new PopFrame();
PFCalendar.prototype.constructor = PFCalendar;
PFCalendar.baseClass = PopFrame.prototype;

function PFCalendar(_id)
{
  if(arguments.length>0){ this.Init(_id); }
}

//
// initialise
//
PFCalendar.prototype.Init = function(_id)
{
  PFCalendar.baseClass.Init.call(this, _id);

  this.index = __aPFCalendars.length;
  __aPFCalendars.push(this);
  this.id = _id;

  this.ctrlID;
  this.fpat;
  this.fmID;
  this.date;
  this.getSelectedDate = function(){ return parent.__DDDGetDate(this.fpat, this.ctrlID, document.forms[this.fmID]) || new Date(); }
  this.wkStDy = 0;
  this.disabledDatesExpr = '';
  this.stylesheet = '@import \'/hyl_client/pfcal_style.css\';';
}

//
// called after page load
//
PFCalendar.prototype.Load = function()
{
  this.relPos = this.relPos || 'btrr';
  this.shuntX = this.shuntX || 1;
  this.shuntY = this.shuntY || 0;
  this.width  = this.width  || '150px';
  this.height = this.height || '150px';

  PFCalendar.baseClass.Load.call(this);
}

//
// refresh contents
//
PFCalendar.prototype.Refresh = function(_date)
{

  this.date = _date;
  this.Build();
  PFCalendar.baseClass.Update.call(this);
}

//
// build contents
//
PFCalendar.prototype.Build = function()
{
  var d = this.date;
  var dy = d.getDate();
  var mn = d.getMonth();
  var yr = d.getFullYear();

  var aDys   = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
  var aMnths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
  var aDysInMnth = [31,(((yr%4==0)&&(yr%100!=0))||(yr%400==0))?29:28,31,30,31,30,31,31,30,31,30,31];

  var prvMn = mn-1;
  var nxtMn = mn+1;
  var prvYr = yr; if(prvMn<0){ prvYr--; prvMn = 11; }
  var nxtYr = yr; if(nxtMn>11){ nxtYr++; nxtMn = 0; }

  var calDy = 1;
  var calMn = mn;
  var calYr = yr;
  var calWkDy = new Date(yr, mn, 1).getDay();
  var dyOffset = (calWkDy>=this.wkStDy)?calWkDy-this.wkStDy:7-this.wkStDy+calWkDy;

  var selDate = this.getSelectedDate();

  var sCalObj = 'parent.__getPFCalendar(\''+ this.id +'\')';
  var sRetFnc = 'parent.__DDDSetDate([\''+ this.fpat.join('\',\'') + '\'], \''+ this.ctrlID +'\', parent.document.forms[\''+ this.fmID + '\'], ';

  if(dyOffset > 0)
  {
    calMn--;
    if(calMn < 0) { calMn = 11; calYr--; }
    calDy = aDysInMnth[calMn] - dyOffset + 1;
  }

  var aRtn = [];
  aRtn.push('<div id="calBody">');

  // month year header
  aRtn.push('<div id="calMnthYrNav"><table border="0" cellpadding="0" cellspacing="0" width="100%">');
  aRtn.push('<tr><td align="left"><span onclick="', sCalObj, '.Refresh(new Date(', prvYr, ',', prvMn, ',', dy, '));" ');
  aRtn.push('class="calMnthNav" title="', aMnths[prvMn], ' ', prvYr, '">&lt;&lt;</span></td>');
  aRtn.push('<td align="center">', aMnths[mn], ' ', yr, '</td>');
  aRtn.push('<td align="right"><span onclick="', sCalObj, '.Refresh(new Date(', nxtYr, ',', nxtMn, ',', dy, '));" class="calMnthNav" ');
  aRtn.push('title="', aMnths[nxtMn], ' ', nxtYr, '">&gt;&gt;</span></td></tr>');
  aRtn.push('</table></div>');

  // week day column header
  aRtn.push('<div id="calWeekDay"><table border="0" cellpadding="0" cellspacing="0" width="100%">');
  aRtn.push('<tr>');
  for(var i=0;i<7;i++)
  {
    aRtn.push('<td title="', aDys[(this.wkStDy+i)%7], '">', aDys[(this.wkStDy+i)%7].substr(0,1), '</td>');
  }
  aRtn.push('</tr>');
  aRtn.push('</table></div>');

  // calendar
  aRtn.push('<div id="calCalendar"><table border="0" cellpadding="0" cellspacing="0" width="100%">');
  for(var row=0;row<6;row++)
  {
    aRtn.push('<tr>');
    for(var col=0;col<7;col++)
    {
      var bDisabled = false;

      if(this.disabledDatesExpr!='')
      {
        var ds = '' + calYr + LZ(calMn + 1) + LZ(calDy);
        eval('bDisabled = ('+ this.disabledDatesExpr +')');
      }

      var calDate = new Date(calYr, calMn, calDy);

      var sDayCellCss = 'calDayCellNormal';

      if(calMn<mn)
      {
        sDayCellCss = 'calDayCellPrvMonth';
      }
      else if(calMn>mn)
      {
        sDayCellCss = 'calDayCellNxtMonth';
      }

      if((calDate.getDay()==6)||(calDate.getDay()==0))
      {
        sDayCellCss += ' calDayCellWeekend';
      }

      if((calYr==selDate.getFullYear())&&(calMn==selDate.getMonth())&&(calDy==selDate.getDate()))
      {
        sDayCellCss = 'calDayCellSelected';
      }

      if(bDisabled)
      {
        aRtn.push('<td class="', sDayCellCss, 'Dsbl">', calDy, '</td>');
      }
      else
      {
        aRtn.push('<td class="', sDayCellCss, '">');
        aRtn.push('<span onclick="', sRetFnc, 'new Date(', calYr, ', ', calMn, ', ', calDy, '));');
        aRtn.push(sCalObj +'.Hide();">'+ calDy +'</span></td>');
      }

      calDy++;
      if(calDy > aDysInMnth[calMn]) { calDy=1; calMn++; }
      if(calMn > 11) { calMn=0; calYr++; }
    }
    aRtn.push('</tr>');
  }

  aRtn.push('</table></div>');

  var dToday = new Date();
  bDisabled = false;
  if(this.disabledDatesExpr!='')
  {
    var ds = '' + dToday.getFullYear() + LZ(dToday.getMonth() + 1) + LZ(dToday.getDate());
    eval('bDisabled = ('+ this.disabledDatesExpr +')');
  }
  if(!bDisabled)
  {
    var sToday = aDys[dToday.getDay()] + ' ' + dToday.getDate() + ' ' + aMnths[dToday.getMonth()] + ' ' + dToday.getFullYear();
    aRtn.push('<div id="calFoot">');
    aRtn.push('<span onclick="', sRetFnc, 'new Date());', sCalObj, '.Hide();" title="', sToday, '">today</span>');
    aRtn.push('</div>');
  }

  aRtn.push('</div>');

  this.content = aRtn.join('');
}

//
// toggle visiblility
//
PFCalendar.prototype.ToggleVisibility = function(sender, ev)
{
  PFCalendar.baseClass.ToggleVisibility.call(this, sender, ev);

  this.Refresh(this.getSelectedDate());

  __hidePFCalendars(this.index);
}

//
// set disabled dates
//
PFCalendar.prototype.SetDisabledDate = function(start, end)
{
  if(arguments.length==1) { end = start; }
  if(start==null && end==null) { return; }
  if(this.disabledDatesExpr!='') { this.disabledDatesExpr += '||'; }
  if(start==null)
  {
    this.disabledDatesExpr += '(ds<='+ end +')';
  }
  else if(end==null)
  {
    this.disabledDatesExpr += '(ds>='+ start +')';
  }
  else
  {
    this.disabledDatesExpr += '(ds>='+ start +'&&ds<='+ end +')';
  }
}

/*
  -- RenderCalendar -------------------------------------------------------------------------------
  writes calendar button to page and creates new calendar object
*/
function RenderCalendar(
  _calId,  // id of popframe calendar to influence
  _sText   // text to show in button
  )
{
  if(!document.getElementById || !document.body.innerHTML || isUndefined(Function.call)){ return false; }

  // write button to page
  document.write('<span href="#" style="position:relative;" onclick="__getPFCalendar(\'', _calId, '\').ToggleVisibility(this.firstChild, event);return false;">');
  document.write(unescape(_sText));
  document.write('</span>');

  return pfCal = new PFCalendar(_calId);
}