// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/quads/draw_polygon.h"

#include <vector>

#include "cc/output/bsp_compare_result.h"
#include "cc/quads/draw_quad.h"

namespace {
// This allows for some imperfection in the normal comparison when checking if
// two pieces of geometry are coplanar.
static const float coplanar_dot_epsilon = 0.01f;
// This threshold controls how "thick" a plane is. If a point's distance is
// <= |compare_threshold|, then it is considered on the plane. Only when this
// boundary is crossed do we consider doing splitting.
static const float compare_threshold = 1.0f;
// |split_threshold| is lower in this case because we want the points created
// during splitting to be well within the range of |compare_threshold| for
// comparison purposes. The splitting operation will produce intersection points
// that fit within a tighter distance to the splitting plane as a result of this
// value. By using a value >= |compare_threshold| we run the risk of creating
// points that SHOULD be intersecting the "thick plane", but actually fail to
// test positively for it because |split_threshold| allowed them to be outside
// this range.
static const float split_threshold = 0.5f;
}  // namespace

namespace cc {

gfx::Vector3dF DrawPolygon::default_normal = gfx::Vector3dF(0.0f, 0.0f, -1.0f);

DrawPolygon::DrawPolygon() {
}

DrawPolygon::DrawPolygon(DrawQuad* original,
                         const std::vector<gfx::Point3F>& in_points,
                         const gfx::Vector3dF& normal,
                         int draw_order_index)
    : order_index_(draw_order_index), original_ref_(original) {
  for (size_t i = 0; i < in_points.size(); i++) {
    points_.push_back(in_points[i]);
  }
  normal_ = normal;
}

// This takes the original DrawQuad that this polygon should be based on,
// a visible content rect to make the 4 corner points from, and a transformation
// to move it and its normal into screen space.
DrawPolygon::DrawPolygon(DrawQuad* original_ref,
                         const gfx::RectF& visible_content_rect,
                         const gfx::Transform& transform,
                         int draw_order_index)
    : order_index_(draw_order_index), original_ref_(original_ref) {
  normal_ = default_normal;
  gfx::Point3F points[8];
  int num_vertices_in_clipped_quad;
  gfx::QuadF send_quad(visible_content_rect);

  // Doing this mapping here is very important, since we can't just transform
  // the points without clipping and not run into strange geometry issues when
  // crossing w = 0. At this point, in the constructor, we know that we're
  // working with a quad, so we can reuse the MathUtil::MapClippedQuad3d
  // function instead of writing a generic polygon version of it.
  MathUtil::MapClippedQuad3d(
      transform, send_quad, points, &num_vertices_in_clipped_quad);
  for (int i = 0; i < num_vertices_in_clipped_quad; i++) {
    points_.push_back(points[i]);
  }
  ApplyTransformToNormal(transform);
}

DrawPolygon::~DrawPolygon() {
}

scoped_ptr<DrawPolygon> DrawPolygon::CreateCopy() {
  scoped_ptr<DrawPolygon> new_polygon(new DrawPolygon());
  new_polygon->order_index_ = order_index_;
  new_polygon->original_ref_ = original_ref_;
  new_polygon->points_.reserve(points_.size());
  new_polygon->points_ = points_;
  new_polygon->normal_.set_x(normal_.x());
  new_polygon->normal_.set_y(normal_.y());
  new_polygon->normal_.set_z(normal_.z());
  return new_polygon.Pass();
}

float DrawPolygon::SignedPointDistance(const gfx::Point3F& point) const {
  return gfx::DotProduct(point - points_[0], normal_);
}

// Checks whether or not shape a lies on the front or back side of b, or
// whether they should be considered coplanar. If on the back side, we
// say A_BEFORE_B because it should be drawn in that order.
// Assumes that layers are split and there are no intersecting planes.
BspCompareResult DrawPolygon::SideCompare(const DrawPolygon& a,
                                          const DrawPolygon& b) {
  // Right away let's check if they're coplanar
  double dot = gfx::DotProduct(a.normal_, b.normal_);
  float sign = 0.0f;
  bool normal_match = false;
  // This check assumes that the normals are normalized.
  if (std::abs(dot) >= 1.0f - coplanar_dot_epsilon) {
    normal_match = true;
    // The normals are matching enough that we only have to test one point.
    sign = gfx::DotProduct(a.points_[0] - b.points_[0], b.normal_);
    // Is it on either side of the splitter?
    if (sign < -compare_threshold) {
      return BSP_BACK;
    }

    if (sign > compare_threshold) {
      return BSP_FRONT;
    }

    // No it wasn't, so the sign of the dot product of the normals
    // along with document order determines which side it goes on.
    if (dot >= 0.0f) {
      if (a.order_index_ < b.order_index_) {
        return BSP_COPLANAR_FRONT;
      }
      return BSP_COPLANAR_BACK;
    }

    if (a.order_index_ < b.order_index_) {
      return BSP_COPLANAR_BACK;
    }
    return BSP_COPLANAR_FRONT;
  }

  int pos_count = 0;
  int neg_count = 0;
  for (size_t i = 0; i < a.points_.size(); i++) {
    if (!normal_match || (normal_match && i > 0)) {
      sign = gfx::DotProduct(a.points_[i] - b.points_[0], b.normal_);
    }

    if (sign < -compare_threshold) {
      ++neg_count;
    } else if (sign > compare_threshold) {
      ++pos_count;
    }

    if (pos_count && neg_count) {
      return BSP_SPLIT;
    }
  }

  if (pos_count) {
    return BSP_FRONT;
  }
  return BSP_BACK;
}

static bool LineIntersectPlane(const gfx::Point3F& line_start,
                               const gfx::Point3F& line_end,
                               const gfx::Point3F& plane_origin,
                               const gfx::Vector3dF& plane_normal,
                               gfx::Point3F* intersection,
                               float distance_threshold) {
  gfx::Vector3dF start_to_origin_vector = plane_origin - line_start;
  gfx::Vector3dF end_to_origin_vector = plane_origin - line_end;

  double start_distance = gfx::DotProduct(start_to_origin_vector, plane_normal);
  double end_distance = gfx::DotProduct(end_to_origin_vector, plane_normal);

  // The case where one vertex lies on the thick-plane and the other
  // is outside of it.
  if (std::abs(start_distance) < distance_threshold &&
      std::abs(end_distance) > distance_threshold) {
    intersection->SetPoint(line_start.x(), line_start.y(), line_start.z());
    return true;
  }

  // This is the case where we clearly cross the thick-plane.
  if ((start_distance > distance_threshold &&
       end_distance < -distance_threshold) ||
      (start_distance < -distance_threshold &&
       end_distance > distance_threshold)) {
    gfx::Vector3dF v = line_end - line_start;
    float total_distance = std::abs(start_distance) + std::abs(end_distance);
    float lerp_factor = std::abs(start_distance) / total_distance;

    intersection->SetPoint(line_start.x() + (v.x() * lerp_factor),
                           line_start.y() + (v.y() * lerp_factor),
                           line_start.z() + (v.z() * lerp_factor));

    return true;
  }
  return false;
}

// This function is separate from ApplyTransform because it is often unnecessary
// to transform the normal with the rest of the polygon.
// When drawing these polygons, it is necessary to move them back into layer
// space before sending them to OpenGL, which requires using ApplyTransform,
// but normal information is no longer needed after sorting.
void DrawPolygon::ApplyTransformToNormal(const gfx::Transform& transform) {
  // Now we use the inverse transpose of |transform| to transform the normal.
  gfx::Transform inverse_transform;
  bool inverted = transform.GetInverse(&inverse_transform);
  DCHECK(inverted);
  if (!inverted)
    return;
  inverse_transform.Transpose();

  gfx::Point3F new_normal(normal_.x(), normal_.y(), normal_.z());
  inverse_transform.TransformPoint(&new_normal);
  // Make sure our normal is still normalized.
  normal_ = gfx::Vector3dF(new_normal.x(), new_normal.y(), new_normal.z());
  float normal_magnitude = normal_.Length();
  if (normal_magnitude != 0 && normal_magnitude != 1) {
    normal_.Scale(1.0f / normal_magnitude);
  }
}

void DrawPolygon::ApplyTransform(const gfx::Transform& transform) {
  for (size_t i = 0; i < points_.size(); i++) {
    transform.TransformPoint(&points_[i]);
  }
}

// TransformToScreenSpace assumes we're moving a layer from its layer space
// into 3D screen space, which for sorting purposes requires the normal to
// be transformed along with the vertices.
void DrawPolygon::TransformToScreenSpace(const gfx::Transform& transform) {
  ApplyTransform(transform);
  ApplyTransformToNormal(transform);
}

// In the case of TransformToLayerSpace, we assume that we are giving the
// inverse transformation back to the polygon to move it back into layer space
// but we can ignore the costly process of applying the inverse to the normal
// since we know the normal will just reset to its original state.
void DrawPolygon::TransformToLayerSpace(
    const gfx::Transform& inverse_transform) {
  ApplyTransform(inverse_transform);
  normal_ = gfx::Vector3dF(0.0f, 0.0f, -1.0f);
}

bool DrawPolygon::Split(const DrawPolygon& splitter,
                        scoped_ptr<DrawPolygon>* front,
                        scoped_ptr<DrawPolygon>* back) {
  gfx::Point3F intersections[2];
  std::vector<gfx::Point3F> out_points[2];
  // vertex_before stores the index of the vertex before its matching
  // intersection.
  // i.e. vertex_before[0] stores the vertex we saw before we crossed the plane
  // which resulted in the line/plane intersection giving us intersections[0].
  size_t vertex_before[2];
  size_t points_size = points_.size();
  size_t current_intersection = 0;

  size_t current_vertex = 0;
  // We will only have two intersection points because we assume all polygons
  // are convex.
  while (current_intersection < 2) {
    if (LineIntersectPlane(points_[(current_vertex % points_size)],
                           points_[(current_vertex + 1) % points_size],
                           splitter.points_[0],
                           splitter.normal_,
                           &intersections[current_intersection],
                           split_threshold)) {
      vertex_before[current_intersection] = current_vertex % points_size;
      current_intersection++;
      // We found both intersection points so we're done already.
      if (current_intersection == 2) {
        break;
      }
    }
    if (current_vertex++ > points_size) {
      break;
    }
  }
  DCHECK_EQ(current_intersection, static_cast<size_t>(2));

  // Since we found both the intersection points, we can begin building the
  // vertex set for both our new polygons.
  size_t start1 = (vertex_before[0] + 1) % points_size;
  size_t start2 = (vertex_before[1] + 1) % points_size;
  size_t points_remaining = points_size;

  // First polygon.
  out_points[0].push_back(intersections[0]);
  for (size_t i = start1; i <= vertex_before[1]; i++) {
    out_points[0].push_back(points_[i]);
    --points_remaining;
  }
  out_points[0].push_back(intersections[1]);

  // Second polygon.
  out_points[1].push_back(intersections[1]);
  size_t index = start2;
  for (size_t i = 0; i < points_remaining; i++) {
    out_points[1].push_back(points_[index % points_size]);
    ++index;
  }
  out_points[1].push_back(intersections[0]);

  // Give both polygons the original splitting polygon's ID, so that they'll
  // still be sorted properly in co-planar instances.
  scoped_ptr<DrawPolygon> poly1(
      new DrawPolygon(original_ref_, out_points[0], normal_, order_index_));
  scoped_ptr<DrawPolygon> poly2(
      new DrawPolygon(original_ref_, out_points[1], normal_, order_index_));

  if (SideCompare(*poly1, splitter) == BSP_FRONT) {
    *front = poly1.Pass();
    *back = poly2.Pass();
  } else {
    *front = poly2.Pass();
    *back = poly1.Pass();
  }
  return true;
}

// This algorithm takes the first vertex in the polygon and uses that as a
// pivot point to fan out and create quads from the rest of the vertices.
// |offset| starts off as the second vertex, and then |op1| and |op2| indicate
// offset+1 and offset+2 respectively.
// After the first quad is created, the first vertex in the next quad is the
// same as all the rest, the pivot point. The second vertex in the next quad is
// the old |op2|, the last vertex added to the previous quad. This continues
// until all points are exhausted.
// The special case here is where there are only 3 points remaining, in which
// case we use the same values for vertex 3 and 4 to make a degenerate quad
// that represents a triangle.
void DrawPolygon::ToQuads2D(std::vector<gfx::QuadF>* quads) const {
  if (points_.size() <= 2)
    return;

  gfx::PointF first(points_[0].x(), points_[0].y());
  size_t offset = 1;
  while (offset < points_.size() - 1) {
    size_t op1 = offset + 1;
    size_t op2 = offset + 2;
    if (op2 >= points_.size()) {
      // It's going to be a degenerate triangle.
      op2 = op1;
    }
    quads->push_back(
        gfx::QuadF(first,
                   gfx::PointF(points_[offset].x(), points_[offset].y()),
                   gfx::PointF(points_[op1].x(), points_[op1].y()),
                   gfx::PointF(points_[op2].x(), points_[op2].y())));
    offset = op2;
  }
}

}  // namespace cc
