// 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 "view_manager/cpp/view.h"

#include <set>
#include <string>

#include "mojo/public/cpp/application/service_provider_impl.h"
#include "view_manager/cpp/lib/view_manager_client_impl.h"
#include "view_manager/cpp/lib/view_private.h"
#include "view_manager/cpp/view_observer.h"
#include "view_manager/cpp/view_tracker.h"

namespace mojo {

namespace {

void NotifyViewTreeChangeAtReceiver(
    View* receiver,
    const ViewObserver::TreeChangeParams& params,
    bool change_applied) {
  ViewObserver::TreeChangeParams local_params = params;
  local_params.receiver = receiver;
  if (change_applied) {
    FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(receiver).observers(),
                      OnTreeChanged(local_params));
  } else {
    FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(receiver).observers(),
                      OnTreeChanging(local_params));
  }
}

void NotifyViewTreeChangeUp(View* start_at,
                            const ViewObserver::TreeChangeParams& params,
                            bool change_applied) {
  for (View* current = start_at; current; current = current->parent())
    NotifyViewTreeChangeAtReceiver(current, params, change_applied);
}

void NotifyViewTreeChangeDown(View* start_at,
                              const ViewObserver::TreeChangeParams& params,
                              bool change_applied) {
  NotifyViewTreeChangeAtReceiver(start_at, params, change_applied);
  View::Children::const_iterator it = start_at->children().begin();
  for (; it != start_at->children().end(); ++it)
    NotifyViewTreeChangeDown(*it, params, change_applied);
}

void NotifyViewTreeChange(const ViewObserver::TreeChangeParams& params,
                          bool change_applied) {
  NotifyViewTreeChangeDown(params.target, params, change_applied);
  if (params.old_parent)
    NotifyViewTreeChangeUp(params.old_parent, params, change_applied);
  if (params.new_parent)
    NotifyViewTreeChangeUp(params.new_parent, params, change_applied);
}

class ScopedTreeNotifier {
 public:
  ScopedTreeNotifier(View* target, View* old_parent, View* new_parent) {
    params_.target = target;
    params_.old_parent = old_parent;
    params_.new_parent = new_parent;
    NotifyViewTreeChange(params_, false);
  }
  ~ScopedTreeNotifier() { NotifyViewTreeChange(params_, true); }

 private:
  ViewObserver::TreeChangeParams params_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedTreeNotifier);
};

void RemoveChildImpl(View* child, View::Children* children) {
  View::Children::iterator it =
      std::find(children->begin(), children->end(), child);
  if (it != children->end()) {
    children->erase(it);
    ViewPrivate(child).ClearParent();
  }
}

class ScopedOrderChangedNotifier {
 public:
  ScopedOrderChangedNotifier(View* view,
                             View* relative_view,
                             OrderDirection direction)
      : view_(view), relative_view_(relative_view), direction_(direction) {
    FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view_).observers(),
                      OnViewReordering(view_, relative_view_, direction_));
  }
  ~ScopedOrderChangedNotifier() {
    FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view_).observers(),
                      OnViewReordered(view_, relative_view_, direction_));
  }

 private:
  View* view_;
  View* relative_view_;
  OrderDirection direction_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedOrderChangedNotifier);
};

// Returns true if the order actually changed.
bool ReorderImpl(View::Children* children,
                 View* view,
                 View* relative,
                 OrderDirection direction) {
  DCHECK(relative);
  DCHECK_NE(view, relative);
  DCHECK_EQ(view->parent(), relative->parent());

  const size_t child_i =
      std::find(children->begin(), children->end(), view) - children->begin();
  const size_t target_i =
      std::find(children->begin(), children->end(), relative) -
      children->begin();
  if ((direction == OrderDirection::ABOVE && child_i == target_i + 1) ||
      (direction == OrderDirection::BELOW && child_i + 1 == target_i)) {
    return false;
  }

  ScopedOrderChangedNotifier notifier(view, relative, direction);

  const size_t dest_i = direction == OrderDirection::ABOVE
                            ? (child_i < target_i ? target_i : target_i + 1)
                            : (child_i < target_i ? target_i - 1 : target_i);
  children->erase(children->begin() + child_i);
  children->insert(children->begin() + dest_i, view);

  return true;
}

