/*
 * Copyright 2009 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.event.shared;

import com.google.gwt.event.shared.GwtEvent.Type;

/**
 * Manager responsible for adding handlers to event sources and firing those
 * handlers on passed in events. Primitive ancestor of {@link EventBus}, and
 * used at the core of {com.google.gwt.user.client.ui.Widget}.
 * <p>
 * While widget authors should continue to use
 * {@link com.google.gwt.user.client.ui.Widget#addDomHandler(EventHandler, com.google.gwt.event.dom.client.DomEvent.Type)}
 * and
 * {@link com.google.gwt.user.client.ui.Widget#addHandler(EventHandler, Type)},
 * application developers are strongly discouraged from using a HandlerManager
 * instance as a global event dispatch mechanism.
 */
public class HandlerManager implements HasHandlers {

  private final SimpleEventBus eventBus;

  // source of the events
  private final Object source;

  /**
   * Creates a handler manager with a source to be set on all events fired via
   * {@link #fireEvent(GwtEvent)}. Handlers will be fired in the order that they
   * are added.
   *
   * @param source the default event source
   */
  public HandlerManager(Object source) {
    this(source, false);
  }

  /**
   * Creates a handler manager with the given source, specifying the order in
   * which handlers are fired.
   *
   * @param source the event source
   * @param fireInReverseOrder true to fire handlers in reverse order
   */
  @SuppressWarnings("deprecation")
  public HandlerManager(Object source, boolean fireInReverseOrder) {
    eventBus = new SimpleEventBus(fireInReverseOrder);
    this.source = source;
  }

  /**
   * Adds a handler.
   *
   * @param <H> The type of handler
   * @param type the event type associated with this handler
   * @param handler the handler
   * @return the handler registration, can be stored in order to remove the
   *         handler later
   */
  public <H extends EventHandler> HandlerRegistration addHandler(
      GwtEvent.Type<H> type, final H handler) {
    return eventBus.addHandler(type, handler);
  }

  /**
   * Fires the given event to the handlers listening to the event's type.
   * <p>
   * Any exceptions thrown by handlers will be bundled into a
   * {@link UmbrellaException} and then re-thrown after all handlers have
   * completed. An exception thrown by a handler will not prevent other handlers
   * from executing.
   * <p>
   * Note, any subclass should be very careful about overriding this method, as
   * adds/removes of handlers will not be safe except within this
   * implementation.
   *
   * @param event the event
   */
  public void fireEvent(GwtEvent<?> event) {
    // If it not live we should revive it.
    if (!event.isLive()) {
      event.revive();
    }
    Object oldSource = event.getSource();
    event.setSource(source);
    try {

      // May throw an UmbrellaException.
      eventBus.fireEvent(event);

    } finally {
      if (oldSource == null) {
        // This was my event, so I should kill it now that I'm done.
        event.kill();
      } else {
        // Restoring the source for the next handler to use.
        event.setSource(oldSource);
      }
    }
  }

  /**
   * Gets the handler at the given index.
   *
   * @param <H> the event handler type
   * @param index the index
   * @param type the handler's event type
   * @return the given handler
   */
  @SuppressWarnings("deprecation")
  public <H extends EventHandler> H getHandler(GwtEvent.Type<H> type, int index) {
    return eventBus.getHandler(type, index);
  }

  /**
   * Gets the number of handlers listening to the event type.
   *
   * @param type the event type
   * @return the number of registered handlers
   */
  @SuppressWarnings("deprecation")
  public int getHandlerCount(Type<?> type) {
    return eventBus.getHandlerCount(type);
  }

  /**
   * Does this handler manager handle the given event type?
   *
   * @param e the event type
   * @return whether the given event type is handled
   */
  @SuppressWarnings("deprecation")
  public boolean isEventHandled(Type<?> e) {
    return eventBus.isEventHandled(e);
  }

  /**
   * Removes the given handler from the specified event type.
   *
   * @param <H> handler type
   *
   * @param type the event type
   * @param handler the handler
   */
  public <H extends EventHandler> void removeHandler(GwtEvent.Type<H> type,
      final H handler) {
      eventBus.doRemove(type, null, handler);
  }
}
