// Copyright 2017 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/renderer/rasterizer/egl/draw_rect_border.h"

#include <GLES2/gl2.h>

#include "base/logging.h"
#include "cobalt/math/insets_f.h"
#include "cobalt/math/transform_2d.h"
#include "cobalt/renderer/backend/egl/utils.h"
#include "egl/generated_shader_impl.h"
#include "starboard/memory.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace egl {

namespace {
// The border is drawn using three regions: an antialiased outer area, an
// antialiased inner area, and the solid area in between.
const int kRegionCount = 3;

// Each region consists of an outer and inner rectangle. However, since regions
// are adjacent to each other, many of these rectangles are shared.
const int kVertexCount = (kRegionCount + 1) * 4;

// The draw object may draw the content rect as well. If so, two triangles are
// used to draw the content rect.
const int kIndexCountForContentRect = 2 * 3;

// Each region has 4 rectangular areas corresponding to the possible borders.
// Each rectangular area is drawn using 2 triangles.
const int kIndexCount = kRegionCount * (4 * 2 * 3) + kIndexCountForContentRect;
}  // namespace

DrawRectBorder::DrawRectBorder(GraphicsState* graphics_state,
    const BaseState& base_state,
    const scoped_refptr<render_tree::RectNode>& node)
    : DrawPolyColor(base_state),
      draw_content_rect_(false) {
  DCHECK(node->data().border);
  allow_simple_clip_ = true;

  const render_tree::Border& border = *(node->data().border);
  render_tree::ColorRGBA border_color;
  int num_borders = 0;
  int num_unhandled_borders = 0;
  bool uniform_opposing_borders =
      border.left.style == border.right.style &&
      border.left.color == border.right.color &&
      border.top.style == border.bottom.style &&
      border.top.color == border.bottom.color;
  bool uniform_borders =
      uniform_opposing_borders &&
      border.left.style == border.top.style &&
      border.left.color == border.top.color;

  if (border.left.style == render_tree::kBorderStyleSolid) {
    border_color = border.left.color;
    ++num_borders;
  } else if (border.left.width > 0.0f) {
    ++num_unhandled_borders;
  }

  if (border.right.style == render_tree::kBorderStyleSolid) {
    border_color = border.right.color;
    ++num_borders;
  } else if (border.right.width > 0.0f) {
    ++num_unhandled_borders;
  }

  if (border.top.style == render_tree::kBorderStyleSolid) {
    border_color = border.top.color;
    ++num_borders;
  } else if (border.top.width > 0.0f) {
    ++num_unhandled_borders;
  }

  if (border.bottom.style == render_tree::kBorderStyleSolid) {
    border_color = border.bottom.color;
    ++num_borders;
  } else if (border.bottom.width > 0.0f) {
    ++num_unhandled_borders;
  }

  // Only non-rounded borders are supported. Additionally, only borders that
  // do not create a diagonal edge are supported. For example, a top border of
  // one color adjacent to a right border of a different color would create a
  // diagonal edge between them.
  is_valid_ = !node->data().rounded_corners && num_unhandled_borders == 0 &&
              ((num_borders <= 1) ||
               (num_borders == 2 && uniform_opposing_borders) ||
               (num_borders == 4 && uniform_borders));

  // If the background brush is solid-colored, then this object can handle the
  // content rect as well. Otherwise, don't draw the inner antialiased edge to
  // avoid having to blend with an unknown color.
  render_tree::ColorRGBA content_color(0);
  if (is_valid_) {
    if (node->data().background_brush) {
      draw_content_rect_ = node->data().background_brush->GetTypeId() ==
                           base::GetTypeId<render_tree::SolidColorBrush>();
      if (draw_content_rect_) {
        const render_tree::SolidColorBrush* solid_brush =
            base::polymorphic_downcast<const render_tree::SolidColorBrush*>
                (node->data().background_brush.get());
        content_color = GetDrawColor(solid_brush->color()) *
                        base_state_.opacity;
      }
    } else {
      // No background brush is the same as a totally transparent background.
      draw_content_rect_ = true;
    }
  }

  if (is_valid_) {
    content_rect_ = node->data().rect;
    content_rect_.Inset(border.left.width, border.top.width,
                        border.right.width, border.bottom.width);
    node_bounds_ = node->data().rect;

    if (num_borders > 0) {
      attributes_.reserve(kVertexCount);
      indices_.reserve(kIndexCount);
      border_color = GetDrawColor(border_color) * base_state_.opacity;
      is_valid_ = SetSquareBorder(border, node->data().rect, content_rect_,
                                  border_color, content_color);
      if (is_valid_ && attributes_.size() > 0) {
        graphics_state->ReserveVertexData(
            attributes_.size() * sizeof(attributes_[0]));
        graphics_state->ReserveVertexIndices(indices_.size());
      }
    }
  }
}

