// Copyright 2016 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_RENDER_TREE_MOCK_RESOURCE_PROVIDER_H_
#define COBALT_RENDER_TREE_MOCK_RESOURCE_PROVIDER_H_

#include <memory>
#include <string>
#include <vector>

#include "base/memory/ref_counted.h"
#include "cobalt/render_tree/font.h"
#include "cobalt/render_tree/font_provider.h"
#include "cobalt/render_tree/glyph_buffer.h"
#include "cobalt/render_tree/image.h"
#include "cobalt/render_tree/node.h"
#include "cobalt/render_tree/resource_provider.h"
#include "cobalt/render_tree/typeface.h"

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace render_tree {

class MockResourceProvider : public ResourceProvider {
 public:
  // Comment out override in order to enable
  // "-Winconsistent-missing-override" on Clang.  TODO: Remove this hack once
  // gmock adds override support.
  virtual base::TypeId GetTypeId() const /*override*/ {
    return base::GetTypeId<MockResourceProvider>();
  }

  MOCK_METHOD0(Finish, void());
  MOCK_METHOD1(PixelFormatSupported, bool(PixelFormat pixel_format));
  MOCK_METHOD1(AlphaFormatSupported, bool(AlphaFormat alpha_format));
  MOCK_METHOD3(AllocateImageDataMock,
               ImageData*(const math::Size& size, PixelFormat pixel_format,
                          AlphaFormat alpha_format));
  MOCK_METHOD1(CreateImageMock, Image*(ImageData* pixel_data));
  MOCK_METHOD2(AllocateRawImageMemoryMock,
               RawImageMemory*(size_t size_in_bytes, size_t alignment));
  MOCK_METHOD2(CreateMultiPlaneImageFromRawMemoryMock,
               Image*(RawImageMemory* raw_image_memory,
                      const MultiPlaneImageDataDescriptor& descriptor));
  MOCK_CONST_METHOD1(HasLocalFontFamily, bool(const char* font_family_name));
  MOCK_METHOD2(GetLocalTypefaceMock,
               Typeface*(const char* font_family_name, FontStyle font_style));
  MOCK_METHOD1(GetLocalTypefaceIfAvailableMock,
               Typeface*(const std::string& font_face_name));
  MOCK_METHOD3(GetCharacterFallbackTypefaceMock,
               Typeface*(int32 utf32_character, FontStyle font_style,
                         const std::string& language));
  MOCK_METHOD2(CreateTypefaceFromRawDataMock,
               Typeface*(RawTypefaceDataVector* raw_data,
                         std::string* error_string));
  MOCK_METHOD5(CreateGlyphBufferMock,
               render_tree::GlyphBuffer*(
                   const base::char16* text_buffer, size_t text_length,
                   const std::string& language, bool is_rtl,
                   render_tree::FontProvider* font_provider));
  MOCK_METHOD2(
      CreateGlyphBufferMock,
      render_tree::GlyphBuffer*(const std::string& utf8_string,
                                const scoped_refptr<render_tree::Font>& font));
  MOCK_METHOD6(GetTextWidth,
               float(const base::char16* text_buffer, size_t text_length,
                     const std::string& language, bool is_rtl,
                     render_tree::FontProvider* font_provider,
                     render_tree::FontVector* maybe_used_fonts));

  MOCK_METHOD2(CreateMeshMock,
               render_tree::Mesh*(std::vector<render_tree::Mesh::Vertex>*,
                                  render_tree::Mesh::DrawMode));

  MOCK_METHOD1(DrawOffscreenImage,
               scoped_refptr<render_tree::Image>(
                   const scoped_refptr<render_tree::Node>& root));

  std::unique_ptr<ImageData> AllocateImageData(const math::Size& size,
                                               PixelFormat pixel_format,
                                               AlphaFormat alpha_format) {
    return std::unique_ptr<ImageData>(
        AllocateImageDataMock(size, pixel_format, alpha_format));
  }
  scoped_refptr<Image> CreateImage(std::unique_ptr<ImageData> pixel_data) {
    return scoped_refptr<Image>(CreateImageMock(pixel_data.get()));
  }

#if SB_HAS(GRAPHICS)

  scoped_refptr<Image> CreateImageFromSbDecodeTarget(SbDecodeTarget target) {
    SB_UNREFERENCED_PARAMETER(target);
    return NULL;
  }

  bool SupportsSbDecodeTarget() { return false; }

  SbDecodeTargetGraphicsContextProvider*
  GetSbDecodeTargetGraphicsContextProvider() {
    return NULL;
  }

#endif  // SB_HAS(GRAPHICS)

  std::unique_ptr<RawImageMemory> AllocateRawImageMemory(size_t size_in_bytes,
                                                         size_t alignment) {
    return std::unique_ptr<RawImageMemory>(
        AllocateRawImageMemoryMock(size_in_bytes, alignment));
  }
  scoped_refptr<Image> CreateMultiPlaneImageFromRawMemory(
      std::unique_ptr<RawImageMemory> raw_image_memory,
      const MultiPlaneImageDataDescriptor& descriptor) {
    return scoped_refptr<Image>(CreateMultiPlaneImageFromRawMemoryMock(
        raw_image_memory.get(), descriptor));
  }
  scoped_refptr<Typeface> GetLocalTypeface(const char* font_family_name,
                                           FontStyle font_style) {
    return scoped_refptr<Typeface>(
        GetLocalTypefaceMock(font_family_name, font_style));
  }
  scoped_refptr<Typeface> GetLocalTypefaceByFaceNameIfAvailable(
      const char* font_face_name) {
    return scoped_refptr<Typeface>(
        GetLocalTypefaceIfAvailableMock(font_face_name));
  }
  scoped_refptr<Typeface> GetCharacterFallbackTypeface(
      int32 utf32_character, FontStyle font_style,
      const std::string& language) {
    return scoped_refptr<Typeface>(GetCharacterFallbackTypefaceMock(
        utf32_character, font_style, language));
  }
  scoped_refptr<Typeface> CreateTypefaceFromRawData(
      std::unique_ptr<RawTypefaceDataVector> raw_data,
      std::string* error_string) {
    return scoped_refptr<Typeface>(
        CreateTypefaceFromRawDataMock(raw_data.get(), error_string));
  }
  scoped_refptr<render_tree::GlyphBuffer> CreateGlyphBuffer(
      const base::char16* text_buffer, size_t text_length,
      const std::string& language, bool is_rtl,
      render_tree::FontProvider* font_provider) {
    return scoped_refptr<render_tree::GlyphBuffer>(CreateGlyphBufferMock(
        text_buffer, text_length, language, is_rtl, font_provider));
  }
  scoped_refptr<render_tree::GlyphBuffer> CreateGlyphBuffer(
      const std::string& utf8_string,
      const scoped_refptr<render_tree::Font>& font) {
    return scoped_refptr<render_tree::GlyphBuffer>(
        CreateGlyphBufferMock(utf8_string, font.get()));
  }
  virtual scoped_refptr<Mesh> CreateMesh(
      std::unique_ptr<std::vector<Mesh::Vertex> > vertices,
      Mesh::DrawMode draw_mode) {
    return base::WrapRefCounted(CreateMeshMock(vertices.get(), draw_mode));
  }
};

}  // namespace render_tree
}  // namespace cobalt

#endif  // COBALT_RENDER_TREE_MOCK_RESOURCE_PROVIDER_H_
