content: /*
   * Created on Mar 1, 2008
   * 
   * 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.
   * 
   * Copyright @2008-2013 the original author or authors.
   */
  package org.fest.swing.core;
  
  import java.awt.Component;
  import java.awt.Dimension;
  import java.awt.Point;
  import java.awt.Window;
  import java.awt.event.InputEvent;
  
  import javax.annotation.Nonnull;
  import javax.annotation.Nullable;
  import javax.swing.JPopupMenu;
  
  import org.fest.swing.exception.ActionFailedException;
  import org.fest.swing.exception.ComponentLookupException;
  import org.fest.swing.hierarchy.ComponentHierarchy;
  import org.fest.swing.lock.ScreenLock;
  
  /**
   * Simulates user input on an AWT or Swing {@code Component}.
   * 
   * @author Alex Ruiz
   * @author Yvonne Wang
   */
  public interface Robot {
    /**
     * @return the {@code ComponentHierarchy} being used by this robot.
     */
    @Nonnull ComponentHierarchy hierarchy();
  
    /**
     * @return the {@code ComponentFinder} being used by this robot.
     */
    @Nonnull ComponentFinder finder();
  
    /**
     * @return the {@code ComponentPrinter} being used by this robot.
     */
    @Nonnull ComponentPrinter printer();
  
    /**
     * Safely display an AWT or Swing {@code Window} with proper EDT synchronization. This method blocks until the
     * {@code Window} is showing and ready for input.
     * 
     * @param w the window to display.
     */
    void showWindow(@Nonnull Window w);
  
    /**
     * Safely display an AWT or Swing {@code Window} with proper EDT synchronization. This method blocks until the
     * {@code Window} is showing and ready for input.
     * 
     * @param w the window to display.
     * @param size the size of the window to display.
     */
    void showWindow(@Nonnull Window w, @Nonnull Dimension size);
  
    /**
     * <p>
     * Safely display an AWT or Swing {@code Window} with proper EDT synchronization. This method blocks until the
     * {@code Window} is showing. This method will return even when the window is a modal dialog, since the show method is
     * called on the event dispatch thread (EDT.) The {@code Window} will be packed if the pack flag is set, and set to
     * the given size if it is non-{@code null}.
     * </p>
     * 
     * <p>
     * Modal dialogs may be shown with this method without blocking.
     * </p>
     * 
     * @param w the window to display.
     * @param size the size of the window to display. A {@code null} value indicates that the window does not need to be
     *          resized.
     * @param pack flag that indicates if the window should be packed or not. By packed we mean calling {@code w.pack()}.
     */
    void showWindow(@Nonnull Window w, @Nullable Dimension size, boolean pack);
  
    /**
     * Simulates a user closing the given AWT or Swing {@code Window}.
     * 
     * @param w the {@code Window} to close.
     */
    void close(@Nonnull Window w);
  
    /**
     * Gives input focus to the given AWT or Swing {@code Component}. Note that the {@code Component} may not yet have
     * focus when this method returns.
     * 
     * @param c the {@code Component} to give focus to.
     */
    void focus(@Nonnull Component c);
  
    /**
     * Gives input focus to the given AWT or Swing {@code Component} and waits until the {@code Component} has focus.
     * 
     * @param c the {@code Component} to give focus to.
     */
    void focusAndWaitForFocusGain(@Nonnull Component c);
  
    /**
     * Cleans up any used resources (keyboard, mouse, open windows and {@link ScreenLock}) used by this {@code Robot}.
     */
    void cleanUp();
  
    /**
     * <p>
     * Cleans up any used resources (keyboard, mouse and {@link ScreenLock}) used by this {@code Robot}. This method
     * <strong>does not</strong> dispose any open windows.
     * </p>
     * 
     * <p>
     * <strong>Note:</strong> The preferred method to use to clean up resources is {@link #cleanUp()}. Using
     * {@link #cleanUpWithoutDisposingWindows()} may leave many windows open after each test. Use it on very
     * special cases. Please read <a href="http://code.google.com/p/fest/issues/detail?id=138" target="_blank">bug 138</a>
     * for more details.
     * </p>
     */
    void cleanUpWithoutDisposingWindows();
  
    /**
     * Simulates a user clicking once the given AWT or Swing {@code Component} using the left mouse button.
     * 
     * @param c the {@code Component} to click on.
     * @throws ActionFailedException if the {@code Component} to click is out of the boundaries of the screen.
     */
    void click(@Nonnull Component c);
  
    /**
     * Simulates a user right-clicking the given AWT or Swing {@code Component}.
     * 
     * @param c the {@code Component} to click on.
     * @throws ActionFailedException if the {@code Component} to click is out of the boundaries of the screen.
     */
    void rightClick(@Nonnull Component c);
  
    /**
     * Simulates a user clicking once the given AWT or Swing {@code Component} using the given mouse button.
     * 
     * @param c the {@code Component} to click on.
     * @param button the mouse button to use.
     * @throws ActionFailedException if the {@code Component} to click is out of the boundaries of the screen.
     */
    void click(@Nonnull Component c, @Nonnull MouseButton button);
  
    /**
     * Simulates a user double-clicking the given AWT or Swing {@code Component}.
     * 
     * @param c the {@code Component} to click on.
     * @throws ActionFailedException if the {@code Component} to click is out of the boundaries of the screen.
     */
    void doubleClick(@Nonnull Component c);
  
    /**
     * Simulates a user clicking the given mouse button, the given times on the given AWT or Swing {@code Component}.
     * 
     * @param c the {@code Component} to click on.
     * @param button the mouse button to click.
     * @param times the number of times to click the given mouse button.
     * @throws ActionFailedException if the {@code Component} to click is out of the boundaries of the screen.
     */
    void click(@Nonnull Component c, @Nonnull MouseButton button, int times);
  
    /**
     * Simulates a user clicking at the given position on the given AWT or Swing {@code Component}.
     * 
     * @param c the {@code Component} to click on.
     * @param where the given coordinates, relative to the given {@code Component}.
     * @throws ActionFailedException if the {@code Component} to click is out of the boundaries of the screen.
     */
    void click(@Nonnull Component c, @Nonnull Point where);
  
    /**
     * Simulates a user clicking the given mouse button, the given times at the given position on the given AWT or Swing
     * {@code Component}.
     * 
     * @param c the {@code Component} to click on.
     * @param where the given coordinates, relative to the given {@code Component}.
     * @param button the mouse button to click.
     * @param times the number of times to click the given mouse button.
     * @throws ActionFailedException if the {@code Component} to click is out of the boundaries of the screen.
     */
    void click(@Nonnull Component c, @Nonnull Point where, @Nonnull MouseButton button, int times);
  
    /**
     * Simulates a user clicking the given mouse button, the given times at the given absolute coordinates.
     * 
     * @param where the coordinates where to click.
     * @param button the mouse button to click.
     * @param times the number of times to click the given mouse button.
     */
    void click(@Nonnull Point where, @Nonnull MouseButton button, int times);
  
    /**
     * Simulates a user pressing a mouse button.
     * 
     * @param button the mouse button to press.
     */
    void pressMouse(@Nonnull MouseButton button);
  
    /**
     * Simulates a user pressing the left mouse button on the given AWT or Swing {@code Component}.
     * 
     * @param c the {@code Component} to click on.
     * @param where the given coordinates, relative to the given {@code Component}.
     */
    void pressMouse(@Nonnull Component c, @Nonnull Point where);
  
    /**
     * Simulates a user pressing the given mouse button on the given AWT or Swing {@code Component}.
     * 
     * @param c the {@code Component} to click on.
     * @param where the given coordinates, relative to the given {@code Component}.
     * @param button the mouse button to press.
     */
    void pressMouse(@Nonnull Component c, @Nonnull Point where, @Nonnull MouseButton button);
  
    /**
     * Simulates a user pressing the given mouse button on the given coordinates.
     * 
     * @param where the position where to press the given mouse button.
     * @param button the mouse button to press.
     * @since 1.1
     */
    void pressMouse(@Nonnull Point where, @Nonnull MouseButton button);
  
    /**
     * Simulates a user moving the mouse pointer to the center of the given AWT or Swing {@code Component}.
     * 
     * @param c the given {@code Component}.
     */
    void moveMouse(@Nonnull Component c);
  
    /**
     * Simulates a user moving the mouse pointer to the given coordinates relative to the given AWT or Swing
     * {@code Component}.
     * 
     * @param c the given {@code Component}.
     * @param p the given coordinates, relative to the given {@code Component}.
     * @throws ActionFailedException if the given {@code Component} is not showing and ready for input.
     */
    void moveMouse(@Nonnull Component c, @Nonnull Point p);
  
    /**
     * Simulates a user moving the mouse pointer to the given coordinates relative to the given AWT or Swing
     * {@code Component}.
     * 
     * @param c the given {@code Component}.
     * @param x X coordinate, relative to the given {@code Component}.
     * @param y Y coordinate, relative to the given {@code Component}.
     * @throws ActionFailedException if the given {@code Component} is not showing and ready for input.
     */
    void moveMouse(@Nonnull Component c, int x, int y);
  
    /**
     * Simulates a user moving the mouse pointer to the given coordinates.
     * 
     * @param p the given coordinates.
     * @since 1.1
     */
    void moveMouse(@Nonnull Point p);
  
    /**
     * Simulates a user moving the mouse pointer to the given coordinates.
     * 
     * @param x X coordinate.
     * @param y Y coordinate.
     * @since 1.1
     */
    void moveMouse(int x, int y);
  
    /**
     * Releases the given mouse button.
     * 
     * @param button the mouse button to release.
     */
    void releaseMouse(@Nonnull MouseButton button);
  
    /**
     * Releases any mouse button(s) used by the robot.
     */
    void releaseMouseButtons();
  
    /**
     * Moves the mouse pointer over to the given AWT or Swing {@code Component} and rotates the scroll wheel on
     * wheel-equipped mice.
     * 
     * @param c the given {@code Component}.
     * @param amount number of "notches" to move the mouse wheel. Negative values indicate movement up/away from the user,
     *          while positive values indicate movement down/towards the user.
     */
    void rotateMouseWheel(@Nonnull Component c, int amount);
  
    /**
     * Rotates the scroll wheel on wheel-equipped mice.
     * 
     * @param amount number of "notches" to move the mouse wheel. Negative values indicate movement up/away from the user,
     *          while positive values indicate movement down/towards the user.
     */
    void rotateMouseWheel(int amount);
  
    /**
     * Makes the mouse pointer show small quick jumpy movements on the given AWT or Swing {@code Component}.
     * 
     * @param c the given {@code Component}.
     */
    void jitter(@Nonnull Component c);
  
    /**
     * Makes the mouse pointer show small quick jumpy movements on the given AWT or Swing {@code Component} at the given
     * point.
     * 
     * @param c the given {@code Component}.
     * @param where the given point.
     */
    void jitter(@Nonnull Component c, @Nonnull Point where);
  
    /**
     * Simulates a user entering the given text. Note that this method the key strokes to the AWT or Swing
     * {@code Component} that has input focus.
     * 
     * @param text the text to enter.
     */
    void enterText(@Nonnull String text);
  
    /**
     * Types the given character. Note that this method sends the key strokes to the AWT or Swing {@code Component} that
     * has input focus.
     * 
     * @param character the character to type.
     */
    void type(char character);
  
    /**
     * Type the given key code with the given modifiers. Modifiers is a mask from the available
     * {@code java.awt.event.InputEvent} masks.
     * 
     * @param keyCode the code of the key to press.
     * @param modifiers the given modifiers.
     * @throws IllegalArgumentException if the given code is not a valid key code.
     */
    void pressAndReleaseKey(int keyCode, @Nonnull int... modifiers);
  
    /**
     * Simulates a user pressing and releasing the given keys. This method does not affect the current focus.
     * 
     * @param keyCodes one or more codes of the keys to press.
     * @see java.awt.event.KeyEvent
     * @throws IllegalArgumentException if any of the given codes is not a valid key code.
     */
    void pressAndReleaseKeys(@Nonnull int... keyCodes);
  
    /**
     * Simulates a user pressing given key. This method does not affect the current focus.
     * 
     * @param keyCode the code of the key to press.
     * @see java.awt.event.KeyEvent
     * @throws IllegalArgumentException if the given code is not a valid key code.
     */
    void pressKey(int keyCode);
  
    /**
     * Simulates a user releasing the given key. This method does not affect the current focus.
     * 
     * @param keyCode the code of the key to release.
     * @see java.awt.event.KeyEvent
     * @throws IllegalArgumentException if the given code is not a valid key code.
     */
    void releaseKey(int keyCode);
  
    /**
     * Presses the appropriate modifiers corresponding to the given mask. Use mask values from
     * {@code java.awt.event.InputEvent}.
     * 
     * @param modifierMask the given mask.
     * @see InputEvent
     */
    void pressModifiers(int modifierMask);
  
    /**
     * Releases the appropriate modifiers corresponding to the given mask. Use mask values from
     * {@code java.awt.event.InputEvent}.
     * 
     * @param modifierMask the given mask.
     * @see InputEvent
     */
    void releaseModifiers(int modifierMask);
  
    /**
     * Wait for an idle AWT event queue. Note that this is different from the implementation of
     * {@code java.awt.Robot.waitForIdle()}, which may have events on the queue when it returns. Do <strong>NOT</strong>
     * use this method if there are animations or other continual refreshes happening, since in that case it may never
     * return.
     * 
     * @throws IllegalThreadStateException if this method is called from the event dispatch thread (EDT.)
     */
    void waitForIdle();
  
    /**
     * Indicates whether the robot is currently in a dragging operation.
     * 
     * @return {@code true} if the robot is currently in a dragging operation, {@code false} otherwise.
     */
    boolean isDragging();
  
    /**
     * Indicates whether the given AWT or Swing {@code Component} is ready for input.
     * 
     * @param c the given {@code Component}.
     * @return {@code true} if the given {@code Component} is ready for input, {@code false} otherwise.
     * @throws ActionFailedException if the given {@code Component} does not have a {@code Window} ancestor.
     */
    boolean isReadyForInput(@Nonnull Component c);
  
    /**
     * Shows a {@code JPopupMenu}.
     * 
     * @param invoker the {@code Component} to invoke the {@code JPopupMenu} from.
     * @return the displayed {@code JPopupMenu}.
     * @throws ComponentLookupException if a {@code JPopupMenu} cannot be found.
     */
    @Nonnull JPopupMenu showPopupMenu(@Nonnull Component invoker);
  
    /**
     * Shows a {@code JPopupMenu} at the given coordinates.
     * 
     * @param invoker the {@code Component} to invoke the {@code JPopupMenu} from.
     * @param location the given coordinates for the {@code JPopupMenu}.
     * @return the displayed {@code JPopupMenu}.
     * @throws ComponentLookupException if a {@code JPopupMenu} cannot be found.
     */
    @Nonnull JPopupMenu showPopupMenu(@Nonnull Component invoker, @Nonnull Point location);
  
    /**
     * @return the currently active {@code JPopupMenu} or {@code null}, if no pop-up is currently showing.
     */
    @Nullable JPopupMenu findActivePopupMenu();
  
    /**
     * Ensures that there is no {@code JOptionPane} showing, and potentially blocking GUI tests.
     * 
     * @throws AssertionError if there is one or more {@code JOptionPane}s showing on the screen.
     */
    void requireNoJOptionPaneIsShowing();
  
    /**
     * @return the configuration settings for this {@code Robot}.
     */
    @Nonnull Settings settings();
  
    /**
     * Indicates whether this {@code Robot} is active. Being "active" means that {@link #cleanUp()} has not been called
     * yet.
     * 
     * @return {@code true} if this {@code Robot} is active, {@code false} otherwise.
     */
    boolean isActive();
  }