// Copyright 2017 Google Inc. 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/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 = GetScale();
  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
