// 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 CHROME_BROWSER_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_
#define CHROME_BROWSER_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_

#include <map>
#include <string>
#include <vector>

#include "base/compiler_specific.h"
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/automation/automation_resource_message_filter.h"
#include "chrome/browser/external_tab/external_tab_container.h"
#include "chrome/browser/infobars/infobar_container.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "content/public/browser/navigation_type.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
#include "ui/views/widget/widget_observer.h"

class AutomationProvider;
class Browser;
class Profile;
class TabContentsContainer;
class RenderViewContextMenuViews;
struct NavigationInfo;

namespace ui {
class ViewProp;
}

namespace views {
class View;
class WebView;
class Widget;
}

#if defined(USE_AURA)
class ContainerWindow;
#endif

// This class serves as the container window for an external tab.
// An external tab is a Chrome tab that is meant to displayed in an
// external process. This class provides the FocusManger needed by the
// WebContents as well as an implementation of content::WebContentsDelegate.
class ExternalTabContainerWin : public ExternalTabContainer,
                                public content::WebContentsDelegate,
                                public content::WebContentsObserver,
                                public content::NotificationObserver,
                                public views::WidgetObserver,
                                public ui::AcceleratorTarget,
                                public InfoBarContainer::Delegate {
 public:
  typedef std::map<uintptr_t,
                   scoped_refptr<ExternalTabContainerWin> > PendingTabs;

  ExternalTabContainerWin(AutomationProvider* automation,
                          AutomationResourceMessageFilter* filter);

  static scoped_refptr<ExternalTabContainer> RemovePendingExternalTab(
      uintptr_t cookie);

  // Overridden from ExternalTabContainer:
  virtual bool Init(Profile* profile,
                    HWND parent,
                    const gfx::Rect& bounds,
                    DWORD style,
                    bool load_requests_via_automation,
                    bool handle_top_level_requests,
                    content::WebContents* existing_contents,
                    const GURL& initial_url,
                    const GURL& referrer,
                    bool infobars_enabled,
                    bool supports_full_tab_mode) OVERRIDE;
  virtual void Uninitialize() OVERRIDE;
  virtual bool Reinitialize(AutomationProvider* automation_provider,
                            AutomationResourceMessageFilter* filter,
                            HWND parent_window) OVERRIDE;
  virtual content::WebContents* GetWebContents() const OVERRIDE;
  virtual HWND GetExternalTabHWND() const OVERRIDE;
  virtual HWND GetContentHWND() const OVERRIDE;
  virtual void SetTabHandle(int handle) OVERRIDE;
  virtual int GetTabHandle() const OVERRIDE;
  virtual bool ExecuteContextMenuCommand(int command) OVERRIDE;
  virtual void RunUnloadHandlers(IPC::Message* reply_message) OVERRIDE;
  virtual void ProcessUnhandledAccelerator(const MSG& msg) OVERRIDE;
  virtual void FocusThroughTabTraversal(bool reverse,
                                        bool restore_focus_to_view) OVERRIDE;

  // Overridden from content::WebContentsDelegate:
  virtual content::WebContents* OpenURLFromTab(
      content::WebContents* source,
      const content::OpenURLParams& params) OVERRIDE;
  virtual void NavigationStateChanged(const content::WebContents* source,
                                      unsigned changed_flags) OVERRIDE;
  virtual void AddNewContents(content::WebContents* source,
                              content::WebContents* new_contents,
                              WindowOpenDisposition disposition,
                              const gfx::Rect& initial_pos,
                              bool user_gesture,
                              bool* was_blocked) OVERRIDE;
  virtual void CloseContents(content::WebContents* source) OVERRIDE;
  virtual void MoveContents(content::WebContents* source,
                            const gfx::Rect& pos) OVERRIDE;
  virtual bool IsPopupOrPanel(
      const content::WebContents* source) const OVERRIDE;
  virtual void UpdateTargetURL(content::WebContents* source, int32 page_id,
                               const GURL& url) OVERRIDE;
  virtual void ContentsZoomChange(bool zoom_in) OVERRIDE;
  virtual void WebContentsCreated(content::WebContents* source_contents,
                                  int64 source_frame_id,
                                  const string16& frame_name,
                                  const GURL& target_url,
                                  content::WebContents* new_contents) OVERRIDE;
  virtual bool PreHandleKeyboardEvent(
      content::WebContents* source,
      const content::NativeWebKeyboardEvent& event,
      bool* is_keyboard_shortcut) OVERRIDE;
  virtual void HandleKeyboardEvent(
      content::WebContents* source,
      const content::NativeWebKeyboardEvent& event) OVERRIDE;
  virtual bool TakeFocus(content::WebContents* source, bool reverse) OVERRIDE;
  virtual void WebContentsFocused(content::WebContents* contents) OVERRIDE;
  virtual void CanDownload(content::RenderViewHost* render_view_host,
                           int request_id,
                           const std::string& request_method,
                           const base::Callback<void(bool)>& callback) OVERRIDE;
  virtual bool OnGoToEntryOffset(int offset) OVERRIDE;
  virtual bool HandleContextMenu(
      const content::ContextMenuParams& params) OVERRIDE;
  virtual void BeforeUnloadFired(content::WebContents* tab,
                                 bool proceed,
                                 bool* proceed_to_fire_unload) OVERRIDE;
  virtual content::JavaScriptDialogManager*
      GetJavaScriptDialogManager() OVERRIDE;
  virtual void ShowRepostFormWarningDialog(
      content::WebContents* source) OVERRIDE;
  virtual content::ColorChooser* OpenColorChooser(
      content::WebContents* web_contents, SkColor color) OVERRIDE;
  virtual void RunFileChooser(
      content::WebContents* tab,
      const content::FileChooserParams& params) OVERRIDE;
  virtual void EnumerateDirectory(content::WebContents* tab,
                                  int request_id,
                                  const base::FilePath& path) OVERRIDE;
  virtual void JSOutOfMemory(content::WebContents* tab);
  virtual void RegisterProtocolHandler(content::WebContents* tab,
                                       const std::string& protocol,
                                       const GURL& url,
                                       const string16& title,
                                       bool user_gesture) OVERRIDE;
  virtual void FindReply(content::WebContents* tab,
                         int request_id,
                         int number_of_matches,
                         const gfx::Rect& selection_rect,
                         int active_match_ordinal,
                         bool final_update) OVERRIDE;
  virtual void RequestMediaAccessPermission(
      content::WebContents* web_contents,
      const content::MediaStreamRequest& request,
      const content::MediaResponseCallback& callback) OVERRIDE;
  virtual bool RequestPpapiBrokerPermission(
      content::WebContents* web_contents,
      const GURL& url,
      const base::FilePath& plugin_path,
      const base::Callback<void(bool)>& callback) OVERRIDE;

  void RegisterRenderViewHost(content::RenderViewHost* render_view_host);
  void UnregisterRenderViewHost(content::RenderViewHost* render_view_host);

  // Overridden from content::WebContentsObserver:
  virtual void RenderViewDeleted(
      content::RenderViewHost* render_view_host) OVERRIDE;
  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
  virtual void DidFailProvisionalLoad(
      int64 frame_id,
      const string16& frame_unique_name,
      bool is_main_frame,
      const GURL& validated_url,
      int error_code,
      const string16& error_description,
      content::RenderViewHost* render_view_host) OVERRIDE;

  // Message handlers
  void OnForwardMessageToExternalHost(const std::string& message,
                                      const std::string& origin,
                                      const std::string& target);

  // Overridden from content::NotificationObserver:
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details);

  // Overridden from ui::AcceleratorTarget:
  virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
  virtual bool CanHandleAccelerators() const OVERRIDE;

  void set_pending(bool pending) { pending_ = pending; }
  bool pending() const { return pending_; }

  void set_is_popup_window(bool is_popup_window) {
    is_popup_window_ = is_popup_window;
  }

  // Overridden from InfoBarContainer::Delegate:
  virtual SkColor GetInfoBarSeparatorColor() const OVERRIDE;
  virtual void InfoBarContainerStateChanged(bool is_animating) OVERRIDE;
  virtual bool DrawInfoBarArrows(int* x) const OVERRIDE;

 protected:
  virtual ~ExternalTabContainerWin();

  // WidgetObserver overrides.
  virtual void OnWidgetCreated(views::Widget* widget) OVERRIDE;
  virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
  virtual void OnWidgetDestroyed(views::Widget* widget) OVERRIDE;

  bool InitNavigationInfo(NavigationInfo* nav_info,
                          content::NavigationType nav_type,
                          int relative_offset);
  void Navigate(const GURL& url, const GURL& referrer);

  // Helper resource automation registration method, allowing registration of
  // pending RenderViewHosts.
  void RegisterRenderViewHostForAutomation(
      bool pending_view,
      content::RenderViewHost* render_view_host);

  // Helper function for processing keystokes coming back from the renderer
  // process.
  bool ProcessUnhandledKeyStroke(HWND window, UINT message, WPARAM wparam,
                                 LPARAM lparam);

  void LoadAccelerators();

  // Sends over pending Open URL requests to the external host.
  void ServicePendingOpenURLRequests();

  // Scheduled as a task in ExternalTabContainerWin::Reinitialize.
  void OnReinitialize();

  // Creates and initializes the view hierarchy for this
  // ExternalTabContainerWin.
  void SetupExternalTabView();

  views::Widget* widget_;
  scoped_ptr<content::WebContents> web_contents_;
  scoped_refptr<AutomationProvider> automation_;

  content::RenderViewHost::CreatedCallback rvh_callback_;

  content::NotificationRegistrar registrar_;

  // A view to handle focus cycling
  views::WebView* tab_contents_container_;

  int tab_handle_;
  // A failed navigation like a 404 is followed in chrome with a success
  // navigation for the 404 page. We need to ignore the next navigation
  // to avoid confusing the clients of the external tab. This member variable
  // is set when we need to ignore the next load notification.
  bool ignore_next_load_notification_;

  scoped_ptr<RenderViewContextMenuViews> external_context_menu_;

  // A message filter to load resources via automation
  scoped_refptr<AutomationResourceMessageFilter>
      automation_resource_message_filter_;

  // If all the url requests for this tab are to be loaded via automation.
  bool load_requests_via_automation_;

  // whether top level URL requests are to be handled by the automation client.
  bool handle_top_level_requests_;

  // Set to true if the host needs to get notified of all top level navigations
  // in this page. This typically applies to hosts which would render the new
  // page without chrome frame.
  bool route_all_top_level_navigations_;

  // Contains ExternalTabContainers that have not been connected to as yet.
  static base::LazyInstance<PendingTabs> pending_tabs_;

  // Allows us to run tasks on the ExternalTabContainerWin instance which are
  // bound by its lifetime.
  base::WeakPtrFactory<ExternalTabContainerWin> weak_factory_;

  // The URL request context to be used for this tab. Can be NULL.
  scoped_refptr<ChromeURLRequestContextGetter> request_context_;

  views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;

  // A mapping between accelerators and commands.
  std::map<ui::Accelerator, int> accelerator_table_;

  // Top level navigations received for a tab while it is waiting for an ack
  // from the external host go here. Scenario is a window.open executes on a
  // page in ChromeFrame. A new WebContents is created and the current
  // ExternalTabContainerWin is notified via AddNewContents. At this point we
  // send off an attach tab request to the host browser. Before the host
  // browser sends over the ack, we receive a top level URL navigation for the
  // new tab, which needs to be routed over the correct automation channel.
  // We receive the automation channel only when the external host acks the
  // attach tab request.
  // Contains the list of URL requests which are pending waiting for an ack
  // from the external host.
  std::vector<content::OpenURLParams> pending_open_url_requests_;

  // Set to true if the ExternalTabContainerWin instance is waiting for an ack
  // from the host.
  bool pending_;

  views::FocusManager* focus_manager_;

  views::View* external_tab_view_;

  IPC::Message* unload_reply_message_;

  scoped_ptr<ui::ViewProp> prop_;

  // if this tab is a popup
  bool is_popup_window_;

