// 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.

#include "content/browser/browser_plugin/browser_plugin_embedder.h"

#include "base/values.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/browser_plugin/browser_plugin_guest_manager.h"
#include "content/browser/browser_plugin/browser_plugin_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/browser_plugin/browser_plugin_constants.h"
#include "content/common/browser_plugin/browser_plugin_messages.h"
#include "content/common/drag_messages.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/url_constants.h"
#include "net/base/escape.h"
#include "ui/events/keycodes/keyboard_codes.h"

namespace content {

// static
BrowserPluginHostFactory* BrowserPluginEmbedder::factory_ = NULL;

BrowserPluginEmbedder::BrowserPluginEmbedder(WebContentsImpl* web_contents)
    : WebContentsObserver(web_contents),
      next_get_render_view_request_id_(0) {
}

BrowserPluginEmbedder::~BrowserPluginEmbedder() {
  CleanUp();
}

// static
BrowserPluginEmbedder* BrowserPluginEmbedder::Create(
    WebContentsImpl* web_contents) {
  if (factory_)
    return factory_->CreateBrowserPluginEmbedder(web_contents);
  return new BrowserPluginEmbedder(web_contents);
}

void BrowserPluginEmbedder::DragEnteredGuest(BrowserPluginGuest* guest) {
  guest_dragging_over_ = guest->AsWeakPtr();
}

void BrowserPluginEmbedder::DragLeftGuest(BrowserPluginGuest* guest) {
  // Avoid race conditions in switching between guests being hovered over by
  // only un-setting if the caller is marked as the guest being dragged over.
  if (guest_dragging_over_.get() == guest) {
    guest_dragging_over_.reset();
  }
}

void BrowserPluginEmbedder::StartDrag(BrowserPluginGuest* guest) {
  guest_started_drag_ = guest->AsWeakPtr();
}

void BrowserPluginEmbedder::StopDrag(BrowserPluginGuest* guest) {
  if (guest_started_drag_.get() == guest) {
    guest_started_drag_.reset();
  }
}

void BrowserPluginEmbedder::GetRenderViewHostAtPosition(
    int x, int y, const WebContents::GetRenderViewHostCallback& callback) {
  // Store the callback so we can call it later when we have the response.
  pending_get_render_view_callbacks_.insert(
      std::make_pair(next_get_render_view_request_id_, callback));
  Send(new BrowserPluginMsg_PluginAtPositionRequest(
      routing_id(),
      next_get_render_view_request_id_,
      gfx::Point(x, y)));
  ++next_get_render_view_request_id_;
}

bool BrowserPluginEmbedder::DidSendScreenRectsCallback(
   BrowserPluginGuest* guest) {
  static_cast<RenderViewHostImpl*>(
      guest->GetWebContents()->GetRenderViewHost())->SendScreenRects();
  // Not handled => Iterate over all guests.
  return false;
}

void BrowserPluginEmbedder::DidSendScreenRects() {
  WebContentsImpl* embedder =
      static_cast<WebContentsImpl*>(web_contents());
  GetBrowserPluginGuestManager()->ForEachGuest(embedder, base::Bind(
      &BrowserPluginEmbedder::DidSendScreenRectsCallback,
      base::Unretained(this)));
}

bool BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback(
    const NativeWebKeyboardEvent& event,
    BrowserPluginGuest* guest) {
  return guest->UnlockMouseIfNecessary(event);
}

bool BrowserPluginEmbedder::HandleKeyboardEvent(
    const NativeWebKeyboardEvent& event) {
  if ((event.type != blink::WebInputEvent::RawKeyDown) ||
      (event.windowsKeyCode != ui::VKEY_ESCAPE) ||
      (event.modifiers & blink::WebInputEvent::InputModifiers)) {
    return false;
  }

  WebContentsImpl* embedder =
      static_cast<WebContentsImpl*>(web_contents());
  return GetBrowserPluginGuestManager()->ForEachGuest(embedder, base::Bind(
      &BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback,
      base::Unretained(this),
      event));
}

bool BrowserPluginEmbedder::SetZoomLevelCallback(
    double level, BrowserPluginGuest* guest) {
  guest->GetWebContents()->SetZoomLevel(level);
  // Not handled => Iterate over all guests.
  return false;
}

void BrowserPluginEmbedder::SetZoomLevel(double level) {
  WebContentsImpl* embedder =
      static_cast<WebContentsImpl*>(web_contents());
  GetBrowserPluginGuestManager()->ForEachGuest(embedder, base::Bind(
      &BrowserPluginEmbedder::SetZoomLevelCallback,
      base::Unretained(this),
      level));
}

void BrowserPluginEmbedder::RenderProcessGone(base::TerminationStatus status) {
  CleanUp();
}

bool BrowserPluginEmbedder::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(BrowserPluginEmbedder, message)
    IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_AllocateInstanceID,
                        OnAllocateInstanceID)
    IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_Attach, OnAttach)
    IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_PluginAtPositionResponse,
                        OnPluginAtPositionResponse)
    IPC_MESSAGE_HANDLER_GENERIC(DragHostMsg_UpdateDragCursor,
                                OnUpdateDragCursor(&handled));
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void BrowserPluginEmbedder::DragSourceEndedAt(int client_x, int client_y,
    int screen_x, int screen_y, blink::WebDragOperation operation) {
  if (guest_started_drag_.get()) {
    gfx::Point guest_offset =
        guest_started_drag_->GetScreenCoordinates(gfx::Point());
    guest_started_drag_->DragSourceEndedAt(client_x - guest_offset.x(),
        client_y - guest_offset.y(), screen_x, screen_y, operation);
  }
}

