// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_VIEWS_FOCUS_FOCUS_MANAGER_H_
#define UI_VIEWS_FOCUS_FOCUS_MANAGER_H_

#include <list>
#include <map>

#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/accelerators/accelerator_manager.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/views_export.h"

// The FocusManager class is used to handle focus traversal, store/restore
// focused views and handle keyboard accelerators.
//
// There are 2 types of focus:
// - the native focus, which is the focus that an gfx::NativeView has.
// - the view focus, which is the focus that a views::View has.
//
// Each native view must register with their Focus Manager so the focus manager
// gets notified when they are focused (and keeps track of the native focus) and
// as well so that the tab key events can be intercepted.
// They can provide when they register a View that is kept in synch in term of
// focus. This is used in NativeControl for example, where a View wraps an
// actual native window.
// This is already done for you if you subclass the NativeControl class or if
// you use the NativeViewHost class.
//
// When creating a top window (derived from views::Widget) that is not a child
// window, it creates and owns a FocusManager to manage the focus for itself and
// all its child windows.
//
// The FocusTraversable interface exposes the methods a class should implement
// in order to be able to be focus traversed when tab key is pressed.
// RootViews implement FocusTraversable.
// The FocusManager contains a top FocusTraversable instance, which is the top
// RootView.
//
// If you just use views, then the focus traversal is handled for you by the
// RootView. The default traversal order is the order in which the views have
// been added to their container. You can modify this order by using the View
// method SetNextFocusableView().
//
// If you are embedding a native view containing a nested RootView (for example
// by adding a NativeControl that contains a NativeWidgetWin as its native
// component), then you need to:
// - override the View::GetFocusTraversable() method in your outer component.
//   It should return the RootView of the inner component. This is used when
//   the focus traversal traverse down the focus hierarchy to enter the nested
//   RootView. In the example mentioned above, the NativeControl overrides
//   GetFocusTraversable() and returns hwnd_view_container_->GetRootView().
// - call Widget::SetFocusTraversableParent() on the nested RootView and point
//   it to the outer RootView. This is used when the focus goes out of the
//   nested RootView. In the example:
//   hwnd_view_container_->GetWidget()->SetFocusTraversableParent(
//      native_control->GetRootView());
// - call RootView::SetFocusTraversableParentView() on the nested RootView with
//   the parent view that directly contains the native window. This is needed
//   when traversing up from the nested RootView to know which view to start
//   with when going to the next/previous view.
//   In our example:
//   hwnd_view_container_->GetWidget()->SetFocusTraversableParent(
//      native_control);
//
// Note that FocusTraversable do not have to be RootViews: AccessibleToolbarView
// is FocusTraversable.

namespace ui {
class AcceleratorManager;
class AcceleratorTarget;
class EventHandler;
class KeyEvent;
}

namespace views {

class FocusManagerDelegate;
class FocusSearch;
class View;
class Widget;

// The FocusTraversable interface is used by components that want to process
// focus traversal events (due to Tab/Shift-Tab key events).
class VIEWS_EXPORT FocusTraversable {
 public:
  // Return a FocusSearch object that implements the algorithm to find
  // the next or previous focusable view.
  virtual FocusSearch* GetFocusSearch() = 0;

  // Should return the parent FocusTraversable.
  // The top RootView which is the top FocusTraversable returns NULL.
  virtual FocusTraversable* GetFocusTraversableParent() = 0;

  // This should return the View this FocusTraversable belongs to.
  // It is used when walking up the view hierarchy tree to find which view
  // should be used as the starting view for finding the next/previous view.
  virtual View* GetFocusTraversableParentView() = 0;

 protected:
  virtual ~FocusTraversable() {}
};

// This interface should be implemented by classes that want to be notified when
// the focus is about to change.  See the Add/RemoveFocusChangeListener methods.
class VIEWS_EXPORT FocusChangeListener {
 public:
  // No change to focus state has occurred yet when this function is called.
  virtual void OnWillChangeFocus(View* focused_before, View* focused_now) = 0;

  // Called after focus state has changed.
  virtual void OnDidChangeFocus(View* focused_before, View* focused_now) = 0;

 protected:
  virtual ~FocusChangeListener() {}
};

class VIEWS_EXPORT FocusManager {
 public:
  // The reason why the focus changed.
  enum FocusChangeReason {
    // The focus changed because the user traversed focusable views using
    // keys like Tab or Shift+Tab.
    kReasonFocusTraversal,

    // The focus changed due to restoring the focus.
    kReasonFocusRestore,

    // The focus changed due to a click or a shortcut to jump directly to
    // a particular view.
    kReasonDirectFocusChange
  };

  // TODO: use Direction in place of bool reverse throughout.
  enum Direction {
    kForward,
    kBackward
  };

