/***************************************************************************
 *  calendar.js
 *  version 0.6
 *
 *  Wed 9 June 2007
 *  Copyright helios
 *  helios@elte.hu
 *
 ****************************************************************************/

 function Calendar(options) {
  inputs = []; calendar = []; calendar_status = [];
  for (option in options) {
    if (option == 'inputs')
      options[option].scan(/\w+/, function(match) { inputs.push(match[0]); });
    else if (option == 'calendar')
      options[option].scan(/\w+/, function(match) { calendar.push(match[0]); calendar_status.push(0); });
    else eval('this.'+option+' = "'+options[option]+'"');
  }
  this.inputs = inputs;
  this.calendar = calendar;
  this.calendar_status = calendar_status;
  this.show = show;
  this.hide = hide;
  this.loadCalendar = loadCalendar;
  this.genRow = genRow;
  this.convertDateToValue = convertDateToValue;
  this.convertValueToDate = convertValueToDate;
  this.setMonth = setMonth;
  this.setYear  = setYear;
  this.setDate  = setDate;
  this.setDay   = setDay;
}

function convertDateToValue(date) {
  pd = this.dateformat.indexOf('dd');
  pm = this.dateformat.indexOf('mm');
  py = this.dateformat.indexOf('yyyy');
  d  = date.substr(pd,2);
  m  = date.substr(pm,2);
  y  = date.substr(py,4);
  if (d<1 || d>31 || m<1 || m>12 || y<this.yearmin || y>this.yearmax || !d || !m || !y) {
    value = new Date();
    y = value.getFullYear();
    m = value.getMonth()+1;
    d = value.getDate();
  }
  value = new Date(y+'/'+m+'/'+d);
  return value.getTime();
}

function convertValueToDate(value) {
  date  = new Date(value);
  ret   = this.dateformat;
  year  = date.getFullYear();
  month = date.getMonth()+1;
  day   = date.getDate();
  if (day<10) day = '0'+day;
  if (month<10) month = '0'+month;
  ret = ret.replace(/dd/,day);
  ret = ret.replace(/mm/,month);
  ret = ret.replace(/yyyy/,year);
  return ret;
}

function setMonth(month) {
  day = new Date();
  day.setTime(this.month);
  if (month == 'prev')
    month = day.getMonth()-1;
  else if (month == 'next')
    month = day.getMonth()+1;
  if (day.getFullYear() == this.yearmin && month == -1 ||
      day.getFullYear() == this.yearmax && month == 12)
    return;
  day.setMonth(month);
  day.setDate(1);
  this.month = day.getTime();
  month++;
  day.setMonth(month);
  if (month == 0) day.setFullYear(day.getFullYear()+1);
  if (month == 13) day.setFullYear(day.getFullYear()-1);
  this.nextmonth = day.getTime();
  this.loadCalendar(this.inputs[this.active]);
}

function setYear(year) {
  day = new Date();
  day.setTime(this.month);
  if (year>=this.yearmin && year<=this.yearmax) {
    day.setYear(year);
    day.setDate(1);
    this.month = day.getTime();
    month = day.getMonth()+1;
    day.setMonth(month);
    this.nextmonth = day.getTime();
    this.loadCalendar(this.inputs[this.active]);
  }
}

function setDate(date) {
  day = new Date();
  day.setTime(date);
  if (day.getFullYear()>this.yearmax) {
    day.setFullYear(this.yearmax);
    day.setMonth(11,31);
    date = day.getTime();
  }
  $(this.inputs[this.active]).value = this.convertValueToDate(date);
  if (!this.active && this.inputs.length == 2 && this.mode == 'reservation') {
    tmp = this.convertDateToValue($(this.inputs[1]).value);
    if (date>=tmp)
      $(this.inputs[1]).value = this.convertValueToDate(this.setDay(date,1));
  }
  this.hide(this.inputs[this.active],this.active);
}

function setDay(date,days) {
  day = new Date();
  tmp = (days) ? 86400000*days : -86400000*days;
  day.setTime(date+tmp);
  if (day.getHours() == 23)
    tmp += 3600000;
  else if (day.getHours() == 1)
    tmp -= 3600000;
  day.setTime(date+tmp);
  return day.getTime();
}

function hide(calendar,active) {
  if (this.calendar[active]) {
    $(this.calendar[active]).innerHTML = '';
    $(this.calendar[active]).style.visibility = "hidden";
    this.calendar_status[active] = 0;
  }
}

function show(calendar) {
  this.active = this.inputs.indexOf(calendar);
  if (this.active<0) return;
  ret = false;
  for(i=0;i<this.inputs.length;i++) {
    if (i == this.active && this.calendar_status[i] == 1) {
      this.hide(this.inputs[i],i);
      ret = true;
    } else if (i != this.active)
      this.hide(this.inputs[i],i);
  }
  if (ret) return;

  this.date = this.convertDateToValue($F(this.inputs[this.active]));
  day = new Date();
  day.setHours(0);
  day.setMinutes(0);
  day.setSeconds(0);
  day.setMilliseconds(0);
  this.today = day.getTime();
  day.setTime(this.date);
  day.setDate(1);
  this.month = day.getTime();
  day.setMonth(day.getMonth()+1);
  this.nextmonth = day.getTime();

  if (this.active && this.mode == 'reservation') {
    this.lastdate = this.convertDateToValue($F(this.inputs[0]));
    if (this.lastdate>=this.today)
      this.lastdate = this.setDay(this.lastdate,1);
    if (this.lastdate>this.date)
      this.date = this.lastdate;
  } else this.lastdate = this.today;

  $(this.inputs[this.active]).value = this.convertValueToDate(this.date);
  this.loadCalendar(calendar);
  $(this.calendar[this.active]).style.visibility = "visible";
  this.calendar_status[this.active]++;
}

