#ifndef CHROME_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_H_
#define CHROME_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "chrome/browser/devtools/devtools_contents_resizing_strategy.h"
#include "chrome/browser/devtools/devtools_embedder_message_dispatcher.h"
#include "chrome/browser/devtools/devtools_file_helper.h"
#include "chrome/browser/devtools/devtools_file_system_indexer.h"
#include "chrome/browser/devtools/devtools_toggle_action.h"
#include "content/public/browser/devtools_client_host.h"
#include "content/public/browser/devtools_frontend_host_delegate.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_delegate.h"
#include "ui/gfx/size.h"
class Browser;
class BrowserWindow;
class DevToolsControllerTest;
class Profile;
namespace base {
class Value;
}
namespace content {
class DevToolsAgentHost;
class DevToolsClientHost;
struct FileChooserParams;
class RenderViewHost;
class WebContents;
}
namespace IPC {
class Message;
}
namespace user_prefs {
class PrefRegistrySyncable;
}
class DevToolsWindow : private content::NotificationObserver,
                       private content::WebContentsDelegate,
                       private content::DevToolsFrontendHostDelegate,
                       private DevToolsEmbedderMessageDispatcher::Delegate {
 public:
  typedef base::Callback<void(bool)> InfoBarCallback;
  static const char kDevToolsApp[];
  virtual ~DevToolsWindow();
  static std::string GetDevToolsWindowPlacementPrefKey();
  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
  
  
  static DevToolsWindow* GetInstanceForInspectedRenderViewHost(
      content::RenderViewHost* inspected_rvh);
  
  
  
  
  
  static DevToolsWindow* GetDockedInstanceForInspectedTab(
      content::WebContents* inspected_tab);
  static bool IsDevToolsWindow(content::RenderViewHost* window_rvh);
  
  static DevToolsWindow* OpenDevToolsWindow(
      content::RenderViewHost* inspected_rvh,
      const DevToolsToggleAction& action);
  
  static DevToolsWindow* OpenDevToolsWindow(
      content::RenderViewHost* inspected_rvh);
  static DevToolsWindow* OpenDevToolsWindowForTest(
      content::RenderViewHost* inspected_rvh, bool is_docked);
  static DevToolsWindow* OpenDevToolsWindowForTest(
      Browser* browser, bool is_docked);
  
  
  static DevToolsWindow* ToggleDevToolsWindow(
      Browser* browser,
      const DevToolsToggleAction& action);
  
  static void OpenExternalFrontend(
      Profile* profile,
      const std::string& frontend_uri,
      content::DevToolsAgentHost* agent_host);
  
  static DevToolsWindow* OpenDevToolsWindowForWorker(
      Profile* profile,
      content::DevToolsAgentHost* worker_agent);
  static void InspectElement(
      content::RenderViewHost* inspected_rvh, int x, int y);
  
  virtual void InspectedContentsClosing() OVERRIDE;
  content::WebContents* web_contents() { return web_contents_; }
  Browser* browser() { return browser_; }  
  content::RenderViewHost* GetRenderViewHost();
  
  
  
  const DevToolsContentsResizingStrategy& GetContentsResizingStrategy() const;
  
  
  gfx::Size GetMinimumSize() const;
  
  
  void SetLoadCompletedCallback(const base::Closure& closure);
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  static bool HandleBeforeUnload(content::WebContents* contents,
                                 bool proceed,
                                 bool* proceed_to_fire_unload);
  
  
  
  
  
  static bool InterceptPageBeforeUnload(content::WebContents* contents);
  
  
  static bool HasFiredBeforeUnloadEventForDevToolsBrowser(Browser* browser);
  
  
  static bool NeedsToInterceptBeforeUnload(content::WebContents* contents);
  
  
  static void OnPageCloseCanceled(content::WebContents* contents);
 private:
  friend class DevToolsControllerTest;
  friend class DevToolsSanityTest;
  friend class BrowserWindowControllerTest;
  
  
  
  
  
  
  
  
  
  enum LoadState {
    kNotLoaded,
    kOnLoadFired, 
    kIsDockedSet, 
    kLoadCompleted
  };
  DevToolsWindow(Profile* profile,
                 const GURL& frontend_url,
                 content::RenderViewHost* inspected_rvh,
                 bool can_dock);
  static DevToolsWindow* Create(Profile* profile,
                                const GURL& frontend_url,
                                content::RenderViewHost* inspected_rvh,
                                bool shared_worker_frontend,
                                bool external_frontend,
                                bool can_dock);
  static GURL GetDevToolsURL(Profile* profile,
                             const GURL& base_url,
                             bool shared_worker_frontend,
                             bool external_frontend,
                             bool can_dock);
  static DevToolsWindow* FindDevToolsWindow(content::DevToolsAgentHost*);
  static DevToolsWindow* AsDevToolsWindow(content::RenderViewHost*);
  static DevToolsWindow* CreateDevToolsWindowForWorker(Profile* profile);
  static bool FindInspectedBrowserAndTabIndex(
      content::WebContents* inspected_web_contents, Browser**, int* tab);
  static DevToolsWindow* ToggleDevToolsWindow(
      content::RenderViewHost* inspected_rvh,
      bool force_open,
      const DevToolsToggleAction& action);
  
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;
  
  virtual content::WebContents* OpenURLFromTab(
      content::WebContents* source,
      const content::OpenURLParams& params) 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 ContentsZoomChange(bool zoom_in) OVERRIDE;
  virtual void BeforeUnloadFired(content::WebContents* tab,
                                 bool proceed,
                                 bool* proceed_to_fire_unload) 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 content::JavaScriptDialogManager*
      GetJavaScriptDialogManager() OVERRIDE;
  virtual content::ColorChooser* OpenColorChooser(
      content::WebContents* web_contents,
      SkColor color,
      const std::vector<content::ColorSuggestion>& suggestions) OVERRIDE;
  virtual void RunFileChooser(
      content::WebContents* web_contents,
      const content::FileChooserParams& params) OVERRIDE;
  virtual void WebContentsFocused(content::WebContents* contents) OVERRIDE;
  virtual bool PreHandleGestureEvent(
      content::WebContents* source,
      const blink::WebGestureEvent& event) OVERRIDE;
  
  virtual void DispatchOnEmbedder(const std::string& message) OVERRIDE;
  
  virtual void ActivateWindow() OVERRIDE;
  virtual void ActivateContents(content::WebContents* contents) OVERRIDE;
  virtual void CloseWindow() OVERRIDE;
  virtual void SetContentsInsets(
      int left, int top, int right, int bottom) OVERRIDE;
  virtual void SetContentsResizingStrategy(
      const gfx::Insets& insets, const gfx::Size& min_size) OVERRIDE;
  virtual void InspectElementCompleted() OVERRIDE;
  virtual void MoveWindow(int x, int y) OVERRIDE;
  virtual void SetIsDocked(bool is_docked) OVERRIDE;
  virtual void OpenInNewTab(const std::string& url) OVERRIDE;
  virtual void SaveToFile(const std::string& url,
                          const std::string& content,
                          bool save_as) OVERRIDE;
  virtual void AppendToFile(const std::string& url,
                            const std::string& content) OVERRIDE;
  virtual void RequestFileSystems() OVERRIDE;
  virtual void AddFileSystem() OVERRIDE;
  virtual void RemoveFileSystem(const std::string& file_system_path) OVERRIDE;
  virtual void UpgradeDraggedFileSystemPermissions(
      const std::string& file_system_url) OVERRIDE;
  virtual void IndexPath(int request_id,
                         const std::string& file_system_path) OVERRIDE;
  virtual void StopIndexing(int request_id) OVERRIDE;
  virtual void SearchInPath(int request_id,
                            const std::string& file_system_path,
                            const std::string& query) OVERRIDE;
  virtual void ZoomIn() OVERRIDE;
  virtual void ZoomOut() OVERRIDE;
  virtual void ResetZoom() OVERRIDE;
  
  void FileSavedAs(const std::string& url);
  void CanceledFileSaveAs(const std::string& url);
  void AppendedTo(const std::string& url);
  void FileSystemsLoaded(
      const std::vector<DevToolsFileHelper::FileSystem>& file_systems);
  void FileSystemAdded(const DevToolsFileHelper::FileSystem& file_system);
  void IndexingTotalWorkCalculated(int request_id,
                                   const std::string& file_system_path,
                                   int total_work);
  void IndexingWorked(int request_id,
                      const std::string& file_system_path,
                      int worked);
  void IndexingDone(int request_id, const std::string& file_system_path);
  void SearchCompleted(int request_id,
                       const std::string& file_system_path,
                       const std::vector<std::string>& file_paths);
  void ShowDevToolsConfirmInfoBar(const base::string16& message,
                                  const InfoBarCallback& callback);
  void CreateDevToolsBrowser();
  BrowserWindow* GetInspectedBrowserWindow();
  void ScheduleShow(const DevToolsToggleAction& action);
  void Show(const DevToolsToggleAction& action);
  void DoAction(const DevToolsToggleAction& action);
  void LoadCompleted();
  void SetIsDockedAndShowImmediatelyForTest(bool is_docked);
  void UpdateTheme();
  void AddDevToolsExtensionsToClient();
  void CallClientFunction(const std::string& function_name,
                          const base::Value* arg1,
                          const base::Value* arg2,
                          const base::Value* arg3);
  void UpdateBrowserToolbar();
  content::WebContents* GetInspectedWebContents();
  void DocumentOnLoadCompletedInMainFrame();
  class InspectedWebContentsObserver;
  scoped_ptr<InspectedWebContentsObserver> inspected_contents_observer_;
  class FrontendWebContentsObserver;
  friend class FrontendWebContentsObserver;
  scoped_ptr<FrontendWebContentsObserver> frontend_contents_observer_;
  Profile* profile_;
  content::WebContents* web_contents_;
  Browser* browser_;
  bool is_docked_;
  bool can_dock_;
  LoadState load_state_;
  DevToolsToggleAction action_on_load_;
  bool ignore_set_is_docked_;
  content::NotificationRegistrar registrar_;
  scoped_ptr<content::DevToolsClientHost> frontend_host_;
  scoped_ptr<DevToolsFileHelper> file_helper_;
  scoped_refptr<DevToolsFileSystemIndexer> file_system_indexer_;
  typedef std::map<
      int,
      scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob> >
      IndexingJobsMap;
  IndexingJobsMap indexing_jobs_;
  DevToolsContentsResizingStrategy contents_resizing_strategy_;
  
  
  bool intercepted_page_beforeunload_;
  base::Closure load_completed_callback_;
  scoped_ptr<DevToolsEmbedderMessageDispatcher> embedder_message_dispatcher_;
  base::WeakPtrFactory<DevToolsWindow> weak_factory_;
  base::TimeTicks inspect_element_start_time_;
  DISALLOW_COPY_AND_ASSIGN(DevToolsWindow);
};
#endif