// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_LINUX_LINUX_UI_H_
#define UI_LINUX_LINUX_UI_H_

#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "base/command_line.h"
#include "base/component_export.h"
#include "base/containers/flat_map.h"
#include "base/observer_list.h"
#include "base/scoped_observation_traits.h"
#include "build/buildflag.h"
#include "build/chromecast_buildflags.h"
#include "printing/buildflags/buildflags.h"
#include "ui/display/types/display_config.h"

// The main entrypoint into Linux toolkit specific code. GTK/QT code should only
// be executed behind this interface.

using SkColor = uint32_t;
// TODO(thomasanderson): Remove Profile forward declaration.
class Profile;

namespace aura {
class Window;
}

namespace gfx {
struct FontRenderParams;
class Image;
class Size;
}  // namespace gfx

namespace printing {
class PrintingContextLinux;
class PrintDialogLinuxInterface;
}  // namespace printing

namespace ui {

class CursorThemeManagerObserver;
class DeviceScaleFactorObserver;
class Event;
class LinuxInputMethodContext;
class LinuxInputMethodContextDelegate;
class LinuxUiTheme;
class NativeTheme;
class NavButtonProvider;
class SelectFileDialog;
class SelectFilePolicy;
class WindowButtonOrderObserver;
class WindowFrameProvider;
enum class TextEditCommand;

// Adapter class with targets to render like different toolkits. Set by any
// project that wants to do linux desktop native rendering.
class COMPONENT_EXPORT(LINUX_UI) LinuxUi {
 public:
  // Describes the window management actions that could be taken in response to
  // a middle click in the non client area.
  enum class WindowFrameAction {
    kNone,
    kLower,
    kMinimize,
    kToggleMaximize,
    kMenu,
  };

  // The types of clicks that might invoke a WindowFrameAction.
  enum class WindowFrameActionSource {
    kDoubleClick,
    kMiddleClick,
    kRightClick,
  };

  struct FontSettings {
    std::string family;
    int size_pixels = 0;
    // Holds a bitfield of gfx::Font::Style values.
    int style = 0;
    // A standard font weight as used in Pango.  Must be a value in [1, 999].
    int weight = 0;
  };

  LinuxUi(const LinuxUi&) = delete;
  LinuxUi& operator=(const LinuxUi&) = delete;
  virtual ~LinuxUi();

  // Sets the dynamically loaded singleton that draws the desktop native UI.
  // Returns the old instance if any.
  static LinuxUi* SetInstance(LinuxUi* instance);

  // Returns a LinuxUI instance for the toolkit used in the user's desktop
  // environment.
  //
  // Can return NULL, in case no toolkit has been set. (For example, if we're
  // running with the "--ash" flag.)
  static LinuxUi* instance();

  // Registers |observer| to be notified about changes to the device
  // scale factor.
  void AddDeviceScaleFactorObserver(DeviceScaleFactorObserver* observer);

  // Unregisters |observer| from receiving changes to the device scale
  // factor.
  void RemoveDeviceScaleFactorObserver(DeviceScaleFactorObserver* observer);

  // Adds |observer| and makes initial OnCursorThemNameChanged() and/or
  // OnCursorThemeSizeChanged() calls if the respective settings were set.
  void AddCursorThemeObserver(CursorThemeManagerObserver* observer);

  void RemoveCursorThemeObserver(CursorThemeManagerObserver* observer);

  // Returns details about the default UI font.
  FontSettings GetDefaultFontDescription();

  // Determines the device scale factor for all screens.
  const display::DisplayConfig& display_config() const {
    return display_config_;
  }

  // Returns true on success.  If false is returned, this instance shouldn't
  // be used and the behavior of all functions is undefined.
  [[nodiscard]] virtual bool Initialize() = 0;

  // Caches the default font render parameters.  This doesn't need to be called
  // explicitly since the first call to get the font settings will implicitly
  // initialize the default front render parameters.
  virtual void InitializeFontSettings() = 0;

  // Returns the icon for a given content type from the icon theme.
  // TODO(davidben): Add an observer for the theme changing, so we can drop the
  // caches.
  virtual gfx::Image GetIconForContentType(const std::string& content_type,
                                           int size,
                                           float scale) const = 0;

