/**
 * Class to display a timeticker.
 * 
 * Using the initial time-settings you can choose which kind of ticker you like.
 * E.g. if you provide seconds, minutes and hours the ticker will count those up
 * or down, if you provide years and weeks, this will be counted up or down.
 * Be careful to use a float-value only for the last time, else the output will
 * not make much sense. E.g. if you try for 4h 30.5mn 2secs then the seconds
 * will displayed funny. The Ticker will decrease/increase the time from left
 * to right and since 0.1mn are 6 seconds the seconds will count up to 5, then
 * the next value would be 4h 30.6mn 0secs, 4h 30.6mn 1secs, 4h 30.6mn 2secs[..]
 * 4h 30.6mn 5secs, 4h 30.7mn 0secs.
 * If you, however, use the float on the last value only, the display will make
 * sense. 4h 30mn 2.2secs, 4h 30mn 2.3secs, 4h 30mn 2.4secs...
 *
 * This class uses the default javascript-Date-object so it works from the
 * 01.01.1970, 0:00:00.
 *
 * The config object:
 *
 *  .element*   The html-element that contains the ticker.
 *
 *  .countdown  A boolean value indicating if this is a countdown (default) or
 *              counting up.
 *  .refresh    An integer that specifies the refresh-time in milliseconds for
 *              the ticker (default is 13)
 *
 *  .seconds    The seconds that the ticker starts up with. Can be a float-value.
 *  .minutes    The minutes that the ticker starts up with. Can be a float-value.
 *  .hours      The hours that the ticker starts up with. Can be a float-value.
 *  .days       The days that the ticker starts up with. Can be a float-value.
 *  .weeks      The weeks that the ticker starts up with. Can be a float value.
 *  .months     The months that the ticker starts up with. Can be a float value.
 *  .years      The years that the ticker starts up with. Can be a float value.
 *  
 *  .labels     An object with strings to append to the days/hours/mins etc.
 *      .seconds    The string to append after the seconds that are displayed.
 *      .minutes    The string to append after the seconds that are displayed.
 *      .hours      The string to append after the seconds that are displayed.
 *      .days       The string to append after the days that are displayed.
 *      .weeks      The string to append after the weeks that are displayed.
 *      .months     The string to append after the months that are displayed.
 *      .years      The string to append after the months that are displayed.
 *
 *  .digits     An object to indicate how many digits the specified time should
 *              contain at least.
 *      .seconds    Integer value of minimum digits for the seconds.
 *      .minutes    Integer value of minimum digits for the minutes.
 *      .hours      Integer value of minimum digits for the hours.
 *      .days       Integer value of minimum digits for the days.
 *      .weeks      Integer value of minimum digits for the weeks.
 *      .months     Integer value of minimum digits for the months.
 *      .years      Integer value of minimum digits for the years.
 *
 *  .floatdigits An object to indicate which time-values should be displayed as
 *              float-values and how many digits should be displayed.
 *      .seconds    The number of float-digits for the second if any. Because of
 *                  the natural short time a second takes not too many digits
 *                  make sense here. Maximum of three.
 *      .minutes    The number of float-digits for the minutes.
 *      .hours      The number of float-digits for the hours.
 *      .days       The number of float-digits for the days.
 *      .weeks      The number of float-digits for the weeks.
 *      .months     The number of float-digits for the months.
 *      .years      The number of float-digits for the years.
 *
 *  (*) Configuration-setting is required.
 *
 */
function TimeTicker( config )
{
  new CoreObject( this );
  this.setConfig( config );

  for(var objs in {'labels':1,'digits':1,'floatdigits':1})
    if(!this[objs])
      this[objs] = {};

  if(this.countdown == undefined)
      this.countdown = 1;

  if(this.refresh == undefined)
      this.refresh = 13;

  this.times = {
      'years':Math.round(365.242222*24*60*60*1000),
      'months':Math.round(365.242222/12*24*60*60*1000),
      'weeks':7*24*60*60*1000,
      'days':24*60*60*1000,
      'hours':60*60*1000,
      'minutes':60*1000,
      'seconds':1000
  };

  this.now = new Date();

  var ms = 0.0;
  for(var time in this.times)
      if(this[time])
          ms+=this[time]*this.times[time];
  this.time = Math.round(ms);

  this.tick = function()
  {
      var now = new Date(),
          output = '', displayTime, floaty, fdigs, sklave;
      this.time += (now.getTime()-this.now.getTime()) * (this.countdown ? -1 : 1)
      this.now = now;

      if(this.time<=0)
          return;

      var currentTime = this.time;

      if(!this.calendarclock)
          for(var time in this.times)
            if(this[time]!=undefined)
            {
                this[time] = Math.floor(currentTime/this.times[time]);
                currentTime %= this.times[time];

                displayTime = this[time]+'';
                if(this.digits[time])
                    while(displayTime.length<this.digits[time])
                        displayTime = '0'+displayTime;

                if(this.floatdigits[time])
                {
                    floaty = 1;
                    for(sklave=0;sklave<this.floatdigits[time];sklave++)
                        floaty*=10;
                    floaty = this.times[time]/floaty;
                    fdigs = Math.floor(currentTime/floaty);
                    currentTime -= Math.round(fdigs*floaty);

                    fdigs = fdigs+'';
                    while(fdigs.length<this.floatdigits[time])
                        fdigs = '0'+fdigs;
                    displayTime += ','+fdigs;
                }

                output += displayTime + (this.labels[time] ? this.labels[time] : '');
            }

      this.timeOut(this.refresh, 'tick()');
      this.element.innerHTML = output;
  }

  this.timeOut(this.refresh, 'tick()');
}

/**
 * Creates TimeTicker. Expects the inital time to be in the following format:
 * 17 days 10 hours 37 minutes 26.95 seconds
 *
 * days, hours and minutes are optional as the time decreases.
 */
function scTimeTicker(obj)
{
    if(!obj)
        return;

    var times = obj.innerHTML.split(' '),
        config = {
           element: obj,
           labels: {},
           digits: {seconds: 2},
           floatdigits: {seconds:2}
        };

    for(var time in {seconds:1,minutes:1,hours:1,days:1})
    {   if(!times.length)
            break;
        config.labels[time] = ' '+times.pop()+' ';
        config[time] = parseFloat(times.pop().replace(',', '.'));
    }

    new TimeTicker(config);
}

