<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="Date &amp; Time"
             author="Mihai Parparita"
             author_email="mihai.parparita@gmail.com"
             author_affiliation="Google Inc."
             author_location="New York, NY"
             screenshot="http://persistent.info/modules/datetime.png"
             description="Smaller/better clock and calendar"
             render_inline="optional" height="165" scaling="false"
/>
<Content type="html"><![CDATA[

<!-- 
  Based on the original Date & Time module by Matt M.:
  http://www.google.com/ig/modules/datetime.xml
-->

<style type="text/css">
  #main__MODULE_ID__ {
    font-family: Helvetica, Verdana, Arial, sans-serif;
    padding-top: 2px;
    width: 100%;
  }
  
  #datetime-shadow__MODULE_ID__,
  #cal__MODULE_ID__ {
    float: left;
  }
  
  #datetime-shadow__MODULE_ID__ {
    border-right: solid 2px #ccc;
    border-bottom: solid 2px #ccc;
    margin-right: 20px;
  }
  
  #time__MODULE_ID__ {
    padding: 4px;
    border-top: solid 1px #999;
    text-align: center;
    clear: both;
  }

  #datetime__MODULE_ID__ {
    font-weight: bold;
    border: solid 1px #666;
    background: #eee;
    width: 7em;
    text-align: right;
  }
  
  #day_month__MODULE_ID__ {
    float: left;
    padding: 4px;
  }
  
  #day__MODULE_ID__ {
    font-size: 16px;
  }
  
  #month__MODULE_ID__ {
    font-size: 20px;
  }
  
  #date__MODULE_ID__ {
    font-size: 42px; 
  }
  
  #controls__MODULE_ID__ {
    text-align: center;
  }

  #controls__MODULE_ID__ span {
    padding: 2px 4px;
    font-weight: bold;
    color: #333;
    cursor: pointer;
    cursor: hand;
  }

  #cal-placeholder__MODULE_ID__ {
    margin-top: 3px;
    border-right: solid 2px #ccc;
    border-bottom: solid 2px #ccc;
  }
  
  #cal__MODULE_ID__ table.calendar {
    background: #eee;
    border: solid 1px #666;
  }

  #cal__MODULE_ID__ table.calendar tr.days th {
    border-bottom: dotted 1px #999;
    font-weight: normal;
    font-size: 11px;
  }

  #cal__MODULE_ID__ table.calendar td {
    border-spacing: 1px;
    border: 0;
    padding: 2px;
    color: #000;
    font-size: 9px;
  } 
  
  #cal__MODULE_ID__ table.calendar td.today {  
    color: #600; 
    font-weight: bold;
    background: #ccc;
  }
</style>

<div id="main__MODULE_ID__">

  <div id="datetime-shadow__MODULE_ID__">
    <div id="datetime__MODULE_ID__">
  
      <div id="day_month__MODULE_ID__">
        <div id="day__MODULE_ID__">Sun</div>
        <div id="month__MODULE_ID__">JAN</div>
      </div>
      <div id="date__MODULE_ID__">1</div>    
  
      <div id="time__MODULE_ID__">
        <span id="hour__MODULE_ID__">10</span>:<span id="min__MODULE_ID__">10</span> <span id="am-pm__MODULE_ID__">AM</span> 
      </div>
    </div>
  </div>

  <div id="cal__MODULE_ID__">
    <div id="cal-placeholder__MODULE_ID__"></div>
    <div id="controls__MODULE_ID__">
      <span id="cal-previous__MODULE_ID__">&laquo;</span>
      <span id="cal-now__MODULE_ID__">&loz;</span>
      <span id="cal-next__MODULE_ID__">&raquo;</span>
    </div>  
  </div>
  
</div>