class ScopedSetBoundsNotifier {
 public:
  ScopedSetBoundsNotifier(View* view,
                          const Rect& old_bounds,
                          const Rect& new_bounds)
      : view_(view), old_bounds_(old_bounds), new_bounds_(new_bounds) {
    FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view_).observers(),
                      OnViewBoundsChanging(view_, old_bounds_, new_bounds_));
  }
  ~ScopedSetBoundsNotifier() {
    FOR_EACH_OBSERVER(ViewObserver, *ViewPrivate(view_).observers(),
                      OnViewBoundsChanged(view_, old_bounds_, new_bounds_));
  }

 private:
  View* view_;
  const Rect old_bounds_;
  const Rect new_bounds_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedSetBoundsNotifier);
};

// Some operations are only permitted in the connection that created the view.
bool OwnsView(ViewManager* manager, View* view) {
  return !manager ||
         static_cast<ViewManagerClientImpl*>(manager)->OwnsView(view->id());
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// View, public:

void View::Destroy() {
  if (!OwnsView(manager_, this))
    return;

  if (manager_)
    static_cast<ViewManagerClientImpl*>(manager_)->DestroyView(id_);
  while (!children_.empty()) {
    View* child = children_.front();
    if (!OwnsView(manager_, child)) {
      ViewPrivate(child).ClearParent();
      children_.erase(children_.begin());
    } else {
      child->Destroy();
      DCHECK(std::find(children_.begin(), children_.end(), child) ==
             children_.end());
    }
  }
  LocalDestroy();
}

void View::SetBounds(const Rect& bounds) {
  if (!OwnsView(manager_, this))
    return;

  if (bounds_.Equals(bounds))
    return;

  if (manager_)
    static_cast<ViewManagerClientImpl*>(manager_)->SetBounds(id_, bounds);
  LocalSetBounds(bounds_, bounds);
}

void View::SetVisible(bool value) {
  if (visible_ == value)
    return;

  if (manager_)
    static_cast<ViewManagerClientImpl*>(manager_)->SetVisible(id_, value);
  LocalSetVisible(value);
}

void View::SetSharedProperty(const std::string& name,
                             const std::vector<uint8_t>* value) {
  std::vector<uint8_t> old_value;
  std::vector<uint8_t>* old_value_ptr = nullptr;
  auto it = properties_.find(name);
  if (it != properties_.end()) {
    old_value = it->second;
    old_value_ptr = &old_value;

    if (value && old_value == *value)
      return;
  } else if (!value) {
    // This property isn't set in |properties_| and |value| is NULL, so there's
    // no change.
    return;
  }

  if (value) {
    properties_[name] = *value;
  } else if (it != properties_.end()) {
    properties_.erase(it);
  }

  // TODO: add test coverage of this (450303).
  if (manager_) {
    Array<uint8_t> transport_value;
    if (value) {
      transport_value.resize(value->size());
      if (value->size())
        memcpy(&transport_value.front(), &(value->front()), value->size());
    }
    static_cast<ViewManagerClientImpl*>(manager_)
        ->SetProperty(id_, name, transport_value.Pass());
  }

  FOR_EACH_OBSERVER(
      ViewObserver, observers_,
      OnViewSharedPropertyChanged(this, name, old_value_ptr, value));
}

bool View::IsDrawn() const {
  if (!visible_)
    return false;
  return parent_ ? parent_->IsDrawn() : drawn_;
}

void View::AddObserver(ViewObserver* observer) {
  observers_.AddObserver(observer);
}

void View::RemoveObserver(ViewObserver* observer) {
  observers_.RemoveObserver(observer);
}

const View* View::GetRoot() const {
  const View* root = this;
  for (const View* parent = this; parent; parent = parent->parent())
    root = parent;
  return root;
}

void View::AddChild(View* child) {
  // TODO(beng): not necessarily valid to all connections, but possibly to the
  //             embeddee in an embedder-embeddee relationship.
  if (manager_)
    CHECK_EQ(child->view_manager(), manager_);
  LocalAddChild(child);
  if (manager_)
    static_cast<ViewManagerClientImpl*>(manager_)->AddChild(child->id(), id_);
}

void View::RemoveChild(View* child) {
  // TODO(beng): not necessarily valid to all connections, but possibly to the
  //             embeddee in an embedder-embeddee relationship.
  if (manager_)
    CHECK_EQ(child->view_manager(), manager_);
  LocalRemoveChild(child);
  if (manager_) {
    static_cast<ViewManagerClientImpl*>(manager_)
        ->RemoveChild(child->id(), id_);
  }
}

void View::MoveToFront() {
  if (!parent_ || parent_->children_.back() == this)
    return;
  Reorder(parent_->children_.back(), OrderDirection::ABOVE);
}

void View::MoveToBack() {
  if (!parent_ || parent_->children_.front() == this)
    return;
  Reorder(parent_->children_.front(), OrderDirection::BELOW);
}

void View::Reorder(View* relative, OrderDirection direction) {
  if (!LocalReorder(relative, direction))
    return;
  if (manager_) {
    static_cast<ViewManagerClientImpl*>(manager_)
        ->Reorder(id_, relative->id(), direction);
  }
}

bool View::Contains(View* child) const {
  if (!child)
    return false;
  if (child == this)
    return true;
  if (manager_)
    CHECK_EQ(child->view_manager(), manager_);
  for (View* p = child->parent(); p; p = p->parent()) {
    if (p == this)
      return true;
  }
  return false;
}

View* View::GetChildById(Id id) {
  if (id == id_)
    return this;
  // TODO(beng): this could be improved depending on how we decide to own views.
  Children::const_iterator it = children_.begin();
  for (; it != children_.end(); ++it) {
    View* view = (*it)->GetChildById(id);
    if (view)
      return view;
  }
  return NULL;
}

void View::SetSurfaceId(SurfaceIdPtr id) {
  if (manager_) {
    static_cast<ViewManagerClientImpl*>(manager_)->SetSurfaceId(id_, id.Pass());
  }
}

void View::SetFocus() {
  if (manager_)
    static_cast<ViewManagerClientImpl*>(manager_)->SetFocus(id_);
}

void View::Embed(const String& url) {
  if (PrepareForEmbed())
    static_cast<ViewManagerClientImpl*>(manager_)->Embed(url, id_);
}

void View::Embed(const String& url,
                 InterfaceRequest<ServiceProvider> services,
                 ServiceProviderPtr exposed_services) {
  if (PrepareForEmbed()) {
    static_cast<ViewManagerClientImpl*>(manager_)
        ->Embed(url, id_, services.Pass(), exposed_services.Pass());
  }
}

void View::Embed(ViewManagerClientPtr client) {
  if (PrepareForEmbed())
    static_cast<ViewManagerClientImpl*>(manager_)->Embed(id_, client.Pass());
}

////////////////////////////////////////////////////////////////////////////////
// View, protected:

namespace {

ViewportMetricsPtr CreateEmptyViewportMetrics() {
  ViewportMetricsPtr metrics = ViewportMetrics::New();
  metrics->size = Size::New();
  return metrics;
}

}  // namespace

View::View()
    : manager_(NULL),
      id_(static_cast<Id>(-1)),
      parent_(NULL),
      viewport_metrics_(CreateEmptyViewportMetrics()),
      visible_(true),
      drawn_(false) {}

View::~View() {
  FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDestroying(this));
  if (parent_)
    parent_->LocalRemoveChild(this);

  // We may still have children. This can happen if the embedder destroys the
  // root while we're still alive.
  while (!children_.empty()) {
    View* child = children_.front();
    LocalRemoveChild(child);
    DCHECK(children_.empty() || children_.front() != child);
  }

  // TODO(beng): It'd be better to do this via a destruction observer in the
  //             ViewManagerClientImpl.
  if (manager_)
    static_cast<ViewManagerClientImpl*>(manager_)->RemoveView(id_);

  // Clear properties.
  for (auto& pair : prop_map_) {
    if (pair.second.deallocator)
      (*pair.second.deallocator)(pair.second.value);
  }
  prop_map_.clear();

  FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDestroyed(this));
}

