// 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 "mojo/services/view_manager/server_view.h"

#include "mojo/services/view_manager/server_view_delegate.h"

namespace mojo {
namespace service {

ServerView::ServerView(ServerViewDelegate* delegate, const ViewId& id)
    : delegate_(delegate), id_(id), parent_(NULL), visible_(true) {
  DCHECK(delegate);  // Must provide a delegate.
}

ServerView::~ServerView() {
  while (!children_.empty())
    children_.front()->parent()->Remove(children_.front());

  if (parent_)
    parent_->Remove(this);

  delegate_->OnViewDestroyed(this);
}

void ServerView::Add(ServerView* child) {
  // We assume validation checks happened already.
  DCHECK(child);
  DCHECK(child != this);
  DCHECK(!child->Contains(this));
  if (child->parent() == this) {
    if (children_.size() == 1)
      return;  // Already in the right position.
    Reorder(child, children_.back(), ORDER_DIRECTION_ABOVE);
    return;
  }

  const ServerView* old_parent = child->parent();
  child->delegate_->OnWillChangeViewHierarchy(child, this, old_parent);
  if (child->parent())
    child->parent()->RemoveImpl(child);

  child->parent_ = this;
  children_.push_back(child);
  child->delegate_->OnViewHierarchyChanged(child, this, old_parent);
}

void ServerView::Remove(ServerView* child) {
  // We assume validation checks happened else where.
  DCHECK(child);
  DCHECK(child != this);
  DCHECK(child->parent() == this);

  child->delegate_->OnWillChangeViewHierarchy(child, NULL, this);
  RemoveImpl(child);
  child->delegate_->OnViewHierarchyChanged(child, NULL, this);
}

void ServerView::Reorder(ServerView* child,
                         ServerView* relative,
                         OrderDirection direction) {
  // We assume validation checks happened else where.
  DCHECK(child);
  DCHECK(child->parent() == this);
  DCHECK_GT(children_.size(), 1u);
  children_.erase(std::find(children_.begin(), children_.end(), child));
  Views::iterator i = std::find(children_.begin(), children_.end(), relative);
  if (direction == ORDER_DIRECTION_ABOVE) {
    DCHECK(i != children_.end());
    children_.insert(++i, child);
  } else if (direction == ORDER_DIRECTION_BELOW) {
    DCHECK(i != children_.end());
    children_.insert(i, child);
  }
  delegate_->OnViewReordered(this, relative, direction);
}

void ServerView::SetBounds(const gfx::Rect& bounds) {
  if (bounds_ == bounds)
    return;

  const gfx::Rect old_bounds = bounds_;
  bounds_ = bounds;
  delegate_->OnViewBoundsChanged(this, old_bounds, bounds);
}

const ServerView* ServerView::GetRoot() const {
  const ServerView* view = this;
  while (view && view->parent())
    view = view->parent();
  return view;
}

std::vector<const ServerView*> ServerView::GetChildren() const {
  std::vector<const ServerView*> children;
  children.reserve(children_.size());
  for (size_t i = 0; i < children_.size(); ++i)
    children.push_back(children_[i]);
  return children;
}

std::vector<ServerView*> ServerView::GetChildren() {
  // TODO(sky): rename to children() and fix return type.
  return children_;
}

bool ServerView::Contains(const ServerView* view) const {
  for (const ServerView* parent = view; parent; parent = parent->parent_) {
    if (parent == this)
      return true;
  }
  return false;
}

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

  delegate_->OnWillChangeViewVisibility(this);
  visible_ = value;
}

void ServerView::SetProperty(const std::string& name,
                             const std::vector<uint8_t>* value) {
  auto it = properties_.find(name);
  if (it != properties_.end()) {
    if (value && it->second == *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);
  }

  delegate_->OnViewSharedPropertyChanged(this, name, value);
}

bool ServerView::IsDrawn(const ServerView* root) const {
  if (!root->visible_)
    return false;
  const ServerView* view = this;
  while (view && view != root && view->visible_)
    view = view->parent_;
  return view == root;
}

void ServerView::SetSurfaceId(cc::SurfaceId surface_id) {
  surface_id_ = surface_id;
  delegate_->OnViewSurfaceIdChanged(this);
}

void ServerView::RemoveImpl(ServerView* view) {
  view->parent_ = NULL;
  children_.erase(std::find(children_.begin(), children_.end(), view));
}

}  // namespace service
}  // namespace mojo
