/************************************************
*                                               *
*            Date object                        *
*                                               *
************************************************/

// format is used in a similar way to http://uk.php.net/date
// restricted chars must be escaped with a '\', however in javascript
// when writing the string the '\' itself must be escaped
// E.g. var str = new Date().format('\\Year: Y');  -> Year: 2005
//      var str = new Date().format('\Year: Y');   -> 2005ear: 2005
// note only the 1 '\' in the second example
Date.prototype.format = function (str) {
  this.procProps();
  var pos = 0;
  var buff = '';
  var esc = false;
  while (pos < str.length) {
    var c = str.charAt(pos);
    if (c == '\\' && !esc) {
      esc = true;
    }
    else if (this.isReservedChar(c) && !esc) {
      buff += eval('this.' + c);
    }
    else {
      buff += c;
      esc = false;
    }
    pos++;
  }
  return buff;
}
Date.prototype.isReservedChar = function (c) {
  for (var i = 0; i < this.reservedChars.length; i++) {
    if (this.reservedChars[i] == c) {
      return true;
    }
  }
  return false;
}
Date.prototype.strPad = function (strIn, padLength) {
  var strPad = '0';
  var strIn = new String(strIn);
  var j = strIn.length;
  for (var i = j; i < padLength; i++) {
    strIn = strPad + strIn;
  }
  return strIn;
}
Date.prototype.procProps = function () {
  // see http://uk.php.net/date for a list of the properties
  // D - A textual representation of a day, three letters (Sun through Sat)
  // l (lowercase 'L') - A full textual representation of the day of the week (Sunday through Saturday)
  // d - Day of the month, 2 digits with leading zeros (01 to 31)
  // j - Day of the month without leading zeros (1 to 31)
  // F - A full textual representation of a month, such as January or March (January through December)
  // m - Numeric representation of a month, with leading zeros (01 through 12)
  // M - A short textual representation of a month, three letters (	Jan through Dec)
  // Y - A full numeric representation of a year, 4 digits (Examples: 1999 or 2003)
  // y - A two digit representation of a year (Examples: 99 or 03)
  // H - 24-hour format of an hour with leading zeros (00 through 23)
  // i - Minutes with leading zeros (00 to 59)
  // s - Seconds, with leading zeros (00 through 59)
  // S - English ordinal suffix for the day of the month, 2 characters (st, nd, rd & th)
  this.reservedChars = ['D', 'l', 'd', 'j', 'F', 'm', 'M', 'Y', 'y', 'H', 'i', 's', 'S'];
  if (isNaN(this.getDate()) || isNaN(this.getMonth()) || isNaN(this.getFullYear())) { 
    this.setFullYear(1900, 0, 1);
  }
  var shortDays = new Array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
  var longDays = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
  var monthNames = new Array ('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
  var shortMonthNames = new Array ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
  this.D = shortDays[this.getDay()];
  this.l = longDays[this.getDay()];
  this.d = this.strPad(this.getDate(), 2);
  this.j = this.getDate();
  this.F = monthNames[this.getMonth()];
  this.m = this.strPad(this.getMonth() + 1, 2);
  this.M = shortMonthNames[this.getMonth()];
  this.Y = this.getFullYear();
  this.y = (this.getYear() > 100) ? this.strPad(this.getYear() - 100, 2) : this.strPad(this.getYear(), 2);
  this.i = this.strPad(this.getMinutes(), 2);
  this.H = this.strPad(this.getHours(), 2);
  this.s = this.strPad(this.getSeconds(), 2);
  switch (this.getDate()) {
    case 1:
      this.S = 'st';
      break;
    case 2:
      this.S = 'nd';
      break;
    case 3:
      this.S = 'rd';
      break;
    case 21:
      this.S = 'st';
      break;
    case 22:
      this.S = 'nd';
      break;
    case 23:
      this.S = 'rd';
      break;
    case 31:
      this.S = 'st';
      break;
    default:
      this.S = 'th';
      break;
  }
}