  // Returns a map of KeyboardEvent code to KeyboardEvent key values.
  virtual base::flat_map<std::string, std::string> GetKeyboardLayoutMap() = 0;

#if BUILDFLAG(ENABLE_PRINTING)
  virtual printing::PrintDialogLinuxInterface* CreatePrintDialog(
      printing::PrintingContextLinux* context) = 0;

  virtual gfx::Size GetPdfPaperSize(
      printing::PrintingContextLinux* context) = 0;
#endif

  // Returns a native file selection dialog.  `listener` is of type
  // SelectFileDialog::Listener.  TODO(thomasanderson): Move
  // SelectFileDialog::Listener to SelectFileDialogListener so that it can be
  // forward declared.
  virtual SelectFileDialog* CreateSelectFileDialog(
      void* listener,
      std::unique_ptr<SelectFilePolicy> policy) const = 0;

  // Returns the prefererd theme name for cursor loading.
  virtual std::string GetCursorThemeName() = 0;

  // Returns the preferred size for cursor bitmaps.  A value of 64 indicates
  // that 64x64 px bitmaps are preferred.
  virtual int GetCursorThemeSize() = 0;

  // Returns a platform specific input method context.
  virtual std::unique_ptr<LinuxInputMethodContext> CreateInputMethodContext(
      LinuxInputMethodContextDelegate* delegate) const = 0;

  // Matches a key event against the users' platform specific key bindings.
  // Returns ui::TextEditCommand::INVALID_COMMAND if the key event doesn't
  // correspond to a predefined key binding.
  //
  // `text_flags` is the current ui::TextInputFlags if available.
  virtual TextEditCommand GetTextEditCommandForEvent(const Event& event,
                                                     int text_flags) = 0;

  // Returns the default font rendering settings.
  virtual gfx::FontRenderParams GetDefaultFontRenderParams() = 0;

  // Indicates if animations are enabled by the toolkit.
  virtual bool AnimationsEnabled() const = 0;

  // Notifies the observer about changes about how window buttons should be
  // laid out.
  virtual void AddWindowButtonOrderObserver(
      WindowButtonOrderObserver* observer) = 0;

  // Removes the observer from the LinuxUI's list.
  virtual void RemoveWindowButtonOrderObserver(
      WindowButtonOrderObserver* observer) = 0;

  // What action we should take when the user clicks on the non-client area.
  // |source| describes the type of click.
  virtual WindowFrameAction GetWindowFrameAction(
      WindowFrameActionSource source) = 0;

  // Returns the command line flags that should be copied to subprocesses
  // to have the same toolkit and version as this process.
  virtual std::vector<std::string> GetCmdLineFlagsForCopy() const = 0;

 protected:
  struct CmdLineArgs {
    CmdLineArgs();
    CmdLineArgs(CmdLineArgs&&);
    CmdLineArgs& operator=(CmdLineArgs&&);
    ~CmdLineArgs();

    // `argc` is modified by toolkits, so store it explicitly.
    int argc = 0;

    // Contains C-strings that point into `args`.  `argv.size()` >= `argc`.
    std::vector<char*> argv;

    // `argv` concatenated with NUL characters.
    std::vector<char> args;
  };

  LinuxUi();

  static CmdLineArgs CopyCmdLine(const base::CommandLine& command_line);

  base::ObserverList<DeviceScaleFactorObserver>::Unchecked&
  device_scale_factor_observer_list() {
    return device_scale_factor_observer_list_;
  }

  base::ObserverList<CursorThemeManagerObserver>& cursor_theme_observers() {
    return cursor_theme_observer_list_;
  }

  display::DisplayConfig& display_config() { return display_config_; }

  void set_default_font_settings(
      const std::optional<FontSettings>& default_font_settings) {
    default_font_settings_ = default_font_settings;
  }

 private:
  // Objects to notify when the device scale factor changes.
  base::ObserverList<DeviceScaleFactorObserver>::Unchecked
      device_scale_factor_observer_list_;

  // Objects to notify when the cursor theme or size changes.
  base::ObserverList<CursorThemeManagerObserver> cursor_theme_observer_list_;

  display::DisplayConfig display_config_;

  std::optional<FontSettings> default_font_settings_;
};

class COMPONENT_EXPORT(LINUX_UI) LinuxUiTheme {
 public:
  LinuxUiTheme(const LinuxUiTheme&) = delete;
  LinuxUiTheme& operator=(const LinuxUiTheme&) = delete;
  virtual ~LinuxUiTheme();

  // Returns the LinuxUi instance for the given window, or the default instance
  // if the window is nullptr.
  static LinuxUiTheme* GetForWindow(aura::Window* window);

  // Returns the LinuxUi instance for the given profile, or the default instance
  // if the profile is nullptr.
  static LinuxUiTheme* GetForProfile(Profile* profile);

  // Returns the native theme for this toolkit.
  virtual ui::NativeTheme* GetNativeTheme() const = 0;

  virtual bool GetColor(int id,
                        SkColor* color,
                        bool use_custom_frame) const = 0;
  virtual bool GetDisplayProperty(int id, int* result) const = 0;

  // Returns the preferences that we pass to Blink.
  virtual void GetFocusRingColor(SkColor* color) const = 0;
  virtual void GetActiveSelectionBgColor(SkColor* color) const = 0;
  virtual void GetActiveSelectionFgColor(SkColor* color) const = 0;
  virtual void GetInactiveSelectionBgColor(SkColor* color) const = 0;
  virtual void GetInactiveSelectionFgColor(SkColor* color) const = 0;

  // Only used on GTK to indicate if the dark GTK theme variant is
  // preferred.
  virtual bool PreferDarkTheme() const = 0;

  // Override the toolkit's dark mode preference.  Used when the dark mode
  // setting is provided by org.freedesktop.appearance instead of the toolkit.
  virtual void SetDarkTheme(bool dark) = 0;

  // Override the toolkit's accent color.
  virtual void SetAccentColor(std::optional<SkColor> accent_color) = 0;

  // Returns a new NavButtonProvider, or nullptr if the underlying
  // toolkit does not support drawing client-side navigation buttons.
  virtual std::unique_ptr<NavButtonProvider> CreateNavButtonProvider() = 0;

  // Returns a WindowFrameProvider, or nullptr if the underlying toolkit does
  // not support drawing client-side window decorations. |solid_frame| indicates
  // if transparency is unsupported and the frame should be rendered opaque.
  // The returned object is not owned by the caller and will remain alive until
  // the process ends.
  virtual WindowFrameProvider* GetWindowFrameProvider(bool solid_frame,
                                                      bool tiled,
                                                      bool maximized) = 0;

 protected:
  LinuxUiTheme();
};

// This is used internally by LinuxUi implementations and linux_ui_factory to
// allow converting a LinuxUi to a LinuxUiTheme.  Users should not use (and have
// no way of obtaining) an instance of this class.
class LinuxUiAndTheme : public LinuxUi, public LinuxUiTheme {
 public:
  ~LinuxUiAndTheme() override = default;
};

}  // namespace ui

namespace base {

template <>
struct ScopedObservationTraits<ui::LinuxUi, ui::CursorThemeManagerObserver> {
  static void AddObserver(ui::LinuxUi* source,
                          ui::CursorThemeManagerObserver* observer) {
    source->AddCursorThemeObserver(observer);
  }
  static void RemoveObserver(ui::LinuxUi* source,
                             ui::CursorThemeManagerObserver* observer) {
    source->RemoveCursorThemeObserver(observer);
  }
};

template <>
struct ScopedObservationTraits<ui::LinuxUi, ui::DeviceScaleFactorObserver> {
  static void AddObserver(ui::LinuxUi* source,
                          ui::DeviceScaleFactorObserver* observer) {
    source->AddDeviceScaleFactorObserver(observer);
  }
  static void RemoveObserver(ui::LinuxUi* source,
                             ui::DeviceScaleFactorObserver* observer) {
    source->RemoveDeviceScaleFactorObserver(observer);
  }
};

template <>
struct ScopedObservationTraits<ui::LinuxUi, ui::WindowButtonOrderObserver> {
  static void AddObserver(ui::LinuxUi* source,
                          ui::WindowButtonOrderObserver* observer) {
    source->AddWindowButtonOrderObserver(observer);
  }
  static void RemoveObserver(ui::LinuxUi* source,
                             ui::WindowButtonOrderObserver* observer) {
    source->RemoveWindowButtonOrderObserver(observer);
  }
};

}  // namespace base

#endif  // UI_LINUX_LINUX_UI_H_
