// 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.

#include "cobalt/cssom/map_to_mesh_function.h"

#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "cobalt/cssom/filter_function_list_value.h"
#include "cobalt/cssom/keyword_value.h"
#include "cobalt/cssom/property_value_visitor.h"

namespace cobalt {
namespace cssom {

std::string MapToMeshFunction::ToString() const {
  std::string result = "map-to-mesh(";

  if (mesh_spec().mesh_type() == kEquirectangular) {
    result.append("equirectangular");
  } else if (mesh_spec().mesh_type() == kRectangular) {
    result.append("rectangular");
  } else if (mesh_spec().mesh_type() == kUrls) {
    result.append(mesh_spec().mesh_url()->ToString());

    const ResolutionMatchedMeshListBuilder& meshes =
        mesh_spec().resolution_matched_meshes();
    for (size_t mesh_index = 0; mesh_index < meshes.size(); ++mesh_index) {
      result.push_back(' ');
      result.append(base::IntToString(meshes[mesh_index]->width_match()));
      result.push_back(' ');
      result.append(base::IntToString(meshes[mesh_index]->height_match()));
      result.push_back(' ');
      result.append(meshes[mesh_index]->mesh_url()->ToString());
    }
  }

  if (mesh_spec().mesh_type() == kRectangular) {
    // Rectangular filters carry neither FOV nor transforms.
    result.append(", none, none, ");
  } else {
    result.append(base::StringPrintf(", %.7grad", horizontal_fov_in_radians()));
    result.append(base::StringPrintf(" %.7grad, ", vertical_fov_in_radians()));

    result.append("matrix3d(");
    for (int col = 0; col <= 3; ++col) {
      for (int row = 0; row <= 3; ++row) {
        if (col > 0 || row > 0) {
          result.append(", ");
        }
        result.append(base::StringPrintf("%.7g", transform()[col][row]));
      }
    }

    result.append("), ");
  }

  result.append(stereo_mode()->ToString());
  result.append(")");

  return result;
}

MapToMeshFunction::ResolutionMatchedMesh::ResolutionMatchedMesh(
    int width_match, int height_match,
    const scoped_refptr<PropertyValue>& mesh_url)
    : width_match_(width_match),
      height_match_(height_match),
      mesh_url_(mesh_url) {
  DCHECK(mesh_url_);
}

bool MapToMeshFunction::ResolutionMatchedMesh::operator==(
    const MapToMeshFunction::ResolutionMatchedMesh& rhs) const {
  return mesh_url()->Equals(*rhs.mesh_url()) &&
         width_match() == rhs.width_match() &&
         height_match() == rhs.height_match();
}

bool MapToMeshFunction::ResolutionMatchedMesh::operator!=(
    const MapToMeshFunction::ResolutionMatchedMesh& rhs) const {
  return !(*this == rhs);
}

const MapToMeshFunction* MapToMeshFunction::ExtractFromFilterList(
    PropertyValue* filter_value) {
  if (filter_value && filter_value != cssom::KeywordValue::GetNone()) {
    const cssom::FilterFunctionListValue::Builder& filter_list =
        base::polymorphic_downcast<cssom::FilterFunctionListValue*>(
            filter_value)
            ->value();

    for (size_t list_index = 0; list_index < filter_list.size(); ++list_index) {
      if (filter_list[list_index]->GetTypeId() ==
          base::GetTypeId<cssom::MapToMeshFunction>()) {
        return base::polymorphic_downcast<const cssom::MapToMeshFunction*>(
            filter_list[list_index].get());
      }
    }
  }

  return NULL;
}

bool MapToMeshFunction::operator==(const MapToMeshFunction& rhs) const {
  if (mesh_spec().mesh_type() != rhs.mesh_spec().mesh_type() ||
      horizontal_fov_in_radians() != rhs.horizontal_fov_in_radians() ||
      vertical_fov_in_radians() != rhs.vertical_fov_in_radians() ||
      !stereo_mode()->Equals(*rhs.stereo_mode())) {
    return false;
  }

  if (mesh_spec().mesh_type() == kUrls) {
    if (!mesh_spec().mesh_url()->Equals(*rhs.mesh_spec().mesh_url())) {
      return false;
    }

    const ResolutionMatchedMeshListBuilder& lhs_meshes =
        mesh_spec().resolution_matched_meshes();
    const ResolutionMatchedMeshListBuilder& rhs_meshes =
        rhs.mesh_spec().resolution_matched_meshes();

    if (lhs_meshes.size() != rhs_meshes.size()) {
      return false;
    }

    for (size_t i = 0; i < lhs_meshes.size(); ++i) {
      if (*lhs_meshes[i] != *rhs_meshes[i]) {
        return false;
      }
    }

    for (int col = 0; col <= 3; ++col) {
      if (!glm::all(glm::equal(transform()[col], rhs.transform()[col]))) {
        return false;
      }
    }
  }

  return true;
}

}  // namespace cssom
}  // namespace cobalt
