// Copyright 2016 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/layers/layer_list_iterator.h"

#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"

namespace cc {

static Layer* Parent(Layer* layer) {
  return layer->parent();
}

static LayerImpl* Parent(LayerImpl* layer) {
  return layer->test_properties()->parent;
}
template <typename LayerType>
LayerListIterator<LayerType>::LayerListIterator(LayerType* root_layer)
    : current_layer_(root_layer) {
  DCHECK(!root_layer || !Parent(root_layer));
  list_indices_.push_back(0);
}

static LayerImplList& Children(LayerImpl* layer) {
  return layer->test_properties()->children;
}

static const LayerList& Children(Layer* layer) {
  return layer->children();
}

static LayerImpl* ChildAt(LayerImpl* layer, int index) {
  return layer->test_properties()->children[index];
}

static Layer* ChildAt(Layer* layer, int index) {
  return layer->children()[index].get();
}

template <typename LayerType>
LayerListIterator<LayerType>::LayerListIterator(
    const LayerListIterator<LayerType>& other) = default;

template <typename LayerType>
LayerListIterator<LayerType>::~LayerListIterator() = default;

template <typename LayerType>
LayerListIterator<LayerType>& LayerListIterator<LayerType>::operator++() {
  // case 0: done
  if (!current_layer_)
    return *this;

  // case 1: descend.
  if (!Children(current_layer_).empty()) {
    current_layer_ = ChildAt(current_layer_, 0);
    list_indices_.push_back(0);
    return *this;
  }

  for (LayerType* parent = Parent(current_layer_); parent;
       parent = Parent(parent)) {
    // We now try and advance in some list of siblings.
    // case 2: Advance to a sibling.
    if (list_indices_.back() + 1 < Children(parent).size()) {
      ++list_indices_.back();
      current_layer_ = ChildAt(parent, list_indices_.back());
      return *this;
    }

    // We need to ascend. We will pop an index off the stack.
    list_indices_.pop_back();
  }

  current_layer_ = nullptr;
  return *this;
}

template <typename LayerType>
LayerListReverseIterator<LayerType>::LayerListReverseIterator(
    LayerType* root_layer)
    : LayerListIterator<LayerType>(root_layer) {
  DescendToRightmostInSubtree();
}

template <typename LayerType>
LayerListReverseIterator<LayerType>::~LayerListReverseIterator() = default;

// We will only support prefix increment.
template <typename LayerType>
LayerListIterator<LayerType>& LayerListReverseIterator<LayerType>::
operator++() {
  // case 0: done
  if (!current_layer())
    return *this;

  // case 1: we're the leftmost sibling.
  if (!list_indices().back()) {
    list_indices().pop_back();
    this->current_layer_ = Parent(current_layer());
    return *this;
  }

  // case 2: we're not the leftmost sibling. In this case, we want to move one
  // sibling over, and then descend to the rightmost descendant in that subtree.
  CHECK(Parent(current_layer()));
  --list_indices().back();
  this->current_layer_ =
      ChildAt(Parent(current_layer()), list_indices().back());
  DescendToRightmostInSubtree();
  return *this;
}

template <typename LayerType>
void LayerListReverseIterator<LayerType>::DescendToRightmostInSubtree() {
  if (!current_layer())
    return;

  if (Children(current_layer()).empty())
    return;

  size_t last_index = Children(current_layer()).size() - 1;
  this->current_layer_ = ChildAt(current_layer(), last_index);
  list_indices().push_back(last_index);
  DescendToRightmostInSubtree();
}

template class LayerListIterator<Layer>;
template class LayerListIterator<LayerImpl>;
template class LayerListReverseIterator<Layer>;
template class LayerListReverseIterator<LayerImpl>;

}  // namespace cc
