// Copyright 2014 Google Inc. 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.

#include "cobalt/render_tree/node_visitor.h"

#include <string>

#include "base/bind.h"
#include "cobalt/math/rect_f.h"
#include "cobalt/math/size.h"
#include "cobalt/render_tree/animations/animate_node.h"
#include "cobalt/render_tree/composition_node.h"
#include "cobalt/render_tree/filter_node.h"
#include "cobalt/render_tree/font.h"
#include "cobalt/render_tree/glyph_buffer.h"
#include "cobalt/render_tree/image_node.h"
#include "cobalt/render_tree/matrix_transform_node.h"
#include "cobalt/render_tree/punch_through_video_node.h"
#include "cobalt/render_tree/rect_node.h"
#include "cobalt/render_tree/rect_shadow_node.h"
#include "cobalt/render_tree/text_node.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using cobalt::render_tree::animations::AnimateNode;
using cobalt::render_tree::Brush;
using cobalt::render_tree::BrushVisitor;
using cobalt::render_tree::ColorRGBA;
using cobalt::render_tree::CompositionNode;
using cobalt::render_tree::FilterNode;
using cobalt::render_tree::Font;
using cobalt::render_tree::FontMetrics;
using cobalt::render_tree::GlyphBuffer;
using cobalt::render_tree::Image;
using cobalt::render_tree::ImageNode;
using cobalt::render_tree::MatrixTransformNode;
using cobalt::render_tree::NodeVisitor;
using cobalt::render_tree::OpacityFilter;
using cobalt::render_tree::PunchThroughVideoNode;
using cobalt::render_tree::RectNode;
using cobalt::render_tree::RectShadowNode;
using cobalt::render_tree::TextNode;

class MockNodeVisitor : public NodeVisitor {
 public:
  MOCK_METHOD1(Visit, void(AnimateNode* animate));
  MOCK_METHOD1(Visit, void(CompositionNode* composition));
  MOCK_METHOD1(Visit, void(FilterNode* image));
  MOCK_METHOD1(Visit, void(ImageNode* image));
  MOCK_METHOD1(Visit, void(MatrixTransformNode* matrix_transform_node));
  MOCK_METHOD1(Visit, void(PunchThroughVideoNode* punch_through_video_node));
  MOCK_METHOD1(Visit, void(RectNode* rect));
  MOCK_METHOD1(Visit, void(RectShadowNode* rect_shadow));
  MOCK_METHOD1(Visit, void(TextNode* text));
};

TEST(NodeVisitorTest, VisitsComposition) {
  CompositionNode::Builder builder;
  scoped_refptr<CompositionNode> composition(new CompositionNode(builder));
  MockNodeVisitor mock_visitor;
  EXPECT_CALL(mock_visitor, Visit(composition.get()));
  composition->Accept(&mock_visitor);
}

TEST(NodeVisitorTest, VisitsFilter) {
  scoped_refptr<FilterNode> filter(new FilterNode(OpacityFilter(0.5f), NULL));
  MockNodeVisitor mock_visitor;
  EXPECT_CALL(mock_visitor, Visit(filter.get()));
  filter->Accept(&mock_visitor);
}

namespace {

class DummyImage : public Image {
  const cobalt::math::Size& GetSize() const OVERRIDE { return size_; }

 private:
  cobalt::math::Size size_;
};

class DummyBrush : public Brush {
  void Accept(BrushVisitor* visitor) const OVERRIDE {
    UNREFERENCED_PARAMETER(visitor);
  }

  base::TypeId GetTypeId() const OVERRIDE {
    return base::GetTypeId<DummyBrush>();
  }
};

bool SetBounds(const cobalt::math::Rect&) { return false; }

}  // namespace

TEST(NodeVisitorTest, VisitsAnimate) {
  scoped_refptr<DummyImage> dummy_image = make_scoped_refptr(new DummyImage());
  scoped_refptr<ImageNode> dummy_image_node(new ImageNode(dummy_image));
  scoped_refptr<AnimateNode> animate_node(new AnimateNode(dummy_image_node));
  MockNodeVisitor mock_visitor;
  EXPECT_CALL(mock_visitor, Visit(animate_node.get()));
  animate_node->Accept(&mock_visitor);
}

TEST(NodeVisitorTest, VisitsImage) {
  scoped_refptr<DummyImage> image = make_scoped_refptr(new DummyImage());
  scoped_refptr<ImageNode> image_node(new ImageNode(image));
  MockNodeVisitor mock_visitor;
  EXPECT_CALL(mock_visitor, Visit(image_node.get()));
  image_node->Accept(&mock_visitor);
}

TEST(NodeVisitorTest, VisitsMatrixTransform) {
  scoped_refptr<MatrixTransformNode> matrix_transform_node(
      new MatrixTransformNode(NULL, cobalt::math::Matrix3F::Identity()));
  MockNodeVisitor mock_visitor;
  EXPECT_CALL(mock_visitor, Visit(matrix_transform_node.get()));
  matrix_transform_node->Accept(&mock_visitor);
}

TEST(NodeVisitorTest, VisitsPunchThroughVideo) {
  PunchThroughVideoNode::Builder builder(cobalt::math::RectF(),
                                         base::Bind(SetBounds));
  scoped_refptr<PunchThroughVideoNode> punch_through_video_node(
      new PunchThroughVideoNode(builder));
  MockNodeVisitor mock_visitor;
  EXPECT_CALL(mock_visitor, Visit(punch_through_video_node.get()));
  punch_through_video_node->Accept(&mock_visitor);
}

TEST(NodeVisitorTest, VisitsRect) {
  scoped_refptr<RectNode> rect(
      new RectNode(cobalt::math::RectF(), scoped_ptr<Brush>(new DummyBrush())));
  MockNodeVisitor mock_visitor;
  EXPECT_CALL(mock_visitor, Visit(rect.get()));
  rect->Accept(&mock_visitor);
}

TEST(NodeVisitorTest, VisitsRectShadow) {
  scoped_refptr<RectShadowNode> rect_shadow(new RectShadowNode(
      cobalt::math::RectF(),
      cobalt::render_tree::Shadow(cobalt::math::Vector2dF(1.0f, 1.0f), 1.0f,
                                  ColorRGBA(0, 0, 0, 1.0f))));
  MockNodeVisitor mock_visitor;
  EXPECT_CALL(mock_visitor, Visit(rect_shadow.get()));
  rect_shadow->Accept(&mock_visitor);
}

TEST(NodeVisitorTest, VisitsText) {
  scoped_refptr<TextNode> text(
      new TextNode(cobalt::math::Vector2dF(0, 0),
                   new GlyphBuffer(cobalt::math::RectF(0, 0, 1, 1)),
                   ColorRGBA(0.0f, 0.0f, 0.0f)));
  MockNodeVisitor mock_visitor;
  EXPECT_CALL(mock_visitor, Visit(text.get()));
  text->Accept(&mock_visitor);
}
