/*
 * 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.core.client.JavaScriptObject;
import com.google.gwt.core.client.impl.Impl;

/**
 * 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 native JavaScriptObject createCallback(Timer timer, int cancelCounter) /*-{
    return $entry(function() { timer.@com.google.gwt.user.client.Timer::fire(I)(cancelCounter); });
  }-*/;

  private boolean isRepeating;

  private Integer timerId = null;

  /**
   * Workaround for broken clearTimeout in IE. Keeps track of whether cancel has been called since
   * schedule was called. See https://code.google.com/p/google-web-toolkit/issues/detail?id=8101
   */
  private int cancelCounter = 0;

  /**
   * Returns {@code true} if the timer is running. Timer is running if and only if it is scheduled
   * but it is not expired or cancelled.
   */
  public final boolean isRunning() {
    return timerId != null;
  }

  /**
   * Cancels this timer. If the timer is not running, this is a no-op.
   */
  public void cancel() {
    if (!isRunning()) {
      return;
    }

    cancelCounter++;
    if (isRepeating) {
      Impl.clearInterval(timerId);
    } else {
      Impl.clearTimeout(timerId);
    }
    timerId = null;
  }

  /**
   * 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. If the timer is already running then it will be
   * first canceled before re-scheduling.
   *
   * @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 non-negative");
    }
    if (isRunning()) {
      cancel();
    }
    isRepeating = false;
    timerId = Impl.setTimeout(createCallback(this, cancelCounter), delayMillis);
  }

  /**
   * Schedules a timer that elapses repeatedly. If the timer is already running then it will be
   * first canceled before re-scheduling.
   *
   * @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");
    }
    if (isRunning()) {
      cancel();
    }
    isRepeating = true;
    timerId = Impl.setInterval(createCallback(this, cancelCounter), periodMillis);
  }

  /*
   * Called by native code when this timer fires.
   *
   * Only call run() if cancelCounter has not changed since the timer was scheduled.
   */
  final void fire(int scheduleCancelCounter) {
    // Workaround for broken clearTimeout in IE.
    if (scheduleCancelCounter != cancelCounter) {
      return;
    }

    if (!isRepeating) {
      timerId = null;
    }

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