// 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 "ui/views/controls/webview/webview.h"

#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "ipc/ipc_message.h"
#include "ui/accessibility/ax_enums.h"
#include "ui/accessibility/ax_view_state.h"
#include "ui/base/ui_base_switches_util.h"
#include "ui/events/event.h"
#include "ui/views/accessibility/native_view_accessibility.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/views_delegate.h"

namespace views {

// static
const char WebView::kViewClassName[] = "WebView";

////////////////////////////////////////////////////////////////////////////////
// WebView, public:

WebView::WebView(content::BrowserContext* browser_context)
    : holder_(new NativeViewHost()),
      embed_fullscreen_widget_mode_enabled_(false),
      is_embedding_fullscreen_widget_(false),
      browser_context_(browser_context),
      allow_accelerators_(false) {
  AddChildView(holder_);  // Takes ownership of |holder_|.
  NativeViewAccessibility::RegisterWebView(this);
}

WebView::~WebView() {
  SetWebContents(NULL);  // Make sure all necessary tear-down takes place.
  NativeViewAccessibility::UnregisterWebView(this);
}

content::WebContents* WebView::GetWebContents() {
  if (!web_contents()) {
    wc_owner_.reset(CreateWebContents(browser_context_));
    wc_owner_->SetDelegate(this);
    SetWebContents(wc_owner_.get());
  }
  return web_contents();
}

void WebView::SetWebContents(content::WebContents* replacement) {
  if (replacement == web_contents())
    return;
  DetachWebContents();
  WebContentsObserver::Observe(replacement);
  // web_contents() now returns |replacement| from here onwards.
  SetFocusable(!!web_contents());
  if (wc_owner_ != replacement)
    wc_owner_.reset();
  if (embed_fullscreen_widget_mode_enabled_) {
    is_embedding_fullscreen_widget_ =
        web_contents() && web_contents()->GetFullscreenRenderWidgetHostView();
  } else {
    DCHECK(!is_embedding_fullscreen_widget_);
  }
  AttachWebContents();
  NotifyMaybeTextInputClientChanged();
}

void WebView::SetEmbedFullscreenWidgetMode(bool enable) {
  DCHECK(!web_contents())
      << "Cannot change mode while a WebContents is attached.";
  embed_fullscreen_widget_mode_enabled_ = enable;
}

void WebView::LoadInitialURL(const GURL& url) {
  GetWebContents()->GetController().LoadURL(
      url, content::Referrer(), ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
      std::string());
}

void WebView::SetFastResize(bool fast_resize) {
  holder_->set_fast_resize(fast_resize);
}

void WebView::OnWebContentsFocused(content::WebContents* web_contents) {
  FocusManager* focus_manager = GetFocusManager();
  if (focus_manager)
    focus_manager->SetFocusedView(this);
}

void WebView::SetPreferredSize(const gfx::Size& preferred_size) {
  preferred_size_ = preferred_size;
  PreferredSizeChanged();
}

////////////////////////////////////////////////////////////////////////////////
// WebView, View overrides:

const char* WebView::GetClassName() const {
  return kViewClassName;
}

ui::TextInputClient* WebView::GetTextInputClient() {
  // This function delegates the text input handling to the underlying
  // content::RenderWidgetHostView.  So when the underlying RWHV is destroyed or
  // replaced with another one, we have to notify the FocusManager through
  // FocusManager::OnTextInputClientChanged() that the focused TextInputClient
  // needs to be updated.
  if (switches::IsTextInputFocusManagerEnabled() &&
      web_contents() && !web_contents()->IsBeingDestroyed()) {
    content::RenderWidgetHostView* host_view =
        is_embedding_fullscreen_widget_ ?
        web_contents()->GetFullscreenRenderWidgetHostView() :
        web_contents()->GetRenderWidgetHostView();
    if (host_view)
      return host_view->GetTextInputClient();
  }
  return NULL;
}

scoped_ptr<content::WebContents> WebView::SwapWebContents(
    scoped_ptr<content::WebContents> new_web_contents) {
  if (wc_owner_)
    wc_owner_->SetDelegate(NULL);
  scoped_ptr<content::WebContents> old_web_contents(wc_owner_.Pass());
  wc_owner_ = new_web_contents.Pass();
  if (wc_owner_)
    wc_owner_->SetDelegate(this);
  SetWebContents(wc_owner_.get());
  return old_web_contents.Pass();
}

void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
  // In most cases, the holder is simply sized to fill this WebView's bounds.
  // Only WebContentses that are in fullscreen mode and being screen-captured
  // will engage the special layout/sizing behavior.
  gfx::Rect holder_bounds(bounds().size());
  if (!embed_fullscreen_widget_mode_enabled_ ||
      !web_contents() ||
      web_contents()->GetCapturerCount() == 0 ||
      web_contents()->GetPreferredSize().IsEmpty() ||
      !(is_embedding_fullscreen_widget_ ||
        (web_contents()->GetDelegate() &&
         web_contents()->GetDelegate()->
             IsFullscreenForTabOrPending(web_contents())))) {
    holder_->SetBoundsRect(holder_bounds);
    return;
  }

