/*
 * Copyright 2007 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.user.client;

import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;

import java.util.ArrayList;

/**
 * A simplified, browser-safe timer class. This class serves the same purpose as
 * java.util.Timer, but is simplified because of the single-threaded
 * environment.
 * 
 * <p>
 * To schedule a timer, simply create a subclass of it (overriding {@link #run})
 * and call {@link #schedule} or {@link #scheduleRepeating}.
 * </p>
 * 
 * <p>
 * NOTE: If you are using a timer to schedule a UI animation, use
 * {@link com.google.gwt.animation.client.AnimationScheduler} instead. The
 * browser can optimize your animation for maximum performance.
 * </p>
 * 
 * <p>
 * <h3>Example</h3>
 * {@example com.google.gwt.examples.TimerExample}
 * </p>
 */
public abstract class Timer {

  private static ArrayList<Timer> timers = new ArrayList<Timer>();

  static {
    hookWindowClosing();
  }

  private static native void clearInterval(int id) /*-{
    $wnd.clearInterval(id);
  }-*/;

  private static native void clearTimeout(int id) /*-{
    $wnd.clearTimeout(id);
  }-*/;

  private static native int createInterval(Timer timer, int period) /*-{
    return $wnd.setInterval(
      $entry(function() { timer.@com.google.gwt.user.client.Timer::fire()(); }),
      period);
  }-*/;

  private static native int createTimeout(Timer timer, int delay) /*-{
    return $wnd.setTimeout(
      $entry(function() { timer.@com.google.gwt.user.client.Timer::fire()(); }),
      delay);
  }-*/;

  private static void hookWindowClosing() {
    // Catch the window closing event.
    Window.addCloseHandler(new CloseHandler<Window>() {

      public void onClose(CloseEvent<Window> event) {
        while (timers.size() > 0) {
          timers.get(0).cancel();
        }
      }
    });
  }

  private boolean isRepeating;

  private int timerId;

  /**
   * Cancels this timer.
   */
  public void cancel() {
    if (isRepeating) {
      clearInterval(timerId);
    } else {
      clearTimeout(timerId);
    }
    timers.remove(this);
  }

  /**
   * This method will be called when a timer fires. Override it to implement the
   * timer's logic.
   */
  public abstract void run();

  /**
   * Schedules a timer to elapse in the future.
   * 
   * @param delayMillis how long to wait before the timer elapses, in
   *          milliseconds
   */
  public void schedule(int delayMillis) {
    if (delayMillis <= 0) {
      throw new IllegalArgumentException("must be positive");
    }
    cancel();
    isRepeating = false;
    timerId = createTimeout(this, delayMillis);
    timers.add(this);
  }

  /**
   * Schedules a timer that elapses repeatedly.
   * 
   * @param periodMillis how long to wait before the timer elapses, in
   *          milliseconds, between each repetition
   */
  public void scheduleRepeating(int periodMillis) {
    if (periodMillis <= 0) {
      throw new IllegalArgumentException("must be positive");
    }
    cancel();
    isRepeating = true;
    timerId = createInterval(this, periodMillis);
    timers.add(this);
  }

  /*
   * Called by native code when this timer fires.
   */
  final void fire() {
    // If this is a one-shot timer, remove it from the timer list. This will
    // allow it to be garbage collected.
    if (!isRepeating) {
      timers.remove(this);
    }

    // Run the timer's code.
    run();
  }
}
