/*
 * 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.dom.client;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;

/**
 * The native dom event.
 */
public class NativeEvent extends JavaScriptObject {

  /**
   * The left mouse button.
   */
  public static final int BUTTON_LEFT = 1;

  /**
   * The middle mouse button.
   */
  public static final int BUTTON_MIDDLE = 4;

  /**
   * The right mouse button.
   */
  public static final int BUTTON_RIGHT = 2;

  /**
   * Required constructor for GWT compiler to function.
   */
  protected NativeEvent() {
  }

  /**
   * Gets whether the ALT key was depressed when the given event occurred.
   * 
   * @return <code>true</code> if ALT was depressed when the event occurred
   */
  public final boolean getAltKey() {
    return DOMImpl.impl.eventGetAltKey(this);
  }

  /**
   * Gets the mouse buttons that were depressed when the given event occurred.
   * 
   * @return a bit-field, defined by {@link NativeEvent#BUTTON_LEFT},
   *         {@link NativeEvent#BUTTON_MIDDLE}, and
   *         {@link NativeEvent#BUTTON_RIGHT}
   */
  public final int getButton() {
    return DOMImpl.impl.eventGetButton(this);
  }

  /**
   * Get an array of touches which have changed since the last touch event.
   * 
   * @return array of touches which have changed since the last touch event
   */
  public final JsArray<Touch> getChangedTouches() {
    return DOMImpl.impl.getChangedTouches(this);
  }

  /**
   * Gets the Unicode codepoint of the character generated by this key event.
   * 
   * @return the Unicode codepoint.
   */
  public final int getCharCode() {
    return DOMImpl.impl.eventGetCharCode(this);
  }

  /**
   * Gets the mouse x-position within the browser window's client area.
   * 
   * @return the mouse x-position
   */
  public final int getClientX() {
    return DOMImpl.impl.eventGetClientX(this);
  }

  /**
   * Gets the mouse y-position within the browser window's client area.
   * 
   * @return the mouse y-position
   */
  public final int getClientY() {
    return DOMImpl.impl.eventGetClientY(this);
  }

  /**
   * Gets whether the CTRL key was depressed when the given event occurred.
   * 
   * @return <code>true</code> if CTRL was depressed when the event occurred
   */
  public final boolean getCtrlKey() {
    return DOMImpl.impl.eventGetCtrlKey(this);
  }

  /**
   * Gets the current target element of this event. This is the element whose
   * listener fired last, not the element which fired the event initially.
   * 
   * @return the event's current target element
   */
  public final EventTarget getCurrentEventTarget() {
    return DOMImpl.impl.eventGetCurrentTarget(this);
  }

  /**
   * Get the {@link DataTransfer} associated with the current drag event.
   * 
   * @return the {@link DataTransfer} object, or null if not a drag event
   */
  public final native DataTransfer getDataTransfer() /*-{
    return this.dataTransfer || null;
  }-*/;

  /**
   * Returns the element that was the actual target of the given event.
   * 
   * @return the target element
   */
  public final EventTarget getEventTarget() {
    return DOMImpl.impl.eventGetTarget(this);
  }

  /**
   * Gets the key code (code associated with the physical key) associated with
   * this event.
   * 
   * @return the key code
   * @see com.google.gwt.event.dom.client.KeyCodes
   */
  public final int getKeyCode() {
    return DOMImpl.impl.eventGetKeyCode(this);
  }

  /**
   * Gets whether the META key was depressed when the given event occurred.
   * 
   * @return <code>true</code> if META was depressed when the event occurred
   */
  public final boolean getMetaKey() {
    return DOMImpl.impl.eventGetMetaKey(this);
  }

  /**
   * Gets the sign of the velocity of the mouse wheel associated with the event along the Y
   * axis.
   * <p>
   * In previous versions of GWT this returned the velocity normalized to a small integer.
   * Unfortunately for some devices such normalization rounded non-trivial velocities to 0.
   * To maintain compatibility with that implementation, this still returns an integer,
   * but using the sign function
   * </p>
   * 
   * @return The velocity of the mouse wheel: -1 for scrolling up, 1 for scrolling down,
   *         0 if not scrolled at all
   * @deprecated use getDeltaY() instead
   */
  @Deprecated
  public final int getMouseWheelVelocityY() {
    return DOMImpl.impl.eventGetMouseWheelVelocityY(this);
  }

  /**
   * Gets the native velocity of the mouse wheel in Y direction.
   * @return The velocity of the mouse wheel
   */
  public final native double getDeltaY() /*-{
    return this.deltaY;
  }-*/;

  /**
   * Gets the native velocity of the mouse wheel in X direction.
   * @return The velocity of the mouse wheel
   */
  public final native double getDeltaX() /*-{
    return this.deltaX;
  }-*/;

  /**
   * Gets the related target for this event.
   * 
   * @return the related target
   */
  public final EventTarget getRelatedEventTarget() {
    return DOMImpl.impl.eventGetRelatedTarget(this);
  }

  /**
   * Get the rotation in degrees, with positive values indicating clockwise rotation.
   * 
   * @return the rotation in degrees since the gesture started
   */
  public final double getRotation() {
    return DOMImpl.impl.eventGetRotation(this);
  }

  /**
   * Get the amount scaled since the gesture started, with 1.0 representing no scaling.
   * 
   * @return the amount scaled since the gesture started
   */
  public final double getScale() {
    return DOMImpl.impl.eventGetScale(this);
  }

  /**
   * Gets the mouse x-position on the user's display.
   * 
   * @return the mouse x-position
   */
  public final int getScreenX() {
    return DOMImpl.impl.eventGetScreenX(this);
  }

  /**
   * Gets the mouse y-position on the user's display.
   * 
   * @return the mouse y-position
   */
  public final int getScreenY() {
    return DOMImpl.impl.eventGetScreenY(this);
  }

  /**
   * Gets whether the shift key was depressed when the given event occurred.
   * 
   * @return <code>true</code> if shift was depressed when the event occurred
   */
  public final boolean getShiftKey() {
    return DOMImpl.impl.eventGetShiftKey(this);
  }

  /**
   * Gets a string representation of this event.
   * 
   * We do not override {@link #toString()} because it is final in
   * {@link com.google.gwt.core.client.JavaScriptObject }.
   * 
   * @return the string representation of this event
   */
  public final String getString() {
    return DOMImpl.impl.eventToString(this);
  }

  /**
   * Get an array of touches which have changed since the last touch event.
   * 
   * @return array of touches which have changed since the last touch event
   */
  public final JsArray<Touch> getTargetTouches() {
    return DOMImpl.impl.getTargetTouches(this);
  }

  /**
   * Get an array of touches which have changed since the last touch event.
   * 
   * @return array of touches which have changed since the last touch event
   */
  public final JsArray<Touch> getTouches() {
    return DOMImpl.impl.getTouches(this);
  }

  /**
   * Gets the enumerated type of this event.
   * 
   * @return the event's enumerated type
   */
  public final String getType() {
    return DOMImpl.impl.eventGetType(this);
  }

  /**
   * Prevents the browser from taking its default action for the given event.
   */
  public final void preventDefault() {
    DOMImpl.impl.eventPreventDefault(this);
  }

  /**
   * Stops the event from being propagated to parent elements.
   */
  public final void stopPropagation() {
    DOMImpl.impl.eventStopPropagation(this);
  }
}