bool DrawRectBorder::SetSquareBorder(const render_tree::Border& border,
    const math::RectF& border_rect, const math::RectF& content_rect,
    const render_tree::ColorRGBA& border_color,
    const render_tree::ColorRGBA& content_color) {
  // If the scaled border rect is too small, then don't bother rendering.
  math::Vector2dF scale = math::GetScale2d(base_state_.transform);
  if (border_rect.width() * scale.x() < 1.0f ||
      border_rect.height() * scale.y() < 1.0f) {
    return true;
  }

  // Antialiased subpixel borders are not supported at this time. It can be
  // done by attenuating the alpha, but this can get complicated if the borders
  // are of different widths.
  float pixel_size_x = 1.0f / scale.x();
  float pixel_size_y = 1.0f / scale.y();
  if ((border.left.style != render_tree::kBorderStyleNone &&
        border.left.width < pixel_size_x) ||
      (border.right.style != render_tree::kBorderStyleNone &&
        border.right.width < pixel_size_x) ||
      (border.top.style != render_tree::kBorderStyleNone &&
        border.top.width < pixel_size_y) ||
      (border.bottom.style != render_tree::kBorderStyleNone &&
        border.bottom.style < pixel_size_y)) {
    return false;
  }

  // To antialias the edges, shrink the borders by half a pixel, then add a
  // 1-pixel edge which transitions to 0 (for outer) or content_color (for
  // inner). The rasterizer will handle interpolating to the correct color.
  math::InsetsF insets(
      border.left.style != render_tree::kBorderStyleNone ? 1.0f : 0.0f,
      border.top.style != render_tree::kBorderStyleNone ? 1.0f : 0.0f,
      border.right.style != render_tree::kBorderStyleNone ? 1.0f : 0.0f,
      border.bottom.style != render_tree::kBorderStyleNone ? 1.0f : 0.0f);
  math::RectF outer_rect(border_rect);
  math::RectF inner_rect(content_rect);
  outer_rect.Inset(insets.Scale(0.5f * pixel_size_x, 0.5f * pixel_size_y));
  if (draw_content_rect_) {
    inner_rect.Inset(insets.Scale(-0.5f * pixel_size_x, -0.5f * pixel_size_y));
  }
  math::RectF outer_outer(outer_rect);
  math::RectF inner_inner(inner_rect);
  outer_outer.Inset(insets.Scale(-pixel_size_x, -pixel_size_y));
  if (draw_content_rect_) {
    inner_inner.Inset(insets.Scale(pixel_size_x, pixel_size_y));
  }

  // Add the vertex attributes for the rectangles that will be used.
  uint16_t outer_outer_verts = static_cast<uint16_t>(attributes_.size());
  AddRectVertices(outer_outer, 0);
  uint16_t outer_rect_verts = static_cast<uint16_t>(attributes_.size());
  AddRectVertices(outer_rect, GetGLRGBA(border_color));
  uint16_t inner_rect_verts = static_cast<uint16_t>(attributes_.size());
  AddRectVertices(inner_rect, GetGLRGBA(border_color));
  uint16_t inner_inner_verts = inner_rect_verts;
  if (draw_content_rect_) {
    inner_inner_verts = static_cast<uint16_t>(attributes_.size());
    AddRectVertices(inner_inner, GetGLRGBA(content_color));
  }

  // Add indices to draw the borders using the vertex attributes added.
  AddBorders(border, outer_outer_verts, outer_rect_verts);
  AddBorders(border, outer_rect_verts, inner_rect_verts);
  if (draw_content_rect_) {
    AddBorders(border, inner_rect_verts, inner_inner_verts);
  }

  // Draw the content rect as appropriate.
  if (draw_content_rect_ && content_color.a() > 0.0f) {
    AddRectIndices(inner_inner_verts, inner_inner_verts + 1,
                   inner_inner_verts + 2, inner_inner_verts + 3);
  }

  // Update the content and node bounds to account for the antialiasing edges.
  node_bounds_ = outer_outer;
  content_rect_ = inner_inner;
  return true;
}

void DrawRectBorder::AddBorders(const render_tree::Border& border,
    uint16_t outer_verts, uint16_t inner_verts) {
  // Draw the area between those two rectangles using triangle primitives.
  // The vertices for the rectangles were added as top-left, top-right,
  // bottom-left, and bottom-right. See DrawPolyColor::AddRectVertices().
  if (border.left.style != render_tree::kBorderStyleNone) {
    AddRectIndices(outer_verts, inner_verts,
                   outer_verts + 2, inner_verts + 2);
  }
  if (border.top.style != render_tree::kBorderStyleNone) {
    AddRectIndices(outer_verts, outer_verts + 1,
                   inner_verts, inner_verts + 1);
  }
  if (border.right.style != render_tree::kBorderStyleNone) {
    AddRectIndices(inner_verts + 1, outer_verts + 1,
                   inner_verts + 3, outer_verts + 3);
  }
  if (border.bottom.style != render_tree::kBorderStyleNone) {
    AddRectIndices(inner_verts + 2, inner_verts + 3,
                   outer_verts + 2, outer_verts + 3);
  }
}

}  // namespace egl
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt
