// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_RENDERER_RASTERIZER_COMMON_FIND_NODE_H_
#define COBALT_RENDERER_RASTERIZER_COMMON_FIND_NODE_H_

#include "base/bind.h"
#include "cobalt/base/enable_if.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/base/type_id.h"
#include "cobalt/render_tree/child_iterator.h"
#include "cobalt/render_tree/node.h"
#include "cobalt/render_tree/node_visitor.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace common {

using NodeReplaceFunction =
    base::Callback<render_tree::Node*(render_tree::Node*)>;

using NodeFilterFunction = base::Callback<bool(render_tree::Node*)>;

template <typename T = render_tree::Node>
struct NodeSearchResult {
  scoped_refptr<T> found_node;  // Null if no such node is found.
  scoped_refptr<render_tree::Node> replaced_tree;
};

// Finds the first node of type |T| that passes an optional |filter_function|,
// and optionally replaces it in the tree with the result of |replace_function|.
//
// Example usage:
//     auto filter = base::Bind(&CheckSomethingOnNode)
//     auto replace = base::Bind(&ReplaceNode)
//     auto search_results = FindNode<SomeNode>(tree, filter, replace);
//     DoSomethingWithNode(search_results.found_node);
//     DoSomethingWithTree(search_results.replaced_tree);
template <typename T>
NodeSearchResult<T> FindNode(
    const scoped_refptr<render_tree::Node>& tree,
    NodeFilterFunction filter_function = base::Bind([](render_tree::Node*) {
      return true;
    }),
    base::Optional<NodeReplaceFunction> replace_function = base::nullopt) {
  // Call the default untyped FindNode with the above wrap.
  NodeSearchResult<> untyped_result =
      FindNode<render_tree::Node>(tree, filter_function, replace_function);
  NodeSearchResult<T> typed_result;
  typed_result.replaced_tree = untyped_result.replaced_tree;
  typed_result.found_node =
      base::polymorphic_downcast<T*>(untyped_result.found_node.get());

  return typed_result;
}

// Same as the above, but not filtering nodes by type, so the filter can act on
// nodes of different classes.
template <>
NodeSearchResult<render_tree::Node> FindNode<render_tree::Node>(
    const scoped_refptr<render_tree::Node>& tree,
    NodeFilterFunction filter_function,
    base::Optional<NodeReplaceFunction> replace_function);

// Checks whether the given filter node has a MapToMesh filter in it.
bool HasMapToMesh(render_tree::Node* node);

render_tree::Node* ReplaceWithEmptyCompositionNode(render_tree::Node* node);

}  // namespace common
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt

#endif  // COBALT_RENDERER_RASTERIZER_COMMON_FIND_NODE_H_
