
function Clock (el, format, offset, local)
{
   this.el = get_by_id(el);
   this.format = format || '%g:%i:%s %p';
   this.offset = offset;
   this.local = local;

   this.display();

   return this;
}


Clock.prototype = {

   el : null,
   format : '',
   local : true,
   offset : 0,

   monthsLong : ['January', 'February', 'March', 'April', 'May', 'June',
                 'July', 'August', 'September', 'October', 'November', 'December'],
   monthsShort : ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],

   daysLong : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
   daysShort : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],

   display : function ()
   {
      kill_children(this.el);
      make_text(this.getTime(), this.el);
   },

   tick : function ()
   {
      this.display();
   },

   getTime : function ()
   {
      if (this.local)
      {
         var time = new Date();
      }
      else
      {
         var now = new Date();
         var now_z = now.getTime();
         var time = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds())
         var time_z = time.getTime();
             time.setTime(time_z + (this.offset * 60 * 60 * 1000));
      }

      // dates
      if (this.format.match(/(a|b|e|j|m|y)/ig))
      {
         var a = this.daysShort[time.getDay()];
         var A = this.daysLong[time.getDay()];
         var b = this.monthsShort[time.getMonth()];
         var B = this.monthsLong[time.getMonth()];
         var e = time.getDate();
         var E = e < 10 ? "0" + e : e;
         var m = time.getMonth() + 1;
         var M = m < 10 ? "0" + m : m;
         var y = time.getFullYear();
         var Y = (""+y).substr(2);

         var j = this.suffix(time.getDate());
      }
      else
      {
         var a = A = b = B = e = E = m = M = y = Y = j = '';
      }

      // times
      var p = time.getHours() > 11 ? "pm" : "am";
      var P = p.toUpperCase();
      var g = time.getHours() > 12 ? time.getHours() - 12 : time.getHours();
      var G = time.getHours();
      var h = g < 10 ? "0" + g : g;
      var H = h < 10 ? "0" + h : h;
      var i = time.getMinutes() < 10 ? "0" + time.getMinutes() : time.getMinutes();
      var s = time.getSeconds() < 10 ? "0" + time.getSeconds() : time.getSeconds();

      var str = this.format.replace(/%p/, p).replace(/%P/, P).replace(/%g/, g).replace(/%G/, G)
          str = str.replace(/%h/, h).replace(/%H/, H).replace(/%i/, i).replace(/%s/, s);

      if (this.format.match(/(a|b|e|j|m|y)/ig))
      {
         str = str.replace(/%a/, a).replace(/%A/, A).replace(/%b/, b).replace(/%B/, B).replace(/%e/, e)
         str = str.replace(/%E/, E).replace(/%m/, m).replace(/%M/, M).replace(/%y/, y).replace(/%Y/, Y);

         str = str.replace(/%j/, j);
      }

      return str;
   },

   suffix : function (date)
   {
      if (date == 11 || date == 12 || date == 13)
         return 'th';

      if ((date % 10) == 1)
         return 'st';
      else if ((date % 10) == 2)
         return 'nd';
      else if ((date % 10) == 3)
         return 'rd';
      else
         return 'th';
   }
}