<script type="text/javascript">
(function() {

function DateTime() {
  this.calendarIsNow = true;
  this.displayedDate = -1;
  

  // Static globals.
  var MONTHS_LONG = [
    "January", "February", "March", "April", "May", "June", "July", "August", 
    "September", "October", "November", "December"
  ];
  var MONTHS_SHORT = [
    "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV",
    "DEC"
  ];

  var DAYS_LONG = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
  var DAYS_SHORT = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
  var DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

  function getNode(id) {
    return _gel(id + "__MODULE_ID__");
  }

  function setNode(id, str) {
    getNode(id).innerHTML = str;
  }
  
  this.resize = function() {
    // Date & Time should be centered vertically relative to the calendar
    var datetimeNode = getNode("datetime-shadow");
    var calendarNode = getNode("cal");
    
    datetimeNode.style.marginTop = 
      (calendarNode.offsetHeight - datetimeNode.offsetHeight)/2 + "px";

    // 20 is for the spacing between the date/time and the calendar
    var mainNode = getNode("main");
    var containerNode = mainNode.parentNode;
    mainNode.style.marginLeft = 
      (containerNode.offsetWidth - 
      (datetimeNode.offsetWidth + calendarNode.offsetWidth + 20))/2 + "px";
    
  }

  this.refresh = function() {
    var now = new Date();
    var hour = now.getHours();
    var minutes = now.getMinutes();
    var day = now.getDay();
    var month = now.getMonth();
    var date = now.getDate();
    
    var isPm = false;
    
    if (hour == 0) {
      hour = 12;
    } else if (hour == 12) {
      isPm = true;
    } else if (hour > 12) {
      isPm = true;
      hour -= 12;
    }

    setNode('hour', hour);
    setNode('min', minutes < 10 ? '0' + minutes : minutes);
    setNode('am-pm', isPm ? 'PM' : 'AM');

    // update date if necessary
    if (date != this.displayedDate) {    
    
      setNode('day', DAYS_LONG[day]);
      setNode('month', MONTHS_SHORT[month]);
      setNode('date', date);
      
      if (this.calendarIsNow) {
        this.calendarYear = now.getFullYear();
        this.calendarMonth = month;
        this.drawCalendar(month, now.getFullYear(), day, date);
      }

      this.displayedDate = date;
    }
    
    this.resize();
  }
  
  this.shiftCalendar = function(delta) {
    this.calendarIsNow = false;
    this.calendarMonth += delta;
    if (this.calendarMonth < 0) {
      this.calendarMonth = 11;
      this.calendarYear--;
    } else if (this.calendarMonth > 11) {
      this.calendarMonth = 0;
      this.calendarYear = 1;
    }
    
    this.drawCalendar(this.calendarMonth, this.calendarYear);
  }
  
  this.calendarNow = function() {
    this.calendarIsNow = true;
    this.displayedDate = -1;
    this.refresh();
  }

  this.drawCalendar = function(month, year, opt_day, opt_date) {
    var totalDays = DAYS_IN_MONTH[month];
    if (month == 1 && year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) {
      totalDays = 29;
    }
    
    var result = 
      '<table class="calendar"><thead>' +
        '<tr><th colspan="7">' + MONTHS_LONG[month] + ' ' + year + '</th></tr>' +
        '<tr class="days">';
    
    for (var i = 0; i < 7; i++) {
      result += '<th>' +
        DAYS_SHORT[i] + '</th>';
    }
    result += '</tr></thead><tbody>';

    var currentDay = 1;
    if (opt_day && opt_date) {
      var startingDay = ((opt_day - opt_date % 7 + 1) + 7 ) % 7;
    } else {
      var tempDate = new Date(year, month, 1);
      
      var startingDay = ((tempDate.getDay() - tempDate.getDate() % 7 + 1) + 7 ) % 7;      
    }
    
    for (var i = 0; i < 6; i++) {
      if (currentDay > totalDays) {
        break;
      }
      
      result += '<tr>';
      for (var j = 0; j < 7; j++) {
        var className = '';
        var content = currentDay;
        if ((i == 0 && j < startingDay) || currentDay > totalDays) {
          content = '&nbsp;';
        } else {
          if (opt_date && (currentDay == opt_date)) {
            className = 'today';
          }
          currentDay++;
        }
        result += '<td class="' + className + '">' + content + '</td>';
      }
      result += '</tr>';
    }
    result += '</tbody></table>';
    
    setNode('cal-placeholder', result);
    
    this.resize();
  }

  /**
   * Sets up the clock to update every minute.
   */
  this.startInterval = function() {
    var self = this;
    window.setInterval(function() {self.refresh();}, 60000);
    this.refresh();
  }

  /**
   * Sets up the clock, and tries its best to sync with the system clock to update at the right time.
   */
  this.main = function() {
    var self = this;
    getNode("cal-previous").onclick = function() {self.shiftCalendar(-1); return false;};
    getNode("cal-now").onclick = function() {self.calendarNow(); return false;};
    getNode("cal-next").onclick = function() {self.shiftCalendar(1); return false;};
    
    this.refresh();
    window.setTimeout(function() {self.startInterval();}, 
                      (60 - new Date().getSeconds()) * 1000 + 5);
  }
}

var datetime = new DateTime();

var resizeClosure = function() {
  datetime.resize();
}

if (window.addEventListener) {
  window.addEventListener("resize", resizeClosure, false);
} else if (window.attachEvent) {
  window.attachEvent("onresize", resizeClosure);
}
    
_IG_RegisterOnloadHandler(function() {
  datetime.main();
});

})();

</script>

]]></Content>
</Module>
