text: // Copyright 2014 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.
  
  #include "content/nw/src/browser/nw_constrained_window_views_client.h"
  
  #include "base/memory/scoped_ptr.h"
  #include "base/observer_list.h"
  #include "components/constrained_window/constrained_window_views.h"
  #include "components/constrained_window/constrained_window_views_client.h"
  #include "components/web_modal/web_contents_modal_dialog_host.h"
  #include "extensions/browser/guest_view/guest_view_base.h"
  #include "ui/aura/window.h"
  #include "ui/aura/window_observer.h"
  #include "ui/aura/window_property.h"
  
  DECLARE_WINDOW_PROPERTY_TYPE(web_modal::ModalDialogHost*);
  
  namespace nw {
  namespace {
  
  // Provides the host environment for web modal dialogs. See
  // web_modal::WebContentsModalDialogHost, and ModalDialogHost for more
  // details.
  class ModalDialogHostImpl : public web_modal::WebContentsModalDialogHost,
                              public aura::WindowObserver {
   public:
    // Returns a modal dialog host for |window|. If it doesn't exist it creates
    // one and stores it as owned property.
    static ModalDialogHost* Get(aura::Window* window);
  
   private:
    explicit ModalDialogHostImpl(aura::Window* host_window)
        : host_window_(host_window) {
      host_window_->AddObserver(this);
    }
    ~ModalDialogHostImpl() override {}
  
    // web_modal::ModalDialogHost:
    gfx::NativeView GetHostView() const override {
      return host_window_;
    }
    gfx::Point GetDialogPosition(const gfx::Size& size) override {
      gfx::Size app_window_size = host_window_->GetBoundsInScreen().size();
      return gfx::Point(app_window_size.width() / 2 - size.width() / 2,
                      app_window_size.height() / 2 - size.height() / 2);
    }
    void AddObserver(web_modal::ModalDialogHostObserver* observer) override {
      observer_list_.AddObserver(observer);
    }
    void RemoveObserver(web_modal::ModalDialogHostObserver* observer) override {
      observer_list_.RemoveObserver(observer);
    }
  
    // web_modal::WebContensModalDialogHost:
    gfx::Size GetMaximumDialogSize() override {
      return host_window_->bounds().size();
    }
  
    // aura::WindowObserver:
    void OnWindowDestroying(aura::Window* window) override {
      if (window != host_window_)
        return;
      host_window_->RemoveObserver(this);
      FOR_EACH_OBSERVER(web_modal::ModalDialogHostObserver,
                        observer_list_,
                        OnHostDestroying());
    }
    void OnWindowBoundsChanged(aura::Window* window,
                               const gfx::Rect& old_bounds,
                               const gfx::Rect& new_bounds) override {
      if (window != host_window_)
        return;
      FOR_EACH_OBSERVER(web_modal::ModalDialogHostObserver,
                        observer_list_,
                        OnPositionRequiresUpdate());
    }
  
    aura::Window* host_window_;
    ObserverList<web_modal::ModalDialogHostObserver> observer_list_;
  
    DISALLOW_COPY_AND_ASSIGN(ModalDialogHostImpl);
  };
  
  // A window property key to store the modal dialog host for
  // dialogs created with the window as its parent.
  DEFINE_OWNED_WINDOW_PROPERTY_KEY(web_modal::ModalDialogHost,
                                   kModalDialogHostKey,
                                   nullptr);
  
  // static
  web_modal::ModalDialogHost* ModalDialogHostImpl::Get(
      aura::Window* window) {
    web_modal::ModalDialogHost* host = window->GetProperty(kModalDialogHostKey);
    if (!host) {
      host = new ModalDialogHostImpl(window);
      window->SetProperty(kModalDialogHostKey, host);
    }
    return host;
  }
  
  class NWConstrainedWindowViewsClient
      : public constrained_window::ConstrainedWindowViewsClient {
   public:
    NWConstrainedWindowViewsClient() {}
    ~NWConstrainedWindowViewsClient() override {}
  
   private:
    // ConstrainedWindowViewsClient:
    content::WebContents* GetEmbedderWebContents(
        content::WebContents* initiator_web_contents) override {
      extensions::GuestViewBase* guest_view =
          extensions::GuestViewBase::FromWebContents(initiator_web_contents);
      return guest_view && guest_view->embedder_web_contents() ?
          guest_view->embedder_web_contents() : initiator_web_contents;
    }
    web_modal::ModalDialogHost* GetModalDialogHost(
        gfx::NativeWindow parent) override {
      return ModalDialogHostImpl::Get(parent);
    }
    gfx::NativeView GetDialogHostView(gfx::NativeWindow parent) override {
      return parent;
    }
  
    DISALLOW_COPY_AND_ASSIGN(NWConstrainedWindowViewsClient);
  };
  
  }  // namespace
  
  void InstallConstrainedWindowViewsClient() {
    constrained_window::SetConstrainedWindowViewsClient(
        make_scoped_ptr(new NWConstrainedWindowViewsClient));
  }
  
  void UninstallConstrainedWindowViewsClient() {
    constrained_window::SetConstrainedWindowViewsClient(nullptr);
  }
  
  }  // namespace athena
  