//
// Timer handling
// (c) Marco Vieth, 2003
// http://www.benchmarko.de/
//
// 0.01  06.06.2003  first tests
// 0.02  17.06.2003  rewritten with timer objects;
//                   simulate non-existing interval timer with old JS 1.1 (e.g. StarOffice 5.2)
// 0.021 30.11.2003  avoid class variables Timer.<var> (not available in JS 1.1)?
//

//
// - For debugging:  use debug1.js
//


// Note:
// Another simple Callwrapper for setTimeout is CCallWrapper.js by Netscape
// (http://devedge.netscape.com/toolbox/examples/2003/CCallWrapper/)
// But this works for setTimeout() only, requires JS 1.2, cannot reuse Timer objects...
//


var g_debug = null; // maybe changed later...


// -----------------------------


// Constructor for class Timer
// new Timer(<object>, <method name>, [<arg0>])
// Note: If method is not sepcified here it must be defined with setTimeout(), setInterval()...
function Timer(obj, method, arg0) {
  // attributes
  if (obj) { // only if parameter obj is given...
    this.idx = Timer_maxidx++; // use the next index in timer pending list
    this.obj = obj;
    this.method = method;
    this.arg0 = arg0;
    this.timer = 0; // current timer, will be set later...
    this.delay_ms = 0; // delay will be set later...
    this.interval_f = 0; // set standard timer
    Timer_pending[this.idx] = this;
    if (g_debug) { g_debug.writeln("Timer::new["+ this.idx +"]: method='"+ this.method +"', arg0='"+ this.arg0 +"'"); }
  }

  // methods
  if (!Timer.prototype) { // old browsers get the methods directly into the object...
    this.exec = Timer_exec; // not called directly
    this.setTimeout = Timer_setTimeout;
    this.clearTimeout = Timer_clearTimeout;
    this.setInterval = Timer_setInterval;
    this.clearInterval = Timer_clearInterval;
    this.close = Timer_close;
  }

}


//
// normally we would create unnamed functions here but for old browsers...
// Sshow.prototype.add_image = function(image, descr) { ... }
//

// For new browsers (JS 1.2) set the prototypes...
new Timer(); // force old browsers to create prototype
if (Timer.prototype) {
  Timer.prototype.exec = Timer_exec; // not called directly
  Timer.prototype.setTimeout = Timer_setTimeout;
  Timer.prototype.clearTimeout = Timer_clearTimeout;
  Timer.prototype.setInterval = Timer_setInterval;
  Timer.prototype.clearInterval = Timer_clearInterval;
  Timer.prototype.close = Timer_close;
}


// Simulate class definitions
// Instead of "Timer.maxidx" we use "var Timer_maxidx" to be JS 1.1 compatible...
// Same with "Timer.pending"...
var Timer_maxidx = 0;
var Timer_pending = new Array();


// called only internally...
// interval_f = 1 => is an interval timer which is not needed to reset... (should be same as this.interval_f)
function Timer_exec() {
  //if (g_debug) { g_debug.writeln("Timer_exec["+ this.idx +"]: interval_f="+ this.interval_f); }
  // We use argument arg0 here and not this.arg0 because we allow to redefine arg0 in set* functions...
  this.obj[this.method](this.arg0);
  if (!this.interval_f) {
    this.timer = 0; // set standard timer to not running
  } else {
    if (!window.setInterval) { // no interval timer available? (JS 1.1)
      if (window.setTimeout) { // if possible, simulate interval timer with standard timer...
        this.timer = window.setTimeout('Timer_pending["'+ this.idx +'"].exec()', this.delay_ms);
        if (g_debug) { g_debug.writeln("Timer_exec["+ this.idx +"]: simulate interval timer: timer="+ this.timer); }
      }
    }
  }
};


// standard timer

// mytimer.setTimeout(<delay_ms>) - set timeout (or interval)
// - if timer is running, stop it first
// - start a new timer, if delay_ms > 0
// (- timer objects can be reused...)
function Timer_setTimeout(delay_ms) {
  if (this.timer) { // clear timeout if already running...
    this.clearTimeout();
  }
  this.delay_ms = delay_ms;
  //if (g_debug) { g_debug.writeln("DDD: Timer_setTimeout["+ this.idx +"]: interval_f="+ this.interval_f +", delay_ms="+ this.delay_ms); }

  if (this.delay_ms > 0) {
    if (this.interval_f && window.setInterval) { // not for NGS (or StarOffice 5.2, JS 1.1)
      this.timer = window.setInterval('Timer_pending['+ this.idx +'].exec()', this.delay_ms);
    } else {
      if (window.setTimeout) { // not for NGS
        this.timer = window.setTimeout('Timer_pending["'+ this.idx +'"].exec()', this.delay_ms);
      }
    }
  }
  if (g_debug) { g_debug.writeln("Timer_setTimeout["+ this.idx +"]: interval_f="+ this.interval_f +", delay_ms="+ this.delay_ms +", timer="+ this.timer); }
}


// clear timeout or interval
function Timer_clearTimeout() {
  if (g_debug) { g_debug.writeln("Timer_clearTimeout["+ this.idx +"]: interval_f="+ this.interval_f +", timer="+ this.timer); }
  if (this.timer) {
    if (this.interval_f && window.clearInterval) { // not for NGS
      window.clearInterval(this.timer);
    } else {
      if (window.clearTimeout) { // not for NGS
        window.clearTimeout(this.timer);
      }
    }
  }
  this.timer = 0;
  this.interval_f = 0; // set standard timer (so we can reuse same object as interval or standard timer)
}


// Interval timer

// mytimer.setInterval(<delay_ms>)
function Timer_setInterval(delay_ms) {
  if (this.timer) { // clear timeout if already running (need to do it here because we set interval_f)...
    this.clearTimeout();
  }
  this.interval_f = 1; // need an interval timer
  this.setTimeout(delay_ms);
}

function Timer_clearInterval() {
  this.clearTimeout();
}


// stop the timer and remove entry from timer pending list
function Timer_close() {
  if (g_debug) { g_debug.writeln("Timer_close["+ this.idx +"]: interval_f="+ this.interval_f); }
  if (this.timer) { // clear timeout if running...
    this.clearTimeout();
  }
  delete Timer_pending[this.idx]; // JS 1.2?
}

//end

