// 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.

precision mediump float;

// A rounded rect is represented by a vec4 specifying (min.xy, max.xy)
// and a matrix of corners. Each vector in the matrix represents a corner
// (order: top left, top right, bottom left, bottom right). Each corner vec4
// represents (start.xy, radius.xy).
uniform vec4 u_scissor_rect;
uniform mat4 u_scissor_corners;
uniform vec4 u_spread_rect;
uniform mat4 u_spread_corners;

// The scale_add uniform is used to switch the shader between generating
// outset shadows and inset shadows. It impacts the shadow gradient and
// scissor behavior. Use (1, 0) to get an outset shadow with the provided
// scissor rect behaving as an exclusive scissor, and (-1, 1) to get an
// inset shadow with scissor rect behaving as an inclusive scissor.
uniform vec2 u_scale_add;

// Blur calculations happen in terms in sigma distances. Use sigma_scale to
// translate pixel distances into sigma distances.
uniform vec2 u_sigma_scale;

// Adjust the sigma input value to tweak the blur output so that it better
// matches the reference. This is usually only needed for very large sigmas.
uniform vec2 u_sigma_tweak;

varying vec2 v_offset;
varying vec4 v_color;

#include "function_is_outside_rrect.inc"

// Calculate the distance from a point in the first quadrant to an ellipse
// centered at the origin.
//
// http://iquilezles.org/www/articles/ellipsedist/ellipsedist.htm
float GetEllipseDistance(vec2 p, vec2 ab) {
  if (abs(ab.x - ab.y) < 0.5) {
    return length(p) - ab.x;
  }

  if (p.x > p.y) {
    p = p.yx;
    ab = ab.yx;
  }

  float lr = 1.0 / (ab.y * ab.y - ab.x * ab.x);
  float m = ab.x * p.x * lr;
  float m2 = m * m;
  float n = ab.y * p.y * lr;
  float n2 = n * n;
  float c = (m2 + n2 - 1.0) * 0.333333333;
  float c3 = c * c * c;
  float q = c3 + m2 * n2 * 2.0;
  float d = c3 + m2 * n2;
  float g = m + m * n2;

  float co;

  if (d < 0.0) {
    float p = acos(q / c3) * 0.333333333;
    float s = cos(p);
    float t = sin(p) * 1.732050808;
    float rx = sqrt(-c * (s + t + 2.0) + m2);
    float ry = sqrt(-c * (s - t + 2.0) + m2);
    co = (ry + sign(lr) * rx + abs(g) / (rx * ry) - m) * 0.5;
  } else {
    float h = 2.0 * m * n * sqrt(d);
    float s = sign(q + h) * pow(abs(q + h), 0.333333333);
    float u = sign(q - h) * pow(abs(q - h), 0.333333333);
    float rx = -s - u - c * 4.0 + 2.0 * m2;
    float ry = (s - u) * 1.732050808;
    float rm = sqrt(rx * rx + ry * ry);
    float p = ry / sqrt(rm - rx);
    co = (p + 2.0 * g / rm - m) * 0.5;
  }

  float si = sqrt(1.0 - co * co);
  vec2 closest = vec2(ab.x * co, ab.y * si);
  return length(closest - p) * sign(p.y - closest.y);
}

// Get the x and y distances from the nearest edges of the rounded rect.
vec2 GetBlurPosition(vec4 rect, mat4 corners) {
  vec2 pos = max(rect.xy - v_offset, v_offset - rect.zw);

  vec4 select_corner = vec4(
      step(v_offset.x, corners[0].x) * step(v_offset.y, corners[0].y),
      step(corners[1].x, v_offset.x) * step(v_offset.y, corners[1].y),
      step(v_offset.x, corners[2].x) * step(corners[2].y, v_offset.y),
      step(corners[3].x, v_offset.x) * step(corners[3].y, v_offset.y));
  if (dot(select_corner, vec4(1.0)) > 0.5) {
    // Use distance from the closest point on the ellipse as the position
    // for blur calculations.
    vec4 corner = corners * select_corner;
    float dist = GetEllipseDistance(abs(v_offset - corner.xy), corner.zw);

    // Since the transition from non-corner to corner positions happens along
    // the ellipse's x or y axis, either pos.x = -corner.z or pos.y = -corner.w
    // when the transition happens. Keep one ordinate at a minimum so that
    // distance from the ellipse smoothly changes blur intensity.
    //
    // The return vec2 is used as blur = gi(x) * gi(y) where gi = the guassian
    // integral function. Swapping x and y has no impact on the final blur, so
    // distance can be substituted for one ordinate as long as the other takes
    // the right value. E.g. when pos = (-corner.z, 0), the point is on the top
    // center of the ellipse, so dist = 0. When pos = (0, -corner.w), dist = 0.
    // When pos = (-corner.z, -corner.w), the point is at the center of the
    // ellipse, and dist = max(-corner.z, -corner.w). So dist can be used as
    // long as the other ordinate is min(pos.x, pos.y).
    return vec2(dist, min(min(pos.x, pos.y), max(-corner.z, -corner.w)));
  }

  return pos;
}

void main() {
  float scissor_scale =
      IsOutsideRRect(v_offset, u_scissor_rect, u_scissor_corners) *
      u_scale_add.x + u_scale_add.y;

  vec2 pos = GetBlurPosition(u_spread_rect, u_spread_corners) *
             u_sigma_scale + u_sigma_tweak;
  vec2 pos2 = pos * pos;
  vec2 pos3 = pos2 * pos;
  vec4 posx = vec4(1.0, pos.x, pos2.x, pos3.x);
  vec4 posy = vec4(1.0, pos.y, pos2.y, pos3.y);

  // Approximation of the gaussian integral from [x, +inf).
  // http://stereopsis.com/shadowrect/
  const vec4 klower = vec4(0.4375, -1.125, -0.75, -0.1666666);
  const vec4 kmiddle = vec4(0.5, -0.75, 0.0, 0.3333333);
  const vec4 kupper = vec4(0.5625, -1.125, 0.75, -0.1666666);

  float gaussx = 0.0;
  if (pos.x < -1.5) {
    gaussx = 1.0;
  } else if (pos.x < -0.5) {
    gaussx = dot(posx, klower);
  } else if (pos.x < 0.5) {
    gaussx = dot(posx, kmiddle);
  } else if (pos.x < 1.5) {
    gaussx = dot(posx, kupper);
  }

  float gaussy = 0.0;
  if (pos.y < -1.5) {
    gaussy = 1.0;
  } else if (pos.y < -0.5) {
    gaussy = dot(posy, klower);
  } else if (pos.y < 0.5) {
    gaussy = dot(posy, kmiddle);
  } else if (pos.y < 1.5) {
    gaussy = dot(posy, kupper);
  }

  float alpha_scale = gaussx * gaussy * u_scale_add.x + u_scale_add.y;
  gl_FragColor = v_color * (alpha_scale * scissor_scale);
}