  enum FocusCycleWrappingBehavior {
    kWrap,
    kNoWrap
  };

  FocusManager(Widget* widget, FocusManagerDelegate* delegate);
  virtual ~FocusManager();

  // Processes the passed key event for accelerators and keyboard traversal.
  // Returns false if the event has been consumed and should not be processed
  // further.
  bool OnKeyEvent(const ui::KeyEvent& event);

  // Returns true is the specified is part of the hierarchy of the window
  // associated with this FocusManager.
  bool ContainsView(View* view);

  // Advances the focus (backward if reverse is true).
  void AdvanceFocus(bool reverse);

  // The FocusManager keeps track of the focused view within a RootView.
  View* GetFocusedView() { return focused_view_; }
  const View* GetFocusedView() const { return focused_view_; }

  // Low-level methods to force the focus to change (and optionally provide
  // a reason). If the focus change should only happen if the view is
  // currenty focusable, enabled, and visible, call view->RequestFocus().
  void SetFocusedViewWithReason(View* view, FocusChangeReason reason);
  void SetFocusedView(View* view) {
    SetFocusedViewWithReason(view, kReasonDirectFocusChange);
  }

  // Get the reason why the focus most recently changed.
  FocusChangeReason focus_change_reason() const {
    return focus_change_reason_;
  }

  // Clears the focused view. The window associated with the top root view gets
  // the native focus (so we still get keyboard events).
  void ClearFocus();

  // Tries to advance focus if the focused view has become unfocusable. If there
  // is no view available to advance focus to, focus will be cleared.
  void AdvanceFocusIfNecessary();

  // Validates the focused view, clearing it if the window it belongs too is not
  // attached to the window hierarchy anymore.
  void ValidateFocusedView();

  // Stores the focused view. Used when the widget loses activation.
  // |clear_native_focus| indicates whether this should invoke ClearFocus().
  // Typically |true| should be passed in.
  void StoreFocusedView(bool clear_native_focus);

  // Restore the view saved with a previous call to StoreFocusedView(). Used
  // when the widget becomes active. Returns true when the previous view was
  // successfully refocused - otherwise false.
  bool RestoreFocusedView();

  // Sets the |view| to be restored when calling RestoreFocusView. This is used
  // to set where the focus should go on restoring a Window created without
  // focus being set.
  void SetStoredFocusView(View* view);

  // Returns the View that either currently has focus, or if no view has focus
  // the view that last had focus.
  View* GetStoredFocusView();

  // Clears the stored focused view.
  void ClearStoredFocusedView();

  // Returns true if in the process of changing the focused view.
  bool is_changing_focus() const { return is_changing_focus_; }

  // Changes the text input focus to |view->GetTextInputClient()| iff |view|
  // is focused.  Views must call this method when their internal
  // TextInputClient instance changes.
  void OnTextInputClientChanged(View* view);

  // Moves the text input focus into/out from |view|.
  void FocusTextInputClient(View* view);
  void BlurTextInputClient(View* view);

  // Disable shortcut handling.
  static void set_shortcut_handling_suspended(bool suspended) {
    shortcut_handling_suspended_ = suspended;
  }
  // Returns whether shortcut handling is currently suspended.
  bool shortcut_handling_suspended() { return shortcut_handling_suspended_; }

  // Register a keyboard accelerator for the specified target. If multiple
  // targets are registered for an accelerator, a target registered later has
  // higher priority.
  // |accelerator| is the accelerator to register.
  // |priority| denotes the priority of the handler.
  // NOTE: In almost all cases, you should specify kNormalPriority for this
  // parameter. Setting it to kHighPriority prevents Chrome from sending the
  // shortcut to the webpage if the renderer has focus, which is not desirable
  // except for very isolated cases.
  // |target| is the AcceleratorTarget that handles the event once the
  // accelerator is pressed.
  // Note that we are currently limited to accelerators that are either:
  // - a key combination including Ctrl or Alt
  // - the escape key
  // - the enter key
  // - any F key (F1, F2, F3 ...)
  // - any browser specific keys (as available on special keyboards)
  void RegisterAccelerator(const ui::Accelerator& accelerator,
                           ui::AcceleratorManager::HandlerPriority priority,
                           ui::AcceleratorTarget* target);

  // Unregister the specified keyboard accelerator for the specified target.
  void UnregisterAccelerator(const ui::Accelerator& accelerator,
                             ui::AcceleratorTarget* target);

  // Unregister all keyboard accelerator for the specified target.
  void UnregisterAccelerators(ui::AcceleratorTarget* target);

  // Activate the target associated with the specified accelerator.
  // First, AcceleratorPressed handler of the most recently registered target
  // is called, and if that handler processes the event (i.e. returns true),
  // this method immediately returns. If not, we do the same thing on the next
  // target, and so on.
  // Returns true if an accelerator was activated.
  bool ProcessAccelerator(const ui::Accelerator& accelerator);

