/*
  -------------------------------------------------------------------------------------------------

  : clock.js
  : ben miller : ben@hyl.co.uk : http://digital.hyl.co.uk
  : v1.6 : 24 May 2004
  :
  : javascript digital clock implementation.
  : reads in .NET Framework DateTimeFormatInfo string array and displays current time accordingly
  :

  -------------------------------------------------------------------------------------------------
*/

/*
  -- Clock: Base Constructor ----------------------------------------------------------------------
*/
function Clock(_id, _formatPattern, _interval)
{
  if((!document.getElementById)&&(!document.all)){ return; };
  if(!_id){ return; };

  var _index         = aClockCollection.length;
  aClockCollection[_index] = this;
  this.ReturnElement = _id;
  this.FormatPattern = _formatPattern;
  this.Index         = _index;
  this.Interval      = (_interval==null)?1000:parseInt(_interval);

  this.Load = function()
  {
    setInterval('aClockCollection['+this.Index+'].Update()', this.Interval);
  }

  this.Update = function()
  {
    var el;
    if(document.getElementById)
    {
      el = document.getElementById(this.ReturnElement);
      el.innerHTML = ''; // Mac IE5.1+ bugfix by Richard Meijer
      el.innerHTML = GetDateTime(this.FormatPattern);
    }
    else if(document.all)
    {
      el = document.all[this.ReturnElement];
      el.innerHTML = GetDateTime(this.FormatPattern);
    }
  }
}


/*
  -- GetDateTime ----------------------------------------------------------------------------------

    returns current date+time+literal strings according to _formatPattern which is a string array
    following the rules of the .NET Framework DateTimeFormatInfo class.
*/
function GetDateTime(_formatPattern)
{
  var now            = new Date();
  var aFormatPattern = new Array();
  var sRetVal        = '';
  var sPattern       = '';

  var d                     = now.getDate();
  aFormatPattern['d']       = d;
  aFormatPattern['dd']      = (d<=9)?'0'+d:d;
  var iDay                  = now.getDay();
  aFormatPattern['ddd']     = aDayNames[iDay].substr(0,3);
  aFormatPattern['dddd']    = aDayNames[iDay];
  var M                     = now.getMonth();
  aFormatPattern['MMM']     = aMonthNames[M].substr(0,3);
  aFormatPattern['MMMM']    = aMonthNames[M];
  M++;
  aFormatPattern['M']       = M;
  aFormatPattern['MM']      = (M<=9)?'0'+M:M;
  var yyyy                  = now.getFullYear();
  aFormatPattern['yyyy']    = yyyy;
  aFormatPattern['yy']      = (''+yyyy).substring(2);
  aFormatPattern['y']       = Math.abs(aFormatPattern['yy']);
  aFormatPattern['g']       = sEraName;
  var H                     = now.getHours();
  aFormatPattern['H']       = H;
  aFormatPattern['HH']      = (H<=9)?'0'+H:H;
  var h                     = (H>12)?H-12:H;
  aFormatPattern['h']       = h;
  aFormatPattern['hh']      = (h<=9)?'0'+h:h;
  var m                     = now.getMinutes();
  aFormatPattern['m']       = m;
  aFormatPattern['mm']      = (m<=9)?'0'+m:m;
  var s                     = now.getSeconds();
  aFormatPattern['s']       = s;
  aFormatPattern['ss']      = (s<=9)?'0'+s:s;
  var f                     = now.getMilliseconds()+'000000';
  aFormatPattern['f']       = f.substr(0,1);
  aFormatPattern['ff']      = f.substr(0,2);
  aFormatPattern['fff']     = f.substr(0,3);
  aFormatPattern['ffff']    = f.substr(0,4); // HACK: filled in with zeros past this point
  aFormatPattern['fffff']   = f.substr(0,5); // because javascript only deals in fractions
  aFormatPattern['ffffff']  = f.substr(0,6); // of a second up to three-digit precision
  aFormatPattern['fffffff'] = f.substr(0,7);
  var tt                    = ((H>=0)&&(H<12))?sAMDesignator:sPMDesignator;
  aFormatPattern['tt']      = tt;
  aFormatPattern['t']       = tt.substr(0,1);
  var z                     = now.getISOTimezoneOffset();
  aFormatPattern['z']       = z.substr(0,1)+(''+parseInt(z.substr(1,2)));
  aFormatPattern['zz']      = z.substr(0,1)+(''+z.substr(1,2));
  aFormatPattern['zzz']     = z;

  var sBackslash = String.fromCharCode(92);

  for(i=0;i<_formatPattern.length;i++)
  {
    if(_formatPattern[i].substr(0,1)==sBackslash)
    {
      sRetVal += _formatPattern[i].substring(1);
    }
    else
    {
      sPattern = aFormatPattern[_formatPattern[i]];
      if(typeof(sPattern)!='undefined')
      {
        sRetVal += sPattern;
      }
      else
      {
        sRetVal += _formatPattern[i];
      }
    }
  }
  return sRetVal;
}


/*
  -- Date : getISOTimezoneOffset ------------------------------------------------------------------

    returns ISO 8601 standard timezone offset rather than that weird ECMA one...
    based in part on ISO Clock by John Walker (john@321webliftoff.net)
*/
function getISOTimezoneOffset()
{
  var dif  = this.getHours()-this.getUTCHours();
  var hDif = Math.abs(dif);
  var m    = this.getMinutes();
  var mUTC = this.getUTCMinutes();

  if(m!=mUTC&&mUTC<30&&dif<0){ hDif--; }
  if(m!=mUTC&&mUTC>30&&dif>0){ hDif--; }

  return (((dif<0)?'-':'+')+((hDif<10)?'0'+hDif:''+hDif)+':'+((m!=mUTC)?'30':'00'));
}
Date.prototype.getISOTimezoneOffset = getISOTimezoneOffset;


/*
  -- safeAddEventListener -------------------------------------------------------------------------
*/
function safeAddEventListener(ob, ev, fnc, useCapture)
{
  if(ob.addEventListener)
  {
    ob.addEventListener(ev, fnc, useCapture);
    return true;
  }
  else if(ob.attachEvent)
  {
    return ob.attachEvent('on'+ev, fnc);
  }
}


/*
  -- Clock: Public --------------------------------------------------------------------------------
*/
var aClockCollection = new Array();

function InitClocks()
{
  for(var clockCount=0;clockCount<aClockCollection.length;clockCount++)
  {
    aClockCollection[clockCount].Load();
  }
}

safeAddEventListener(window, 'load', InitClocks, false);