////////////////////////////////////////////////////////////////////////////////
// View, private:

View::View(ViewManager* manager, Id id)
    : manager_(manager),
      id_(id),
      parent_(nullptr),
      viewport_metrics_(CreateEmptyViewportMetrics()),
      visible_(false),
      drawn_(false) {}

int64 View::SetLocalPropertyInternal(const void* key,
                                     const char* name,
                                     PropertyDeallocator deallocator,
                                     int64 value,
                                     int64 default_value) {
  int64 old = GetLocalPropertyInternal(key, default_value);
  if (value == default_value) {
    prop_map_.erase(key);
  } else {
    Value prop_value;
    prop_value.name = name;
    prop_value.value = value;
    prop_value.deallocator = deallocator;
    prop_map_[key] = prop_value;
  }
  FOR_EACH_OBSERVER(ViewObserver, observers_,
                    OnViewLocalPropertyChanged(this, key, old));
  return old;
}

int64 View::GetLocalPropertyInternal(const void* key,
                                     int64 default_value) const {
  std::map<const void*, Value>::const_iterator iter = prop_map_.find(key);
  if (iter == prop_map_.end())
    return default_value;
  return iter->second.value;
}

void View::LocalDestroy() {
  delete this;
}

void View::LocalAddChild(View* child) {
  ScopedTreeNotifier notifier(child, child->parent(), this);
  if (child->parent())
    RemoveChildImpl(child, &child->parent_->children_);
  children_.push_back(child);
  child->parent_ = this;
}

