// 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_PANELS_PANEL_H_
#define CHROME_BROWSER_UI_PANELS_PANEL_H_

#include <string>

#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "chrome/browser/command_updater.h"
#include "chrome/browser/command_updater_delegate.h"
#include "chrome/browser/sessions/session_id.h"
#include "chrome/browser/ui/panels/panel_constants.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "ui/base/base_window.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/rect.h"

class GURL;
class NativePanel;
class PanelCollection;
class PanelHost;
class PanelManager;
class Profile;
class StackedPanelCollection;

namespace content {
class WebContents;
struct NativeWebKeyboardEvent;
}

namespace extensions {
class Extension;
class WindowController;
}

// A platform independent implementation of ui::BaseWindow for Panels.
// This class gets the first crack at all the ui::BaseWindow calls for Panels
// and does one or more of the following:
// - Do nothing.  The function is not relevant to Panels.
// - Do Panel specific platform independent processing and then invoke the
//   function on the platform specific member. For example, restrict panel
//   size to certain limits.
// - Invoke an appropriate PanelManager function to do stuff that might affect
//   other Panels. For example deleting a panel would rearrange other panels.
class Panel : public ui::BaseWindow,
              public CommandUpdaterDelegate,
              public content::NotificationObserver {
 public:
  enum ExpansionState {
    // The panel is fully expanded with both title-bar and the client-area.
    EXPANDED,
    // The panel is shown with the title-bar only.
    TITLE_ONLY,
    // The panel is shown with 3-pixel line.
    MINIMIZED
  };

  // Controls how the attention should be drawn.
  enum AttentionMode {
    // Uses the panel attention. The panel's titlebar would be painted
    // differently to attract the user's attention. This is the default mode.
    USE_PANEL_ATTENTION = 0x01,
    // Uses the system attention. On Windows or Linux (depending on Window
    // Manager), the app icon on taskbar will be flashed. On MacOS, the dock
    // icon will jump once.
    USE_SYSTEM_ATTENTION = 0x02
  };

  virtual ~Panel();

  // Returns the PanelManager associated with this panel.
  PanelManager* manager() const;

  const std::string& app_name() const { return app_name_; }
  const gfx::Image& app_icon() const { return app_icon_; }
  const SessionID& session_id() const { return session_id_; }
  extensions::WindowController* extension_window_controller() const {
    return extension_window_controller_.get();
  }
  const std::string extension_id() const;

  CommandUpdater* command_updater();
  Profile* profile() const;

  const extensions::Extension* GetExtension() const;

  // Returns web contents of the panel, if any. There may be none if web
  // contents have not been added to the panel yet.
  content::WebContents* GetWebContents() const;

  void SetExpansionState(ExpansionState new_expansion_state);

  bool IsDrawingAttention() const;

  // This function will only get called by PanelManager when full screen mode
  // changes i.e it gets called when an app goes into full screen mode or when
  // an app exits full screen mode. Panel should respond by making sure
  // a) it does not go on top when some app enters full screen mode.
  // b) it remains on top when an app exits full screen mode.
  void FullScreenModeChanged(bool is_full_screen);

  int TitleOnlyHeight() const;

  // Returns true if the panel can show minimize or restore button in its
  // titlebar, depending on its state.
  bool CanShowMinimizeButton() const;
  bool CanShowRestoreButton() const;

  // ui::BaseWindow overrides.
  virtual bool IsActive() const OVERRIDE;
  virtual bool IsMaximized() const OVERRIDE;
  virtual bool IsMinimized() const OVERRIDE;
  virtual bool IsFullscreen() const OVERRIDE;
  virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
  virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
  virtual ui::WindowShowState GetRestoredState() const OVERRIDE;
  virtual gfx::Rect GetBounds() const OVERRIDE;
  virtual void Show() OVERRIDE;
  virtual void Hide() OVERRIDE;
  virtual void ShowInactive() OVERRIDE;
  virtual void Close() OVERRIDE;
  virtual void Activate() OVERRIDE;
  virtual void Deactivate() OVERRIDE;
  virtual void Maximize() OVERRIDE;
  virtual void Minimize() OVERRIDE;
  virtual void Restore() OVERRIDE;
  virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE;
  virtual void FlashFrame(bool flash) OVERRIDE;
  virtual bool IsAlwaysOnTop() const OVERRIDE;

  // Overridden from CommandUpdaterDelegate:
  virtual void ExecuteCommandWithDisposition(
      int id,
      WindowOpenDisposition disposition) OVERRIDE;

  // content::NotificationObserver overrides.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

  // Construct a native panel implementation.
  static NativePanel* CreateNativePanel(Panel* panel,
                                        const gfx::Rect& bounds,
                                        bool always_on_top);

  NativePanel* native_panel() const { return native_panel_; }

  // Invoked when the native panel has detected a mouse click on the
  // panel's titlebar, minimize or restore buttons. Behavior of the
  // click may be modified as indicated by |modifier|.
  void OnTitlebarClicked(panel::ClickModifier modifier);
  void OnMinimizeButtonClicked(panel::ClickModifier modifier);
  void OnRestoreButtonClicked(panel::ClickModifier modifier);

  // Used on platforms where the panel cannot determine its window size
  // until the window has been created. (e.g. GTK)
  void OnWindowSizeAvailable();

  // Asynchronous completion of panel close request.
  void OnNativePanelClosed();

  // May be NULL if:
  // * panel is newly created and has not been positioned yet.
  // * panel is being closed asynchronously.
  // Please use it with caution.
  PanelCollection* collection() const { return collection_; }

  // Sets the current panel collection that contains this panel.
  void set_collection(PanelCollection* new_collection) {
    collection_ = new_collection;
  }

  StackedPanelCollection* stack() const;

  ExpansionState expansion_state() const { return expansion_state_; }
  const gfx::Size& min_size() const { return min_size_; }
  const gfx::Size& max_size() const { return max_size_; }
  bool auto_resizable() const { return auto_resizable_; }

  bool in_preview_mode() const { return in_preview_mode_; }

  panel::Resizability CanResizeByMouse() const;

  AttentionMode attention_mode() const { return attention_mode_; }
  void set_attention_mode(AttentionMode attention_mode) {
    attention_mode_ = attention_mode;
  }

  // The full size is the size of the panel when it is detached or expanded
  // in the docked collection and squeezing mode is not on.
  gfx::Size full_size() const { return full_size_; }
  void set_full_size(const gfx::Size& size) { full_size_ = size; }

  // Panel must be initialized to be "fully created" and ready for use.
  // Only called by PanelManager.
  bool initialized() const { return initialized_; }
  void Initialize(const GURL& url, const gfx::Rect& bounds, bool always_on_top);

  // This is different from BaseWindow::SetBounds():
  // * SetPanelBounds() is only called by PanelManager to manage its position.
  // * SetBounds() is called by the API to try to change the bounds, which may
  //   only change the size for Panel.
  void SetPanelBounds(const gfx::Rect& bounds);

  // Updates the panel bounds instantly without any animation.
  void SetPanelBoundsInstantly(const gfx::Rect& bounds);

  // Ensures that the panel's size does not exceed the work area by updating
  // maximum and full size of the panel. This is called each time when display
  // settings are changed. Note that bounds are not updated here and the call
  // of setting bounds or refreshing layout should be called after this.
  void LimitSizeToWorkArea(const gfx::Rect& work_area);

  // Sets whether the panel will auto resize according to its content.
  void SetAutoResizable(bool resizable);

  // Configures the web contents for auto resize, including configurations
  // on the renderer and detecting renderer changes.
  void EnableWebContentsAutoResize(content::WebContents* web_contents);

  // Invoked when the preferred window size of the given panel might need to
  // get changed due to the contents being auto-resized.
  void OnContentsAutoResized(const gfx::Size& new_content_size);

  // Resizes the panel and sets the origin. Invoked when the panel is resized
  // via the mouse.
  void OnWindowResizedByMouse(const gfx::Rect& new_bounds);

  // Sets minimum and maximum size for the panel.
  void SetSizeRange(const gfx::Size& min_size, const gfx::Size& max_size);

  // Updates the maximum size of the panel so that it's never smaller than the
  // panel's desired size. Note that even if the user resizes the panel smaller
  // later, the increased maximum size will still be in effect. Since it's not
  // possible currently to switch the panel back to autosizing from
  // user-resizable, it should not be a problem.
  void IncreaseMaxSize(const gfx::Size& desired_panel_size);

  // Handles keyboard events coming back from the renderer.
  void HandleKeyboardEvent(const content::NativeWebKeyboardEvent& event);

  // Whether the panel window is always on top.
  void SetAlwaysOnTop(bool on_top);

  // Sets whether the panel is shown in preview mode. When the panel is
  // being dragged, it is in preview mode.
  void SetPreviewMode(bool in_preview_mode);

  // Sets whether the minimize or restore button, if any, are visible.
  void UpdateMinimizeRestoreButtonVisibility();

  // Changes the preferred size to acceptable based on min_size() and max_size()
  gfx::Size ClampSize(const gfx::Size& size) const;

  // Called when the panel's active state changes.
  // |active| is true if panel became active.
  void OnActiveStateChanged(bool active);

  // Called when the panel starts/ends the user resizing.
  void OnPanelStartUserResizing();
  void OnPanelEndUserResizing();

  // Gives beforeunload handlers the chance to cancel the close.
  bool ShouldCloseWindow();

  // Invoked when the window containing us is closing. Performs the necessary
  // cleanup.
  void OnWindowClosing();

  // Executes a command if it's enabled.
  // Returns true if the command is executed.
  bool ExecuteCommandIfEnabled(int id);

  // Gets the title of the window from the web contents.
  string16 GetWindowTitle() const;

  // Gets the Favicon of the web contents.
  gfx::Image GetCurrentPageIcon() const;

  // Updates the title bar to display the current title and icon.
  void UpdateTitleBar();

  // Updates UI to reflect change in loading state.
  void LoadingStateChanged(bool is_loading);

  // Updates UI to reflect that the web cotents receives the focus.
  void WebContentsFocused(content::WebContents* contents);

  // Moves the panel by delta instantly.
  void MoveByInstantly(const gfx::Vector2d& delta_origin);

  // Applies |corner_style| to the panel window.
  void SetWindowCornerStyle(panel::CornerStyle corner_style);

  // Performs the system minimize for the panel, i.e. becoming iconic.
  void MinimizeBySystem();

  bool IsMinimizedBySystem() const;

  // Returns true if the panel is shown in the active desktop. The user could
  // create or use multiple desktops or workspaces.
  bool IsShownOnActiveDesktop() const;

  // Turns on/off the shadow effect around the window shape.
  void ShowShadow(bool show);

 protected:
  // Panel can only be created using PanelManager::CreatePanel() or subclass.
  // |app_name| is the default title for Panels when the page content does not
  // provide a title. For extensions, this is usually the application name
  // generated from the extension id.
  Panel(Profile* profile, const std::string& app_name,
        const gfx::Size& min_size, const gfx::Size& max_size);

 private:
  friend class PanelManager;
  friend class PanelBrowserTest;

  enum MaxSizePolicy {
    // Default maximum size is proportional to the work area.
    DEFAULT_MAX_SIZE,
    // Custom maximum size is used when the panel is resized by the user.
    CUSTOM_MAX_SIZE
  };

  void OnImageLoaded(const gfx::Image& image);

  // Initialize state for all supported commands.
  void InitCommandState();

  // Configures the renderer for auto resize (if auto resize is enabled).
  void ConfigureAutoResize(content::WebContents* web_contents);

  // Load the app's image, firing a load state change when loaded.
  void UpdateAppIcon();

  // Prepares a title string for display (removes embedded newlines, etc).
  static void FormatTitleForDisplay(string16* title);

  // The application name that is also the name of the window when the
  // page content does not provide a title.
  // This name should be set when the panel is created.
  const std::string app_name_;

  Profile* profile_;

  // Current collection of panels to which this panel belongs. This determines
  // the panel's screen layout.
  PanelCollection* collection_;  // Owned by PanelManager.

  bool initialized_;

  // Stores the full size of the panel so we can restore it after it's
  // been minimized or squeezed due to lack of space in the collection.
  gfx::Size full_size_;

  // This is the minimum size that the panel can shrink to.
  gfx::Size min_size_;

  // This is the size beyond which the panel is not going to grow to accomodate
  // the growing content and WebKit would add the scrollbars in such case.
  gfx::Size max_size_;

  MaxSizePolicy max_size_policy_;

  // True if this panel auto resizes based on content.
  bool auto_resizable_;

  // True if this panel is in preview mode. When in preview mode, panel bounds
  // should not be affected by layout refresh. This is currently used by drag
  // controller to add a panel to the collection without causing its bounds to
  // change.
  bool in_preview_mode_;

  // Platform specifc implementation for panels.  It'd be one of
  // PanelGtk/PanelView/PanelCocoa.
  NativePanel* native_panel_;  // Weak, owns us.

  AttentionMode attention_mode_;

  ExpansionState expansion_state_;

  // The CommandUpdater manages the window commands.
  CommandUpdater command_updater_;

  content::NotificationRegistrar registrar_;
  const SessionID session_id_;
  scoped_ptr<extensions::WindowController> extension_window_controller_;
  scoped_ptr<PanelHost> panel_host_;

  // Icon showed in the task bar.
  gfx::Image app_icon_;

  base::WeakPtrFactory<Panel> image_loader_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(Panel);
};

#endif  // CHROME_BROWSER_UI_PANELS_PANEL_H_