  // Resets menu key state if |event| is not menu key release.
  // This is effective only on x11.
  void MaybeResetMenuKeyState(const ui::KeyEvent& key);

  // Called by a RootView when a view within its hierarchy is removed
  // from its parent. This will only be called by a RootView in a
  // hierarchy of Widgets that this FocusManager is attached to the
  // parent Widget of.
  void ViewRemoved(View* removed);

  // Adds/removes a listener.  The FocusChangeListener is notified every time
  // the focused view is about to change.
  void AddFocusChangeListener(FocusChangeListener* listener);
  void RemoveFocusChangeListener(FocusChangeListener* listener);

  // Returns the AcceleratorTarget that should be activated for the specified
  // keyboard accelerator, or NULL if no view is registered for that keyboard
  // accelerator.
  ui::AcceleratorTarget* GetCurrentTargetForAccelerator(
      const ui::Accelerator& accelertor) const;

  // Whether the given |accelerator| has a priority handler associated with it.
  bool HasPriorityHandler(const ui::Accelerator& accelerator) const;

  // Clears the native view having the focus.
  virtual void ClearNativeFocus();

  // Focuses the next keyboard-accessible pane, taken from the list of
  // views returned by WidgetDelegate::GetAccessiblePanes(). If there are
  // no panes, the widget's root view is treated as a single pane.
  // A keyboard-accessible pane should subclass from AccessiblePaneView in
  // order to trap keyboard focus within that pane. If |wrap| is kWrap,
  // it keeps cycling within this widget, otherwise it returns false after
  // reaching the last pane so that focus can cycle to another widget.
  bool RotatePaneFocus(Direction direction, FocusCycleWrappingBehavior wrap);

  // Convenience method that returns true if the passed |key_event| should
  // trigger tab traversal (if it is a TAB key press with or without SHIFT
  // pressed).
  static bool IsTabTraversalKeyEvent(const ui::KeyEvent& key_event);

  // Sets whether arrow key traversal is enabled. When enabled, right/down key
  // behaves like tab and left/up key behaves like shift-tab. Note when this
  // is enabled, the arrow key movement within grouped views are disabled.
  static void set_arrow_key_traversal_enabled(bool enabled) {
    arrow_key_traversal_enabled_ = enabled;
  }
  // Returns whether arrow key traversal is enabled.
  static bool arrow_key_traversal_enabled() {
    return arrow_key_traversal_enabled_;
  }

  // Returns the next focusable view. Traversal starts at |starting_view|. If
  // |starting_view| is NULL |starting_widget| is consuled to determine which
  // Widget to start from. See
  // WidgetDelegate::ShouldAdvanceFocusToTopLevelWidget() for details. If both
  // |starting_view| and |starting_widget| are NULL, traversal starts at
  // |widget_|.
  View* GetNextFocusableView(View* starting_view,
                             Widget* starting_widget,
                             bool reverse,
                             bool dont_loop);

 private:
  // Returns the focusable view found in the FocusTraversable specified starting
  // at the specified view. This traverses down along the FocusTraversable
  // hierarchy.
  // Returns NULL if no focusable view were found.
  View* FindFocusableView(FocusTraversable* focus_traversable,
                          View* starting_view,
                          bool reverse);

  // Process arrow key traversal. Returns true if the event has been consumed
  // and should not be processed further.
  bool ProcessArrowKeyTraversal(const ui::KeyEvent& event);

  // Keeps track of whether shortcut handling is currently suspended.
  static bool shortcut_handling_suspended_;

  // Whether arrow key traversal is enabled.
  static bool arrow_key_traversal_enabled_;

  // The top-level Widget this FocusManager is associated with.
  Widget* widget_;

  // The object which handles an accelerator when |accelerator_manager_| doesn't
  // handle it.
  scoped_ptr<FocusManagerDelegate> delegate_;

  // The view that currently is focused.
  View* focused_view_;

  // The AcceleratorManager this FocusManager is associated with.
  scoped_ptr<ui::AcceleratorManager> accelerator_manager_;

  // The storage id used in the ViewStorage to store/restore the view that last
  // had focus.
  int stored_focused_view_storage_id_;

  // The reason why the focus most recently changed.
  FocusChangeReason focus_change_reason_;

  // The list of registered FocusChange listeners.
  ObserverList<FocusChangeListener, true> focus_change_listeners_;

  // See description above getter.
  bool is_changing_focus_;

  DISALLOW_COPY_AND_ASSIGN(FocusManager);
};

}  // namespace views

#endif  // UI_VIEWS_FOCUS_FOCUS_MANAGER_H_