void View::LocalRemoveChild(View* child) {
  DCHECK_EQ(this, child->parent());
  ScopedTreeNotifier notifier(child, this, NULL);
  RemoveChildImpl(child, &children_);
}

bool View::LocalReorder(View* relative, OrderDirection direction) {
  return ReorderImpl(&parent_->children_, this, relative, direction);
}

void View::LocalSetBounds(const Rect& old_bounds, const Rect& new_bounds) {
  DCHECK(old_bounds.x == bounds_.x);
  DCHECK(old_bounds.y == bounds_.y);
  DCHECK(old_bounds.width == bounds_.width);
  DCHECK(old_bounds.height == bounds_.height);
  ScopedSetBoundsNotifier notifier(this, old_bounds, new_bounds);
  bounds_ = new_bounds;
}

void View::LocalSetViewportMetrics(const ViewportMetrics& old_metrics,
                                   const ViewportMetrics& new_metrics) {
  // TODO(eseidel): We could check old_metrics against viewport_metrics_.
  viewport_metrics_ = new_metrics.Clone();
  FOR_EACH_OBSERVER(
      ViewObserver, observers_,
      OnViewViewportMetricsChanged(this, old_metrics, new_metrics));
}

void View::LocalSetDrawn(bool value) {
  if (drawn_ == value)
    return;

  // As IsDrawn() is derived from |visible_| and |drawn_|, only send drawn
  // notification is the value of IsDrawn() is really changing.
  if (IsDrawn() == value) {
    drawn_ = value;
    return;
  }
  FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDrawnChanging(this));
  drawn_ = value;
  FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDrawnChanged(this));
}

void View::LocalSetVisible(bool visible) {
  if (visible_ == visible)
    return;

  FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChanging(this));
  visible_ = visible;
  NotifyViewVisibilityChanged(this);
}

void View::NotifyViewVisibilityChanged(View* target) {
  if (!NotifyViewVisibilityChangedDown(target)) {
    return;  // |this| has been deleted.
  }
  NotifyViewVisibilityChangedUp(target);
}

bool View::NotifyViewVisibilityChangedAtReceiver(View* target) {
  // |this| may be deleted during a call to OnViewVisibilityChanged() on one
  // of the observers. We create an local observer for that. In that case we
  // exit without further access to any members.
  ViewTracker tracker;
  tracker.Add(this);
  FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChanged(target));
  return tracker.Contains(this);
}

bool View::NotifyViewVisibilityChangedDown(View* target) {
  if (!NotifyViewVisibilityChangedAtReceiver(target))
    return false;  // |this| was deleted.
  std::set<const View*> child_already_processed;
  bool child_destroyed = false;
  do {
    child_destroyed = false;
    for (View::Children::const_iterator it = children_.begin();
         it != children_.end(); ++it) {
      if (!child_already_processed.insert(*it).second)
        continue;
      if (!(*it)->NotifyViewVisibilityChangedDown(target)) {
        // |*it| was deleted, |it| is invalid and |children_| has changed.  We
        // exit the current for-loop and enter a new one.
        child_destroyed = true;
        break;
      }
    }
  } while (child_destroyed);
  return true;
}

void View::NotifyViewVisibilityChangedUp(View* target) {
  // Start with the parent as we already notified |this|
  // in NotifyViewVisibilityChangedDown.
  for (View* view = parent(); view; view = view->parent()) {
    bool ret = view->NotifyViewVisibilityChangedAtReceiver(target);
    DCHECK(ret);
  }
}

bool View::PrepareForEmbed() {
  if (!OwnsView(manager_, this))
    return false;

  while (!children_.empty())
    RemoveChild(children_[0]);
  return true;
}

}  // namespace mojo
