/*
 * Copyright 2011 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.animation.client;

import com.google.gwt.core.client.Duration;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.Timer;

import java.util.ArrayList;
import java.util.List;

/**
 * Implementation using a timer for browsers that do not support animation
 * frames.
 */
class AnimationSchedulerImplTimer extends AnimationScheduler {

  /**
   * Timer based implementation of {@link AnimationScheduler.AnimationHandle}.
   */
  private class AnimationHandleImpl extends AnimationHandle {
    private final AnimationCallback callback;

    public AnimationHandleImpl(AnimationCallback callback) {
      this.callback = callback;
    }

    @Override
    public void cancel() {
      cancelAnimationFrame(this);
    }

    public AnimationCallback getCallback() {
      return callback;
    }
  }

  /**
   * The default time in milliseconds between frames. 60 fps == 16.67 ms.
   */
  private static final int DEFAULT_FRAME_DELAY = 16;

  /**
   * The minimum delay in milliseconds between frames. The minimum delay is
   * imposed to prevent freezing the UI.
   */
  private static final int MIN_FRAME_DELAY = 5;

  /**
   * The list of animations that are currently running.
   */
  private final List<AnimationHandleImpl> animationRequests = new ArrayList<AnimationHandleImpl>();

  /**
   * The singleton timer that updates all animations.
   */
  private final Timer timer = new Timer() {
    @Override
    public void run() {
      updateAnimations();
    }
  };

  @Override
  public AnimationHandle requestAnimationFrame(final AnimationCallback callback, Element element) {
    // Save the animation frame request.
    AnimationHandleImpl requestId = new AnimationHandleImpl(callback);
    animationRequests.add(requestId);

    // Start the timer if it isn't started.
    if (animationRequests.size() == 1) {
      timer.schedule(DEFAULT_FRAME_DELAY);
    }

    // Return the request id.
    return requestId;
  }

  private void cancelAnimationFrame(AnimationHandle requestId) {
    // Remove the request from the list.
    animationRequests.remove(requestId);

    // Stop the timer if there are no more requests.
    if (animationRequests.size() == 0) {
      timer.cancel();
    }
  }

  /**
   * Iterate over all animations and update them.
   */
  private void updateAnimations() {
    // Copy the animation requests to avoid concurrent modifications.
    AnimationHandleImpl[] curAnimations = new AnimationHandleImpl[animationRequests.size()];
    curAnimations = animationRequests.toArray(curAnimations);

    // Iterate over the animation requests.
    Duration duration = new Duration();
    for (AnimationHandleImpl requestId : curAnimations) {
      // Remove the current request.
      animationRequests.remove(requestId);

      // Execute the callback.
      requestId.getCallback().execute(duration.getStartMillis());
    }

    // Reschedule the timer if there are more animation requests.
    if (animationRequests.size() > 0) {
      /*
       * In order to achieve as close to 60fps as possible, we calculate the new
       * delay based on the execution time of this method. The delay will be
       * less than 16ms, assuming this method takes more than 1ms to complete.
       */
      timer.schedule(Math.max(MIN_FRAME_DELAY, DEFAULT_FRAME_DELAY - duration.elapsedMillis()));
    }
  }
}
