// 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_CSSOM_MAP_TO_MESH_FUNCTION_H_
#define COBALT_CSSOM_MAP_TO_MESH_FUNCTION_H_

#include <string>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "cobalt/base/polymorphic_equatable.h"
#include "cobalt/cssom/filter_function.h"
#include "cobalt/cssom/keyword_value.h"
#include "cobalt/cssom/property_value.h"
#include "cobalt/cssom/url_value.h"
#include "third_party/glm/glm/mat4x4.hpp"

namespace cobalt {
namespace cssom {

// Represent a map-to-mesh filter.
class MapToMeshFunction : public FilterFunction {
 public:
  // A resolution-matched mesh specifier.
  class ResolutionMatchedMesh {
   public:
    ResolutionMatchedMesh(int width_match, int height_match,
                          const scoped_refptr<PropertyValue>& mesh_url);
    int width_match() const { return width_match_; }
    int height_match() const { return height_match_; }
    const scoped_refptr<PropertyValue>& mesh_url() const { return mesh_url_; }
    bool operator==(const MapToMeshFunction::ResolutionMatchedMesh& rhs) const;
    bool operator!=(const MapToMeshFunction::ResolutionMatchedMesh& rhs) const;

   private:
    const int width_match_;
    const int height_match_;
    const scoped_refptr<PropertyValue> mesh_url_;
  };

  // Type of the source of the mesh: either a built-in mesh type or a custom
  // mesh.
  enum MeshSpecType {
    // Built-in rectangular mesh.
    kRectangular,
    // Built-in equirectangular mesh.
    kEquirectangular,
    // List of custom binary mesh URLs.
    kUrls
  };
  typedef ScopedVector<ResolutionMatchedMesh> ResolutionMatchedMeshListBuilder;

  // Contains the specification of the mesh source.
  class MeshSpec {
   public:
    explicit MeshSpec(MeshSpecType mesh_type) : mesh_type_(mesh_type) {
      // Check that this is a built-in mesh type.
      DCHECK(mesh_type == kRectangular || mesh_type == kEquirectangular);
    }

    MeshSpec(MeshSpecType mesh_type,
             const scoped_refptr<PropertyValue>& mesh_url,
             ResolutionMatchedMeshListBuilder resolution_matched_meshes)
        : mesh_type_(mesh_type),
          mesh_url_(mesh_url),
          resolution_matched_meshes_(resolution_matched_meshes.Pass()) {
      DCHECK_EQ(mesh_type_, kUrls);
      DCHECK(mesh_url);
    }

    const scoped_refptr<PropertyValue>& mesh_url() const {
      DCHECK_EQ(mesh_type_, kUrls);
      return mesh_url_;
    }
    const ResolutionMatchedMeshListBuilder& resolution_matched_meshes() const {
      DCHECK_EQ(mesh_type_, kUrls);
      return resolution_matched_meshes_;
    }
    MeshSpecType mesh_type() const { return mesh_type_; }

   private:
    MeshSpecType mesh_type_;
    scoped_refptr<PropertyValue> mesh_url_;
    ResolutionMatchedMeshListBuilder resolution_matched_meshes_;

    DISALLOW_COPY_AND_ASSIGN(MeshSpec);
  };

  MapToMeshFunction(scoped_ptr<MeshSpec> mesh_spec,
                    float horizontal_fov_in_radians,
                    float vertical_fov_in_radians, const glm::mat4& transform,
                    const scoped_refptr<KeywordValue>& stereo_mode)
      : mesh_spec_(mesh_spec.Pass()),
        horizontal_fov_in_radians_(horizontal_fov_in_radians),
        vertical_fov_in_radians_(vertical_fov_in_radians),
        transform_(transform),
        stereo_mode_(stereo_mode) {
    DCHECK(mesh_spec_);
    DCHECK_NE(mesh_spec_->mesh_type(), kRectangular);
    DCHECK(stereo_mode_);
  }

  // Alternate constructor for mesh URL lists.
  MapToMeshFunction(const scoped_refptr<PropertyValue>& mesh_url,
                    ResolutionMatchedMeshListBuilder resolution_matched_meshes,
                    float horizontal_fov_in_radians,
                    float vertical_fov_in_radians, const glm::mat4& transform,
                    const scoped_refptr<KeywordValue>& stereo_mode)
      : mesh_spec_(
            new MeshSpec(kUrls, mesh_url, resolution_matched_meshes.Pass())),
        horizontal_fov_in_radians_(horizontal_fov_in_radians),
        vertical_fov_in_radians_(vertical_fov_in_radians),
        transform_(transform),
        stereo_mode_(stereo_mode) {
    DCHECK(stereo_mode_);
  }

  // Alternate constructor for built-in meshes.
  MapToMeshFunction(MeshSpecType spec_type, float horizontal_fov_in_radians,
                    float vertical_fov_in_radians, const glm::mat4& transform,
                    const scoped_refptr<KeywordValue>& stereo_mode)
      : mesh_spec_(new MeshSpec(spec_type)),
        horizontal_fov_in_radians_(horizontal_fov_in_radians),
        vertical_fov_in_radians_(vertical_fov_in_radians),
        transform_(transform),
        stereo_mode_(stereo_mode) {
    DCHECK_NE(spec_type, kRectangular);
    DCHECK(stereo_mode_);
  }

  // Alternate constructor for built-in meshes without FOV or transforms.
  MapToMeshFunction(MeshSpecType spec_type,
                    const scoped_refptr<KeywordValue>& stereo_mode)
      : mesh_spec_(new MeshSpec(spec_type)),
        horizontal_fov_in_radians_(0.0f),
        vertical_fov_in_radians_(0.0f),
        transform_(glm::mat4()),
        stereo_mode_(stereo_mode) {
    DCHECK_EQ(spec_type, kRectangular);
    DCHECK(stereo_mode_);
  }

  ~MapToMeshFunction() override {}

  const MeshSpec& mesh_spec() const { return *mesh_spec_; }
  float horizontal_fov_in_radians() const { return horizontal_fov_in_radians_; }
  float vertical_fov_in_radians() const { return vertical_fov_in_radians_; }
  const glm::mat4& transform() const { return transform_; }
  const scoped_refptr<KeywordValue>& stereo_mode() const {
    return stereo_mode_;
  }

  std::string ToString() const override;

  bool operator==(const MapToMeshFunction& rhs) const;

  static const MapToMeshFunction* ExtractFromFilterList(
      PropertyValue* filter_list);

  DEFINE_POLYMORPHIC_EQUATABLE_TYPE(MapToMeshFunction);

 private:
  const scoped_ptr<MeshSpec> mesh_spec_;
  const float horizontal_fov_in_radians_;
  const float vertical_fov_in_radians_;
  const glm::mat4 transform_;
  const scoped_refptr<KeywordValue> stereo_mode_;

  DISALLOW_COPY_AND_ASSIGN(MapToMeshFunction);
};

}  // namespace cssom
}  // namespace cobalt

#endif  // COBALT_CSSOM_MAP_TO_MESH_FUNCTION_H_