  // Size the holder to the capture video resolution and center it.  If this
  // WebView is not large enough to contain the holder at the preferred size,
  // scale down to fit (preserving aspect ratio).
  const gfx::Size capture_size = web_contents()->GetPreferredSize();
  if (capture_size.width() <= holder_bounds.width() &&
      capture_size.height() <= holder_bounds.height()) {
    // No scaling, just centering.
    holder_bounds.ClampToCenteredSize(capture_size);
  } else {
    // Scale down, preserving aspect ratio, and center.
    // TODO(miu): This is basically media::ComputeLetterboxRegion(), and it
    // looks like others have written this code elsewhere.  Let's considate
    // into a shared function ui/gfx/geometry or around there.
    const int64 x = static_cast<int64>(capture_size.width()) *
        holder_bounds.height();
    const int64 y = static_cast<int64>(capture_size.height()) *
        holder_bounds.width();
    if (y < x) {
      holder_bounds.ClampToCenteredSize(gfx::Size(
          holder_bounds.width(), static_cast<int>(y / capture_size.width())));
    } else {
      holder_bounds.ClampToCenteredSize(gfx::Size(
          static_cast<int>(x / capture_size.height()), holder_bounds.height()));
    }
  }

  holder_->SetBoundsRect(holder_bounds);
}

void WebView::ViewHierarchyChanged(
    const ViewHierarchyChangedDetails& details) {
  if (details.is_add)
    AttachWebContents();
}

bool WebView::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) {
  if (allow_accelerators_)
    return FocusManager::IsTabTraversalKeyEvent(event);

  // Don't look-up accelerators or tab-traversal if we are showing a non-crashed
  // TabContents.
  // We'll first give the page a chance to process the key events.  If it does
  // not process them, they'll be returned to us and we'll treat them as
  // accelerators then.
  return web_contents() && !web_contents()->IsCrashed();
}

void WebView::OnFocus() {
  if (web_contents())
    web_contents()->Focus();
}

void WebView::AboutToRequestFocusFromTabTraversal(bool reverse) {
  if (web_contents())
    web_contents()->FocusThroughTabTraversal(reverse);
}

void WebView::GetAccessibleState(ui::AXViewState* state) {
  state->role = ui::AX_ROLE_GROUP;
}

gfx::NativeViewAccessible WebView::GetNativeViewAccessible() {
  if (web_contents()) {
    content::RenderWidgetHostView* host_view =
        web_contents()->GetRenderWidgetHostView();
    if (host_view)
      return host_view->GetNativeViewAccessible();
  }
  return View::GetNativeViewAccessible();
}

gfx::Size WebView::GetPreferredSize() const {
  if (preferred_size_ == gfx::Size())
    return View::GetPreferredSize();
  else
    return preferred_size_;
}

////////////////////////////////////////////////////////////////////////////////
// WebView, content::WebContentsDelegate implementation:

void WebView::WebContentsFocused(content::WebContents* web_contents) {
  DCHECK(wc_owner_.get());
  // The WebView is only the delegate of WebContentses it creates itself.
  OnWebContentsFocused(wc_owner_.get());
}

bool WebView::EmbedsFullscreenWidget() const {
  DCHECK(wc_owner_.get());
  return embed_fullscreen_widget_mode_enabled_;
}

////////////////////////////////////////////////////////////////////////////////
// WebView, content::WebContentsObserver implementation:

void WebView::RenderViewDeleted(content::RenderViewHost* render_view_host) {
  NotifyMaybeTextInputClientChanged();
}

