// 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*)>;

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

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<T> typed_filter_function = base::Bind([](T*) {
      return true;
    }),
    base::optional<NodeReplaceFunction> replace_function = base::nullopt) {
  // Wrap the typed filter with an untyped callback.
  auto type_checking_filter_function =
      base::Bind([typed_filter_function](render_tree::Node* node) {
        if (node->GetTypeId() != base::GetTypeId<T>()) {
          return false;
        }

        auto* typed_node = base::polymorphic_downcast<T*>(node);
        return typed_filter_function.Run(typed_node);
      });
  // Call the default untyped FindNode with the above wrap.
  NodeSearchResult<> untyped_result = FindNode<render_tree::Node>(
      tree, type_checking_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<render_tree::Node> filter_function,
    base::optional<NodeReplaceFunction> replace_function);

// Checks whether the given filter node has a MapToMesh filter in it.
bool HasMapToMesh(render_tree::FilterNode* 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_