function genRow(wclass,weekday,day) {
  rtpl = new Template("\<td class='#{classes}' onclick='#{onclick}'>#{day}</td>\n");
  rdata = [];
  rdata['day'] = day.getDate();
  if (weekday<6 && day.getTime() == this.today && this.today < this.lastdate && this.mode == 'reservation')
    rdata['classes'] = wclass+' weekday today inactive';
  else if (day.getTime() == this.today && this.today < this.lastdate && this.mode == 'reservation')
    rdata['classes'] = wclass+' weekend today inactive';
  else if (weekday<6 && day.getTime() == this.today && this.today == this.date)
    rdata['classes'] = wclass+' weekday today active';
  else if (day.getTime() == this.today && this.today == this.date)
    rdata['classes'] = wclass+' weekend today active';
  else if (weekday<6 && day.getTime() == this.today)
    rdata['classes'] = wclass+' weekday today';
  else if (day.getTime() == this.today)
    rdata['classes'] = wclass+' weekend today';
  else if (weekday<6 && day.getTime() == this.date)
    rdata['classes'] = wclass+' weekday active';
  else if (day.getTime() == this.date)
    rdata['classes'] = wclass+' weekend active';
  else if (weekday<6 && day.getTime()<this.lastdate && this.mode == 'reservation')
    rdata['classes'] = wclass+' weekday inactive';
  else if (day.getTime()<this.lastdate && this.mode == 'reservation')
    rdata['classes'] = wclass+' weekend inactive';
  else if (weekday<6)
    rdata['classes'] = wclass+' weekday';
  else rdata['classes'] = wclass+' weekend';
  if (rdata['classes'].indexOf('inactive')>-1 && this.mode == 'reservation')
    rdata['onclick'] = '';
  else rdata['onclick'] = this.instance+'.setDate('+day.getTime()+')';
  return rtpl.evaluate(rdata);
}

function loadCalendar(calendar) {
  ctpl = new Template("\
<table class='calendar' cellspacing=0>\n\
  <tr>\n\
    <td colspan='7' class='commands'>\n\
    <input type='button' value='<' onclick='#{instance}.setMonth(\"prev\")'>\n\
    <select name='month' onchange='#{instance}.setMonth(this.value)'>\n\
      <option value='0' #{month0}>January</option>\n\
      <option value='1' #{month1}>February</option>\n\
      <option value='2' #{month2}>March</option>\n\
      <option value='3' #{month3}>April</option>\n\
      <option value='4' #{month4}>May</option>\n\
      <option value='5' #{month5}>June</option>\n\
      <option value='6' #{month6}>July</option>\n\
      <option value='7' #{month7}>August</option>\n\
      <option value='8' #{month8}>September</option>\n\
      <option value='9' #{month9}>October</option>\n\
      <option value='10' #{month10}>November</option>\n\
      <option value='11' #{month11}>December</option>\n\
    </select>\n\
    <select name='year' onchange='#{instance}.setYear(this.value)'>\n\
#{years}\n\
    </select>\n\
    <input type='button' value='>' onclick='#{instance}.setMonth(\"next\")'>\n\
    </td>\n\
  </tr>\n\
  <tr>\n\
    <td class='daynames'>Mon</td>\n\
    <td class='daynames'>Tue</td>\n\
    <td class='daynames'>Wed</td>\n\
    <td class='daynames'>Thu</td>\n\
    <td class='daynames'>Fri</td>\n\
    <td class='daynames'>Sat</td>\n\
    <td class='daynames'>Sun</td>\n\
  </tr>\n\
#{days}\n\
</table>\n");

  day = new Date();
  day.setTime(this.month);
  data = [];
  data['instance'] = this.instance;
  data['years'] = '';
  for(i=this.yearmin;i<=this.yearmax;i++)
    if (day.getFullYear() == i)
      data['years'] += '<option value="'+i+'" selected>'+i+'</option>'+"\n";
    else data['years'] += '<option value="'+i+'">'+i+'</option>'+"\n";
  data['month'+day.getMonth()] = 'selected';

// previous month
  row = '<tr>';
  day.setTime(this.month);
  weekday = day.getDay();
  if (!weekday) weekday = 7;
  if (weekday != 1) {
    day.setTime(this.setDay(this.month,-weekday+1));
    for (i=1;i<weekday;i++) {
      row += this.genRow('prevmonth',i,day);
      day.setTime(this.setDay(day.getTime(),1));
    }
  }

// current month
  weekday = day.getDay();
  if (!weekday) weekday = 7;
  while (day.getTime() != this.nextmonth) {
    if (weekday == 1) row += '<tr>';
    row += this.genRow('currentmonth',weekday,day);
    if (weekday == 7) row += '</tr>';
    day.setTime(this.setDay(day.getTime(),1));
    weekday = day.getDay();
    if (!weekday) weekday = 7;
  }

// next month
  while (weekday != 1) {
    row += this.genRow('nextmonth',weekday,day);
    if (weekday == 7) row += '</tr>'+"\n";
    day.setTime(this.setDay(day.getTime(),1));
    weekday = day.getDay();
    if (!weekday) weekday = 7;
  }
  data['days'] = row;
  $(this.calendar[this.active]).innerHTML = ctpl.evaluate(data);
}
