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

#include <string>
#include <vector>

#include "ash/ash_export.h"
#include "ash/display/display_info.h"
#include "ash/display/display_layout.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/display.h"

#if defined(OS_CHROMEOS)
#include "chromeos/display/output_configurator.h"
#endif

namespace gfx {
class Display;
class Insets;
class Rect;
}

namespace ash {
class AcceleratorControllerTest;
class DisplayController;

namespace test {
class DisplayManagerTestApi;
class SystemGestureEventFilterTest;
}
namespace internal {
class DisplayLayoutStore;

// DisplayManager maintains the current display configurations,
// and notifies observers when configuration changes.
//
// TODO(oshima): Make this non internal.
class ASH_EXPORT DisplayManager
#if defined(OS_CHROMEOS)
    : public chromeos::OutputConfigurator::SoftwareMirroringController
#endif
      {
 public:
  class ASH_EXPORT Delegate {
   public:
    virtual ~Delegate() {}

    // Create or updates the non desktop window with |display_info|.
    virtual void CreateOrUpdateNonDesktopDisplay(
        const DisplayInfo& display_info) = 0;

    // Closes the mirror window if exists.
    virtual void CloseNonDesktopDisplay() = 0;

    // Called before and after the display configuration changes.
    virtual void PreDisplayConfigurationChange(bool display_removed) = 0;
    virtual void PostDisplayConfigurationChange() = 0;
  };

  // How the second display will be used.
  // 1) EXTENDED mode extends the desktop to the second dislpay.
  // 2) MIRRORING mode copies the content of the primary display to
  //    the 2nd display. (Software Mirroring).
  // 3) In VIRTUAL_KEYBOARD mode, the 2nd display is used as a
  //    dedicated display for virtual keyboard, and it is not
  //    recognized as a part of desktop.
  enum SecondDisplayMode {
    EXTENDED,
    MIRRORING,
    VIRTUAL_KEYBOARD
  };

  // Returns the list of possible UI scales for the display.
  static std::vector<float> GetScalesForDisplay(const DisplayInfo& info);

  // Returns next valid UI scale.
  static float GetNextUIScale(const DisplayInfo& info, bool up);

  // Updates the bounds of the display given by |secondary_display_id|
  // according to |layout|.
  static void UpdateDisplayBoundsForLayoutById(
      const DisplayLayout& layout,
      const gfx::Display& primary_display,
      int64 secondary_display_id);

  DisplayManager();
  virtual ~DisplayManager();

  DisplayLayoutStore* layout_store() {
    return layout_store_.get();
  }

  void set_delegate(Delegate* delegate) { delegate_ = delegate; }

  // When set to true, the MonitorManager calls OnDisplayBoundsChanged
  // even if the display's bounds didn't change. Used to swap primary
  // display.
  void set_force_bounds_changed(bool force_bounds_changed) {
    force_bounds_changed_ = force_bounds_changed;
  }

  // Returns the display id of the first display in the outupt list.
  int64 first_display_id() const { return first_display_id_; }

  // Initializes displays using command line flag. Returns false
  // if no command line flag was provided.
  bool InitFromCommandLine();

  // Initialize default display.
  void InitDefaultDisplay();

  // True if the given |display| is currently connected.
  bool IsActiveDisplay(const gfx::Display& display) const;

  // True if there is an internal display.
  bool HasInternalDisplay() const;

  bool IsInternalDisplayId(int64 id) const;

  // Returns the display layout used for current displays.
  DisplayLayout GetCurrentDisplayLayout();

  // Returns the current display pair.
  DisplayIdPair GetCurrentDisplayIdPair() const;

  // Sets the layout for the current display pair. The |layout| specifies
  // the locaion of the secondary display relative to the primary.
  void SetLayoutForCurrentDisplays(
      const DisplayLayout& layout_relative_to_primary);

  // Returns display for given |id|;
  const gfx::Display& GetDisplayForId(int64 id) const;

  // Finds the display that contains |point| in screeen coordinates.
  // Returns invalid display if there is no display that can satisfy
  // the condition.
  const gfx::Display& FindDisplayContainingPoint(
      const gfx::Point& point_in_screen) const;

  // Sets the work area's |insets| to the display given by |display_id|.
  bool UpdateWorkAreaOfDisplay(int64 display_id, const gfx::Insets& insets);

  // Registers the overscan insets for the display of the specified ID. Note
  // that the insets size should be specified in DIP size. It also triggers the
  // display's bounds change.
  void SetOverscanInsets(int64 display_id, const gfx::Insets& insets_in_dip);

  // Sets the display's rotation.
  void SetDisplayRotation(int64 display_id, gfx::Display::Rotation rotation);

  // Sets the display's ui scale.
  void SetDisplayUIScale(int64 display_id, float ui_scale);

  // Sets the display's resolution.
  void SetDisplayResolution(int64 display_id, const gfx::Size& resolution);

  // Register per display properties. |overscan_insets| is NULL if
  // the display has no custom overscan insets.
  void RegisterDisplayProperty(int64 display_id,
                               gfx::Display::Rotation rotation,
                               float ui_scale,
                               const gfx::Insets* overscan_insets,
                               const gfx::Size& resolution_in_pixels);

  // Returns the display's selected resolution.
  bool GetSelectedResolutionForDisplayId(int64 display_id,
                                         gfx::Size* resolution_out) const;

  // Tells if the virtual resolution feature is enabled.
  bool IsDisplayUIScalingEnabled() const;

  // Returns the current overscan insets for the specified |display_id|.
  // Returns an empty insets (0, 0, 0, 0) if no insets are specified for
  // the display.
  gfx::Insets GetOverscanInsets(int64 display_id) const;

  // Called when display configuration has changed. The new display
  // configurations is passed as a vector of Display object, which
  // contains each display's new infomration.
  void OnNativeDisplaysChanged(
      const std::vector<DisplayInfo>& display_info_list);

  // Updates the internal display data and notifies observers about the changes.
  void UpdateDisplays(const std::vector<DisplayInfo>& display_info_list);

  // Updates current displays using current |display_info_|.
  void UpdateDisplays();

  // Returns the display at |index|. The display at 0 is
  // no longer considered "primary".
  const gfx::Display& GetDisplayAt(size_t index) const;

  const gfx::Display& GetPrimaryDisplayCandidate() const;

  // Returns the logical number of displays. This returns 1
  // when displays are mirrored.
  size_t GetNumDisplays() const;

  const std::vector<gfx::Display>& displays() const { return displays_; }

  // Returns the number of connected displays. This returns 2
  // when displays are mirrored.
  size_t num_connected_displays() const { return num_connected_displays_; }

  // Returns the mirroring status.
  bool IsMirrored() const;
  int64 mirrored_display_id() const { return mirrored_display_id_; }

  // Returns the display object that is not a part of desktop.
  const gfx::Display& non_desktop_display() const {
    return non_desktop_display_;
  }

  // Retuns the display info associated with |display_id|.
  const DisplayInfo& GetDisplayInfo(int64 display_id) const;

  // Returns the human-readable name for the display |id|.
  std::string GetDisplayNameForId(int64 id);

  // Returns the display id that is capable of UI scaling. On device,
  // this returns internal display's ID if its device scale factor is 2,
  // or invalid ID if such internal display doesn't exist. On linux
  // desktop, this returns the first display ID.
  int64 GetDisplayIdForUIScaling() const;

  // Change the mirror mode.
  void SetMirrorMode(bool mirrored);

  // Used to emulate display change when run in a desktop environment instead
  // of on a device.
  void AddRemoveDisplay();
  void ToggleDisplayScaleFactor();

  // SoftwareMirroringController override:
#if defined(OS_CHROMEOS)
  virtual void SetSoftwareMirroring(bool enabled) OVERRIDE;
#endif
  bool software_mirroring_enabled() const {
    return second_display_mode_ == MIRRORING;
  };

  // Sets/gets second display mode.
  void SetSecondDisplayMode(SecondDisplayMode mode);
  SecondDisplayMode second_display_mode() const {
    return second_display_mode_;
  }

  // Update the bounds of the display given by |display_id|.
  bool UpdateDisplayBounds(int64 display_id,
                           const gfx::Rect& new_bounds);

  // Creates mirror window if the software mirror mode is enabled.
  // This is used only for bootstrap.
  void CreateMirrorWindowIfAny();

private:
  FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, ConvertPoint);
  FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, TestNativeDisplaysChanged);
  FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest,
                           NativeDisplaysChangedAfterPrimaryChange);
  FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, AutomaticOverscanInsets);
  friend class ash::AcceleratorControllerTest;
  friend class test::DisplayManagerTestApi;
  friend class test::SystemGestureEventFilterTest;
  friend class DisplayManagerTest;

  typedef std::vector<gfx::Display> DisplayList;

  void set_change_display_upon_host_resize(bool value) {
    change_display_upon_host_resize_ = value;
  }

  gfx::Display* FindDisplayForId(int64 id);

  // Add the mirror display's display info if the software based
  // mirroring is in use.
  void AddMirrorDisplayInfoIfAny(std::vector<DisplayInfo>* display_info_list);

  // Inserts and update the DisplayInfo according to the overscan
  // state. Note that The DisplayInfo stored in the |internal_display_info_|
  // can be different from |new_info| (due to overscan state), so
  // you must use |GetDisplayInfo| to get the correct DisplayInfo for
  // a display.
  void InsertAndUpdateDisplayInfo(const DisplayInfo& new_info);

  // Creates a display object from the DisplayInfo for |display_id|.
  gfx::Display CreateDisplayFromDisplayInfoById(int64 display_id);

  // Updates the bounds of the secondary display in |display_list|
  // using the layout registered for the display pair and set the
  // index of display updated to |updated_index|. Returns true
  // if the secondary display's bounds has been changed from current
  // value, or false otherwise.
  bool UpdateSecondaryDisplayBoundsForLayout(DisplayList* display_list,
                                             size_t* updated_index) const;

  static void UpdateDisplayBoundsForLayout(
      const DisplayLayout& layout,
      const gfx::Display& primary_display,
      gfx::Display* secondary_display);

  Delegate* delegate_;  // not owned.

  scoped_ptr<DisplayLayoutStore> layout_store_;

  int64 first_display_id_;

  // List of current active dispays.
  DisplayList displays_;

  int num_connected_displays_;

  bool force_bounds_changed_;

  // The mapping from the display ID to its internal data.
  std::map<int64, DisplayInfo> display_info_;

  // Selected resolutions for displays. Key is the displays' ID.
  std::map<int64, gfx::Size> resolutions_;

  // When set to true, the host window's resize event updates
  // the display's size. This is set to true when running on
  // desktop environment (for debugging) so that resizing the host
  // window wil update the display properly. This is set to false
  // on device as well as during the unit tests.
  bool change_display_upon_host_resize_;

  SecondDisplayMode second_display_mode_;
  int64 mirrored_display_id_;
  gfx::Display non_desktop_display_;

  DISALLOW_COPY_AND_ASSIGN(DisplayManager);
};

}  // namespace internal
}  // namespace ash

#endif  // ASH_DISPLAY_DISPLAY_MANAGER_H_