void BrowserPluginEmbedder::DragSourceMovedTo(int client_x, int client_y,
                                              int screen_x, int screen_y) {
  if (guest_started_drag_.get()) {
    gfx::Point guest_offset =
        guest_started_drag_->GetScreenCoordinates(gfx::Point());
    guest_started_drag_->DragSourceMovedTo(client_x - guest_offset.x(),
        client_y - guest_offset.y(), screen_x, screen_y);
  }
}

void BrowserPluginEmbedder::SystemDragEnded() {
  if (guest_started_drag_.get() &&
      (guest_started_drag_.get() != guest_dragging_over_.get()))
    guest_started_drag_->EndSystemDrag();
  guest_started_drag_.reset();
  guest_dragging_over_.reset();
}

void BrowserPluginEmbedder::OnUpdateDragCursor(bool* handled) {
  *handled = (guest_dragging_over_.get() != NULL);
}

void BrowserPluginEmbedder::CleanUp() {
  // CleanUp gets called when BrowserPluginEmbedder's WebContents goes away
  // or the associated RenderViewHost is destroyed or swapped out. Therefore we
  // don't need to care about the pending callbacks anymore.
  pending_get_render_view_callbacks_.clear();
}

BrowserPluginGuestManager*
    BrowserPluginEmbedder::GetBrowserPluginGuestManager() {
  BrowserPluginGuestManager* guest_manager = static_cast<WebContentsImpl*>(
      web_contents())->GetBrowserPluginGuestManager();
  if (!guest_manager) {
    guest_manager = BrowserPluginGuestManager::Create();
    web_contents()->GetBrowserContext()->SetUserData(
        browser_plugin::kBrowserPluginGuestManagerKeyName, guest_manager);
  }
  return guest_manager;
}

void BrowserPluginEmbedder::OnAllocateInstanceID(int request_id) {
  int instance_id = GetBrowserPluginGuestManager()->get_next_instance_id();
  Send(new BrowserPluginMsg_AllocateInstanceID_ACK(
      routing_id(), request_id, instance_id));
}

void BrowserPluginEmbedder::OnAttach(
    int instance_id,
    const BrowserPluginHostMsg_Attach_Params& params,
    const base::DictionaryValue& extra_params) {
  if (!GetBrowserPluginGuestManager()->CanEmbedderAccessInstanceIDMaybeKill(
          web_contents()->GetRenderProcessHost()->GetID(), instance_id))
    return;

  BrowserPluginGuest* guest =
      GetBrowserPluginGuestManager()->GetGuestByInstanceID(
          instance_id, web_contents()->GetRenderProcessHost()->GetID());

  if (guest) {
    // There is an implicit order expectation here:
    // 1. The content embedder is made aware of the attachment.
    // 2. BrowserPluginGuest::Attach is called.
    // 3. The content embedder issues queued events if any that happened
    //    prior to attachment.
    GetContentClient()->browser()->GuestWebContentsAttached(
        guest->GetWebContents(),
        web_contents(),
        extra_params);
    guest->Attach(
        static_cast<WebContentsImpl*>(web_contents()), params, extra_params);
    return;
  }

  scoped_ptr<base::DictionaryValue> copy_extra_params(extra_params.DeepCopy());
  guest = GetBrowserPluginGuestManager()->CreateGuest(
      web_contents()->GetSiteInstance(),
      instance_id, params,
      copy_extra_params.Pass());
  if (guest) {
    GetContentClient()->browser()->GuestWebContentsAttached(
        guest->GetWebContents(),
        web_contents(),
        extra_params);
    guest->Initialize(params, static_cast<WebContentsImpl*>(web_contents()));
  }
}

void BrowserPluginEmbedder::OnPluginAtPositionResponse(
    int instance_id, int request_id, const gfx::Point& position) {
  const std::map<int, WebContents::GetRenderViewHostCallback>::iterator
      callback_iter = pending_get_render_view_callbacks_.find(request_id);
  if (callback_iter == pending_get_render_view_callbacks_.end())
    return;

  RenderViewHost* render_view_host;
  BrowserPluginGuest* guest = NULL;
  if (instance_id != browser_plugin::kInstanceIDNone) {
    guest = GetBrowserPluginGuestManager()->GetGuestByInstanceID(
                instance_id, web_contents()->GetRenderProcessHost()->GetID());
  }

  if (guest)
    render_view_host = guest->GetWebContents()->GetRenderViewHost();
  else  // No plugin, use embedder's RenderViewHost.
    render_view_host = web_contents()->GetRenderViewHost();

  callback_iter->second.Run(render_view_host, position.x(), position.y());
  pending_get_render_view_callbacks_.erase(callback_iter);
}

}  // namespace content