void WebView::RenderProcessGone(base::TerminationStatus status) {
  NotifyMaybeTextInputClientChanged();
}

void WebView::RenderViewHostChanged(content::RenderViewHost* old_host,
                                    content::RenderViewHost* new_host) {
  FocusManager* const focus_manager = GetFocusManager();
  if (focus_manager && focus_manager->GetFocusedView() == this)
    OnFocus();
  NotifyMaybeTextInputClientChanged();
}

void WebView::DidShowFullscreenWidget(int routing_id) {
  if (embed_fullscreen_widget_mode_enabled_)
    ReattachForFullscreenChange(true);
}

void WebView::DidDestroyFullscreenWidget(int routing_id) {
  if (embed_fullscreen_widget_mode_enabled_)
    ReattachForFullscreenChange(false);
}

void WebView::DidToggleFullscreenModeForTab(bool entered_fullscreen) {
  if (embed_fullscreen_widget_mode_enabled_)
    ReattachForFullscreenChange(entered_fullscreen);
}

void WebView::DidAttachInterstitialPage() {
  NotifyMaybeTextInputClientChanged();
}

void WebView::DidDetachInterstitialPage() {
  NotifyMaybeTextInputClientChanged();
}

////////////////////////////////////////////////////////////////////////////////
// WebView, private:

void WebView::AttachWebContents() {
  // Prevents attachment if the WebView isn't already in a Widget, or it's
  // already attached.
  if (!GetWidget() || !web_contents())
    return;

  const gfx::NativeView view_to_attach = is_embedding_fullscreen_widget_ ?
      web_contents()->GetFullscreenRenderWidgetHostView()->GetNativeView() :
      web_contents()->GetNativeView();
  OnBoundsChanged(bounds());
  if (holder_->native_view() == view_to_attach)
    return;

  holder_->Attach(view_to_attach);

  // The view will not be focused automatically when it is attached, so we need
  // to pass on focus to it if the FocusManager thinks the view is focused. Note
  // that not every Widget has a focus manager.
  FocusManager* const focus_manager = GetFocusManager();
  if (focus_manager && focus_manager->GetFocusedView() == this)
    OnFocus();

#if defined(OS_WIN)
  if (!is_embedding_fullscreen_widget_) {
    web_contents()->SetParentNativeViewAccessible(
        parent()->GetNativeViewAccessible());
  }
#endif
}

void WebView::DetachWebContents() {
  if (web_contents()) {
    holder_->Detach();
#if defined(OS_WIN)
    if (!is_embedding_fullscreen_widget_)
      web_contents()->SetParentNativeViewAccessible(NULL);
#endif
  }
}

void WebView::ReattachForFullscreenChange(bool enter_fullscreen) {
  DCHECK(embed_fullscreen_widget_mode_enabled_);
  const bool web_contents_has_separate_fs_widget =
      web_contents() && web_contents()->GetFullscreenRenderWidgetHostView();
  if (is_embedding_fullscreen_widget_ || web_contents_has_separate_fs_widget) {
    // Shutting down or starting up the embedding of the separate fullscreen
    // widget.  Need to detach and re-attach to a different native view.
    DetachWebContents();
    is_embedding_fullscreen_widget_ =
        enter_fullscreen && web_contents_has_separate_fs_widget;
    AttachWebContents();
  } else {
    // Entering or exiting "non-Flash" fullscreen mode, where the native view is
    // the same.  So, do not change attachment.
    OnBoundsChanged(bounds());
  }
  NotifyMaybeTextInputClientChanged();
}

void WebView::NotifyMaybeTextInputClientChanged() {
  // Update the TextInputClient as needed; see GetTextInputClient().
  FocusManager* const focus_manager = GetFocusManager();
  if (focus_manager)
    focus_manager->OnTextInputClientChanged(this);
}

content::WebContents* WebView::CreateWebContents(
      content::BrowserContext* browser_context) {
  content::WebContents* contents = NULL;
  if (ViewsDelegate::views_delegate) {
    contents = ViewsDelegate::views_delegate->CreateWebContents(
        browser_context, NULL);
  }

  if (!contents) {
    content::WebContents::CreateParams create_params(
        browser_context, NULL);
    return content::WebContents::Create(create_params);
  }

  return contents;
}

}  // namespace views
