// Copyright 2011 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 "cc/trees/tree_synchronizer.h"

#include <set>

#include "base/containers/hash_tables.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "cc/animation/scrollbar_animation_controller.h"
#include "cc/input/scrollbar.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/scrollbar_layer_impl_base.h"
#include "cc/layers/scrollbar_layer_interface.h"

namespace cc {

typedef base::ScopedPtrHashMap<int, LayerImpl> ScopedPtrLayerImplMap;
typedef base::hash_map<int, LayerImpl*> RawPtrLayerImplMap;

void CollectExistingLayerImplRecursive(ScopedPtrLayerImplMap* old_layers,
                                       scoped_ptr<LayerImpl> layer_impl) {
  if (!layer_impl)
    return;

  layer_impl->ClearScrollbars();
  if (ScrollbarLayerImplBase* scrollbar_layer =
          layer_impl->ToScrollbarLayer()) {
    scrollbar_layer->ClearClipLayer();
    scrollbar_layer->ClearScrollLayer();
  }

  OwnedLayerImplList& children = layer_impl->children();
  for (OwnedLayerImplList::iterator it = children.begin();
       it != children.end();
       ++it)
    CollectExistingLayerImplRecursive(old_layers, children.take(it));

  CollectExistingLayerImplRecursive(old_layers, layer_impl->TakeMaskLayer());
  CollectExistingLayerImplRecursive(old_layers, layer_impl->TakeReplicaLayer());

  int id = layer_impl->id();
  old_layers->set(id, layer_impl.Pass());
}

template <typename LayerType>
scoped_ptr<LayerImpl> SynchronizeTreesInternal(
    LayerType* layer_root,
    scoped_ptr<LayerImpl> old_layer_impl_root,
    LayerTreeImpl* tree_impl) {
  DCHECK(tree_impl);

  TRACE_EVENT0("cc", "TreeSynchronizer::SynchronizeTrees");
  ScopedPtrLayerImplMap old_layers;
  RawPtrLayerImplMap new_layers;

  CollectExistingLayerImplRecursive(&old_layers, old_layer_impl_root.Pass());

  scoped_ptr<LayerImpl> new_tree = SynchronizeTreesRecursive(
      &new_layers, &old_layers, layer_root, tree_impl);

  UpdateScrollbarLayerPointersRecursive(&new_layers, layer_root);

  return new_tree.Pass();
}

scoped_ptr<LayerImpl> TreeSynchronizer::SynchronizeTrees(
    Layer* layer_root,
    scoped_ptr<LayerImpl> old_layer_impl_root,
    LayerTreeImpl* tree_impl) {
  return SynchronizeTreesInternal(
      layer_root, old_layer_impl_root.Pass(), tree_impl);
}

scoped_ptr<LayerImpl> TreeSynchronizer::SynchronizeTrees(
    LayerImpl* layer_root,
    scoped_ptr<LayerImpl> old_layer_impl_root,
    LayerTreeImpl* tree_impl) {
  return SynchronizeTreesInternal(
      layer_root, old_layer_impl_root.Pass(), tree_impl);
}

template <typename LayerType>
scoped_ptr<LayerImpl> ReuseOrCreateLayerImpl(RawPtrLayerImplMap* new_layers,
                                             ScopedPtrLayerImplMap* old_layers,
                                             LayerType* layer,
                                             LayerTreeImpl* tree_impl) {
  scoped_ptr<LayerImpl> layer_impl = old_layers->take(layer->id());

  if (!layer_impl)
    layer_impl = layer->CreateLayerImpl(tree_impl);

  (*new_layers)[layer->id()] = layer_impl.get();
  return layer_impl.Pass();
}

template <typename LayerType>
scoped_ptr<LayerImpl> SynchronizeTreesRecursiveInternal(
    RawPtrLayerImplMap* new_layers,
    ScopedPtrLayerImplMap* old_layers,
    LayerType* layer,
    LayerTreeImpl* tree_impl) {
  if (!layer)
    return scoped_ptr<LayerImpl>();

  scoped_ptr<LayerImpl> layer_impl =
      ReuseOrCreateLayerImpl(new_layers, old_layers, layer, tree_impl);

  layer_impl->ClearChildList();
  for (size_t i = 0; i < layer->children().size(); ++i) {
    layer_impl->AddChild(SynchronizeTreesRecursiveInternal(
        new_layers, old_layers, layer->child_at(i), tree_impl));
  }

  layer_impl->SetMaskLayer(SynchronizeTreesRecursiveInternal(
      new_layers, old_layers, layer->mask_layer(), tree_impl));
  layer_impl->SetReplicaLayer(SynchronizeTreesRecursiveInternal(
      new_layers, old_layers, layer->replica_layer(), tree_impl));

  return layer_impl.Pass();
}

scoped_ptr<LayerImpl> SynchronizeTreesRecursive(
    RawPtrLayerImplMap* new_layers,
    ScopedPtrLayerImplMap* old_layers,
    Layer* layer,
    LayerTreeImpl* tree_impl) {
  return SynchronizeTreesRecursiveInternal(
      new_layers, old_layers, layer, tree_impl);
}

scoped_ptr<LayerImpl> SynchronizeTreesRecursive(
    RawPtrLayerImplMap* new_layers,
    ScopedPtrLayerImplMap* old_layers,
    LayerImpl* layer,
    LayerTreeImpl* tree_impl) {
  return SynchronizeTreesRecursiveInternal(
      new_layers, old_layers, layer, tree_impl);
}

template <typename LayerType, typename ScrollbarLayerType>
void UpdateScrollbarLayerPointersRecursiveInternal(
    const RawPtrLayerImplMap* new_layers,
    LayerType* layer) {
  if (!layer)
    return;

  for (size_t i = 0; i < layer->children().size(); ++i) {
    UpdateScrollbarLayerPointersRecursiveInternal<
        LayerType, ScrollbarLayerType>(new_layers, layer->child_at(i));
  }

  ScrollbarLayerType* scrollbar_layer = layer->ToScrollbarLayer();
  if (!scrollbar_layer)
    return;

  RawPtrLayerImplMap::const_iterator iter =
      new_layers->find(layer->id());
  ScrollbarLayerImplBase* scrollbar_layer_impl =
      iter != new_layers->end()
          ? static_cast<ScrollbarLayerImplBase*>(iter->second)
          : NULL;
  DCHECK(scrollbar_layer_impl);

  scrollbar_layer->PushScrollClipPropertiesTo(scrollbar_layer_impl);
}

void UpdateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap* new_layers,
                                           Layer* layer) {
  UpdateScrollbarLayerPointersRecursiveInternal<Layer, ScrollbarLayerInterface>(
      new_layers, layer);
}

void UpdateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap* new_layers,
                                           LayerImpl* layer) {
  UpdateScrollbarLayerPointersRecursiveInternal<
      LayerImpl,
      ScrollbarLayerImplBase>(new_layers, layer);
}

// static
template <typename LayerType>
void TreeSynchronizer::PushPropertiesInternal(
    LayerType* layer,
    LayerImpl* layer_impl,
    size_t* num_dependents_need_push_properties_for_parent) {
  if (!layer) {
    DCHECK(!layer_impl);
    return;
  }

  DCHECK_EQ(layer->id(), layer_impl->id());

  bool push_layer = layer->needs_push_properties();
  bool recurse_on_children_and_dependents =
      layer->descendant_needs_push_properties();

  if (push_layer)
    layer->PushPropertiesTo(layer_impl);
  else if (layer->ToScrollbarLayer())
    layer->ToScrollbarLayer()->PushScrollClipPropertiesTo(layer_impl);

  size_t num_dependents_need_push_properties = 0;
  if (recurse_on_children_and_dependents) {
    PushPropertiesInternal(layer->mask_layer(),
                           layer_impl->mask_layer(),
                           &num_dependents_need_push_properties);
    PushPropertiesInternal(layer->replica_layer(),
                           layer_impl->replica_layer(),
                           &num_dependents_need_push_properties);

    const OwnedLayerImplList& impl_children = layer_impl->children();
    DCHECK_EQ(layer->children().size(), impl_children.size());

    for (size_t i = 0; i < layer->children().size(); ++i) {
      PushPropertiesInternal(layer->child_at(i),
                             impl_children[i],
                             &num_dependents_need_push_properties);
    }

    // When PushPropertiesTo completes for a layer, it may still keep
    // its needs_push_properties() state if the layer must push itself
    // every PushProperties tree walk. Here we keep track of those layers, and
    // ensure that their ancestors know about them for the next PushProperties
    // tree walk.
    layer->num_dependents_need_push_properties_ =
        num_dependents_need_push_properties;
  }

  bool add_self_to_parent = num_dependents_need_push_properties > 0 ||
                            layer->needs_push_properties();
  *num_dependents_need_push_properties_for_parent += add_self_to_parent ? 1 : 0;
}