#if defined(USE_AURA)
  base::WeakPtr<ContainerWindow> tab_container_window_;
#endif

  DISALLOW_COPY_AND_ASSIGN(ExternalTabContainerWin);
};

// This class is instantiated for handling requests to open popups for external
// tabs hosted in browsers which need to be notified about all top level
// navigations. An instance of this class is created for handling window.open
// or link navigations with target blank, etc.
class TemporaryPopupExternalTabContainerWin : public ExternalTabContainerWin {
 public:
  TemporaryPopupExternalTabContainerWin(
      AutomationProvider* automation,
      AutomationResourceMessageFilter* filter);
  virtual ~TemporaryPopupExternalTabContainerWin();

  virtual bool OnGoToEntryOffset(int offset) {
    NOTREACHED();
    return false;
  }

  virtual bool ProcessUnhandledKeyStroke(HWND window, UINT message,
                                         WPARAM wparam, LPARAM lparam) {
    NOTREACHED();
    return false;
  }

  virtual void Observe(int type, const content::NotificationSource& source,
                       const content::NotificationDetails& details) {}

  virtual content::WebContents* OpenURLFromTab(
    content::WebContents* source,
    const content::OpenURLParams& params) OVERRIDE;

  virtual void NavigationStateChanged(const content::WebContents* source,
                                      unsigned changed_flags) {
    NOTREACHED();
  }

  virtual void CloseContents(content::WebContents* source) {
    NOTREACHED();
  }

  virtual void UpdateTargetURL(content::WebContents* source, int32 page_id,
                               const GURL& url) {
    NOTREACHED();
  }

  void ForwardMessageToExternalHost(const std::string& message,
                                    const std::string& origin,
                                    const std::string& target) {
    NOTREACHED();
  }

  virtual bool TakeFocus(bool reverse) {
    NOTREACHED();
    return false;
  }

  virtual bool HandleContextMenu(const content::ContextMenuParams& params) {
    NOTREACHED();
    return false;
  }

  virtual void BeforeUnloadFired(content::WebContents* tab, bool proceed,
                                 bool* proceed_to_fire_unload) {
    NOTREACHED();
  }
};

#endif  // CHROME_BROWSER_UI_VIEWS_EXTERNAL_TAB_CONTAINER_WIN_H_
