// 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_AURA_REMOTE_WINDOW_TREE_HOST_WIN_H_
#define UI_AURA_REMOTE_WINDOW_TREE_HOST_WIN_H_

#include <vector>

#include "base/compiler_specific.h"
#include "base/strings/string16.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/ime/remote_input_method_delegate_win.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_source.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/metro_viewer/ime_types.h"

struct MetroViewerHostMsg_MouseButtonParams;

namespace base {
class FilePath;
}

namespace ui {
class RemoteInputMethodPrivateWin;
class ViewProp;
}

namespace IPC {
class Message;
class Sender;
}

namespace aura {

// WindowTreeHost implementaton that receives events from a different
// process. In the case of Windows this is the Windows 8 (aka Metro)
// frontend process, which forwards input events to this class.
class AURA_EXPORT RemoteWindowTreeHostWin
    : public WindowTreeHost,
      public ui::internal::RemoteInputMethodDelegateWin {
 public:
  // Returns the current RemoteWindowTreeHostWin. This does *not* create a
  // RemoteWindowTreeHostWin.
  static RemoteWindowTreeHostWin* Instance();

  // Returns true if there is a RemoteWindowTreeHostWin and it has a valid
  // HWND. A return value of false typically indicates we're not in metro mode.
  static bool IsValid();

  // Sets the handle to the remote window. The |remote_window| is the actual
  // window owned by the viewer process. Call this before Connected() for some
  // customers like input method initialization which needs the handle.
  void SetRemoteWindowHandle(HWND remote_window);
  HWND remote_window() { return remote_window_; }

  // The |host| can be used when we need to send a message to it.
  void Connected(IPC::Sender* host);
  // Called when the remote process has closed its IPC connection.
  void Disconnected();

  // Called when we have a message from the remote process.
  bool OnMessageReceived(const IPC::Message& message);

  void HandleOpenURLOnDesktop(const base::FilePath& shortcut,
                              const base::string16& url);

  void HandleWindowSizeChanged(uint32 width, uint32 height);

  // Returns the active ASH root window.
  Window* GetAshWindow();

  // Returns true if the remote window is the foreground window according to the
  // OS.
  bool IsForegroundWindow();

 protected:
  RemoteWindowTreeHostWin();
  ~RemoteWindowTreeHostWin() override;

 private:
  // IPC message handing methods:
  void OnMouseMoved(int32 x, int32 y, int32 flags);
  void OnMouseButton(const MetroViewerHostMsg_MouseButtonParams& params);
  void OnKeyDown(uint32 vkey,
                 uint32 repeat_count,
                 uint32 scan_code,
                 uint32 flags);
  void OnKeyUp(uint32 vkey,
               uint32 repeat_count,
               uint32 scan_code,
               uint32 flags);
  void OnChar(uint32 key_code,
              uint32 repeat_count,
              uint32 scan_code,
              uint32 flags);
  void OnWindowActivated(bool repaint);
  void OnEdgeGesture();
  void OnTouchDown(int32 x, int32 y, uint64 timestamp, uint32 pointer_id);
  void OnTouchUp(int32 x, int32 y, uint64 timestamp, uint32 pointer_id);
  void OnTouchMoved(int32 x, int32 y, uint64 timestamp, uint32 pointer_id);
  void OnSetCursorPosAck();

  // For Input Method support:
  ui::RemoteInputMethodPrivateWin* GetRemoteInputMethodPrivate();
  void OnImeCandidatePopupChanged(bool visible);
  void OnImeCompositionChanged(
      const base::string16& text,
      int32 selection_start,
      int32 selection_end,
      const std::vector<metro_viewer::UnderlineInfo>& underlines);
  void OnImeTextCommitted(const base::string16& text);
  void OnImeInputSourceChanged(uint16 language_id, bool is_ime);

  // WindowTreeHost overrides:
  ui::EventSource* GetEventSource() override;
  gfx::AcceleratedWidget GetAcceleratedWidget() override;
  void ShowImpl() override;
  void HideImpl() override;
  gfx::Rect GetBounds() const override;
  void SetBounds(const gfx::Rect& bounds) override;
  gfx::Point GetLocationOnNativeScreen() const override;
  void SetCapture() override;
  void ReleaseCapture() override;
  void SetCursorNative(gfx::NativeCursor cursor) override;
  void MoveCursorToNative(const gfx::Point& location) override;
  void OnCursorVisibilityChangedNative(bool show) override;

  // ui::internal::RemoteInputMethodDelegateWin overrides:
  void CancelComposition() override;
  void OnTextInputClientUpdated(
      const std::vector<int32>& input_scopes,
      const std::vector<gfx::Rect>& composition_character_bounds) override;

  // Helper function to dispatch a keyboard message to the desired target.
  // The default target is the WindowEventDispatcher. For nested message loop
  // invocations we post a synthetic keyboard message directly into the message
  // loop. The dispatcher for the nested loop would then decide how this
  // message is routed.
  void DispatchKeyboardMessage(ui::EventType type,
                               uint32 vkey,
                               uint32 repeat_count,
                               uint32 scan_code,
                               uint32 flags,
                               bool is_character);

  // Sets the event flags. |flags| is a bitmask of EventFlags. If there is a
  // change the system virtual key state is updated as well. This way if chrome
  // queries for key state it matches that of event being dispatched.
  void SetEventFlags(uint32 flags);

  uint32 mouse_event_flags() const {
    return event_flags_ & (ui::EF_LEFT_MOUSE_BUTTON |
                           ui::EF_MIDDLE_MOUSE_BUTTON |
                           ui::EF_RIGHT_MOUSE_BUTTON);
  }

  uint32 key_event_flags() const {
    return event_flags_ & (ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN |
                           ui::EF_ALT_DOWN | ui::EF_CAPS_LOCK_DOWN);
  }

  HWND remote_window_;
  IPC::Sender* host_;
  scoped_ptr<ui::ViewProp> prop_;

  // Incremented if we need to ignore mouse messages until the SetCursorPos
  // operation is acked by the viewer.
  int ignore_mouse_moves_until_set_cursor_ack_;

  // Tracking last click event for synthetically generated mouse events.
  scoped_ptr<ui::MouseEvent> last_mouse_click_event_;

  // State of the keyboard/mouse at the time of the last input event. See
  // description of SetEventFlags().
  uint32 event_flags_;

  // Current size of this root window.
  gfx::Size window_size_;

  DISALLOW_COPY_AND_ASSIGN(RemoteWindowTreeHostWin);
};

}  // namespace aura

#endif  // UI_AURA_REMOTE_WINDOW_TREE_HOST_WIN_H_