static void CheckScrollAndClipPointersRecursive(Layer* layer,
                                                LayerImpl* layer_impl) {
  DCHECK_EQ(!!layer, !!layer_impl);
  if (!layer)
    return;

  DCHECK_EQ(!!layer->scroll_parent(), !!layer_impl->scroll_parent());
  if (layer->scroll_parent())
    DCHECK_EQ(layer->scroll_parent()->id(), layer_impl->scroll_parent()->id());

  DCHECK_EQ(!!layer->clip_parent(), !!layer_impl->clip_parent());
  if (layer->clip_parent())
    DCHECK_EQ(layer->clip_parent()->id(), layer_impl->clip_parent()->id());

  DCHECK_EQ(!!layer->scroll_children(), !!layer_impl->scroll_children());
  if (layer->scroll_children()) {
    for (std::set<Layer*>::iterator it = layer->scroll_children()->begin();
         it != layer->scroll_children()->end();
         ++it) {
      DCHECK_EQ((*it)->scroll_parent(), layer);
    }
    for (std::set<LayerImpl*>::iterator it =
             layer_impl->scroll_children()->begin();
         it != layer_impl->scroll_children()->end();
         ++it) {
      DCHECK_EQ((*it)->scroll_parent(), layer_impl);
    }
  }

  DCHECK_EQ(!!layer->clip_children(), !!layer_impl->clip_children());
  if (layer->clip_children()) {
    for (std::set<Layer*>::iterator it = layer->clip_children()->begin();
         it != layer->clip_children()->end();
         ++it) {
      DCHECK_EQ((*it)->clip_parent(), layer);
    }
    for (std::set<LayerImpl*>::iterator it =
             layer_impl->clip_children()->begin();
         it != layer_impl->clip_children()->end();
         ++it) {
      DCHECK_EQ((*it)->clip_parent(), layer_impl);
    }
  }

  for (size_t i = 0u; i < layer->children().size(); ++i) {
    CheckScrollAndClipPointersRecursive(layer->child_at(i),
                                        layer_impl->child_at(i));
  }
}

void TreeSynchronizer::PushProperties(Layer* layer,
                                      LayerImpl* layer_impl) {
  size_t num_dependents_need_push_properties = 0;
  PushPropertiesInternal(
      layer, layer_impl, &num_dependents_need_push_properties);
#if DCHECK_IS_ON
  CheckScrollAndClipPointersRecursive(layer, layer_impl);
#endif
}

void TreeSynchronizer::PushProperties(LayerImpl* layer, LayerImpl* layer_impl) {
  size_t num_dependents_need_push_properties = 0;
  PushPropertiesInternal(
      layer, layer_impl, &num_dependents_need_push_properties);
}

}  // namespace cc
