/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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.
 */

// The highest z value can't be higher than (CASTER_Z_CAP_RATIO * light.z)
#define CASTER_Z_CAP_RATIO 0.95f

// When there is no umbra, then just fake the umbra using
// centroid * (1 - FAKE_UMBRA_SIZE_RATIO) + outline * FAKE_UMBRA_SIZE_RATIO
#define FAKE_UMBRA_SIZE_RATIO 0.05f

// When the polygon is about 90 vertices, the penumbra + umbra can reach 270 rays.
// That is consider pretty fine tessllated polygon so far.
// This is just to prevent using too much some memory when edge slicing is not
// needed any more.
#define FINE_TESSELLATED_POLYGON_RAY_NUMBER 270
/**
 * Extra vertices for the corner for smoother corner.
 * Only for outer loop.
 * Note that we use such extra memory to avoid an extra loop.
 */
// For half circle, we could add EXTRA_VERTEX_PER_PI vertices.
// Set to 1 if we don't want to have any.
#define SPOT_EXTRA_CORNER_VERTEX_PER_PI 18

// For the whole polygon, the sum of all the deltas b/t normals is 2 * M_PI,
// therefore, the maximum number of extra vertices will be twice bigger.
#define SPOT_MAX_EXTRA_CORNER_VERTEX_NUMBER (2 * SPOT_EXTRA_CORNER_VERTEX_PER_PI)

// For each RADIANS_DIVISOR, we would allocate one more vertex b/t the normals.
#define SPOT_CORNER_RADIANS_DIVISOR (M_PI / SPOT_EXTRA_CORNER_VERTEX_PER_PI)

#define PENUMBRA_ALPHA 0.0f
#define UMBRA_ALPHA 1.0f

#include "SpotShadow.h"

#include "ShadowTessellator.h"
#include "Vertex.h"
#include "VertexBuffer.h"
#include "utils/MathUtils.h"

#include <math.h>
#include <stdlib.h>
#include <utils/Log.h>
#include <algorithm>

// TODO: After we settle down the new algorithm, we can remove the old one and
// its utility functions.
// Right now, we still need to keep it for comparison purpose and future expansion.
namespace android {
namespace uirenderer {

static const float EPSILON = 1e-7;

/**
 * For each polygon's vertex, the light center will project it to the receiver
 * as one of the outline vertex.
 * For each outline vertex, we need to store the position and normal.
 * Normal here is defined against the edge by the current vertex and the next vertex.
 */
struct OutlineData {
    Vector2 position;
    Vector2 normal;
    float radius;
};

/**
 * For each vertex, we need to keep track of its angle, whether it is penumbra or
 * umbra, and its corresponding vertex index.
 */
struct SpotShadow::VertexAngleData {
    // The angle to the vertex from the centroid.
    float mAngle;
    // True is the vertex comes from penumbra, otherwise it comes from umbra.
    bool mIsPenumbra;
    // The index of the vertex described by this data.
    int mVertexIndex;
    void set(float angle, bool isPenumbra, int index) {
        mAngle = angle;
        mIsPenumbra = isPenumbra;
        mVertexIndex = index;
    }
};

/**
 * Calculate the angle between and x and a y coordinate.
 * The atan2 range from -PI to PI.
 */
static float angle(const Vector2& point, const Vector2& center) {
    return atan2(point.y - center.y, point.x - center.x);
}

/**
 * Calculate the intersection of a ray with the line segment defined by two points.
 *
 * Returns a negative value in error conditions.

 * @param rayOrigin The start of the ray
 * @param dx The x vector of the ray
 * @param dy The y vector of the ray
 * @param p1 The first point defining the line segment
 * @param p2 The second point defining the line segment
 * @return The distance along the ray if it intersects with the line segment, negative if otherwise
 */
static float rayIntersectPoints(const Vector2& rayOrigin, float dx, float dy, const Vector2& p1,
                                const Vector2& p2) {
    // The math below is derived from solving this formula, basically the
    // intersection point should stay on both the ray and the edge of (p1, p2).
    // solve([p1x+t*(p2x-p1x)=dx*t2+px,p1y+t*(p2y-p1y)=dy*t2+py],[t,t2]);

    float divisor = (dx * (p1.y - p2.y) + dy * p2.x - dy * p1.x);
    if (divisor == 0) return -1.0f;  // error, invalid divisor

#if DEBUG_SHADOW
    float interpVal = (dx * (p1.y - rayOrigin.y) + dy * rayOrigin.x - dy * p1.x) / divisor;
    if (interpVal < 0 || interpVal > 1) {
        ALOGW("rayIntersectPoints is hitting outside the segment %f", interpVal);
    }
#endif

    float distance = (p1.x * (rayOrigin.y - p2.y) + p2.x * (p1.y - rayOrigin.y) +
                      rayOrigin.x * (p2.y - p1.y)) /
                     divisor;

    return distance;  // may be negative in error cases
}

/**
 * Sort points by their X coordinates
 *
 * @param points the points as a Vector2 array.
 * @param pointsLength the number of vertices of the polygon.
 */
void SpotShadow::xsort(Vector2* points, int pointsLength) {
    auto cmp = [](const Vector2& a, const Vector2& b) -> bool { return a.x < b.x; };
    std::sort(points, points + pointsLength, cmp);
}

/**
 * compute the convex hull of a collection of Points
 *
 * @param points the points as a Vector2 array.
 * @param pointsLength the number of vertices of the polygon.
 * @param retPoly pre allocated array of floats to put the vertices
 * @return the number of points in the polygon 0 if no intersection
 */
int SpotShadow::hull(Vector2* points, int pointsLength, Vector2* retPoly) {
    xsort(points, pointsLength);
    int n = pointsLength;
    Vector2 lUpper[n];
    lUpper[0] = points[0];
    lUpper[1] = points[1];

    int lUpperSize = 2;

    for (int i = 2; i < n; i++) {
        lUpper[lUpperSize] = points[i];
        lUpperSize++;

        while (lUpperSize > 2 &&
               !ccw(lUpper[lUpperSize - 3].x, lUpper[lUpperSize - 3].y, lUpper[lUpperSize - 2].x,
                    lUpper[lUpperSize - 2].y, lUpper[lUpperSize - 1].x, lUpper[lUpperSize - 1].y)) {
            // Remove the middle point of the three last
            lUpper[lUpperSize - 2].x = lUpper[lUpperSize - 1].x;
            lUpper[lUpperSize - 2].y = lUpper[lUpperSize - 1].y;
            lUpperSize--;
        }
    }

    Vector2 lLower[n];
    lLower[0] = points[n - 1];
    lLower[1] = points[n - 2];

    int lLowerSize = 2;

    for (int i = n - 3; i >= 0; i--) {
        lLower[lLowerSize] = points[i];
        lLowerSize++;

        while (lLowerSize > 2 &&
               !ccw(lLower[lLowerSize - 3].x, lLower[lLowerSize - 3].y, lLower[lLowerSize - 2].x,
                    lLower[lLowerSize - 2].y, lLower[lLowerSize - 1].x, lLower[lLowerSize - 1].y)) {
            // Remove the middle point of the three last
            lLower[lLowerSize - 2] = lLower[lLowerSize - 1];
            lLowerSize--;
        }
    }

    // output points in CW ordering
    const int total = lUpperSize + lLowerSize - 2;
    int outIndex = total - 1;
    for (int i = 0; i < lUpperSize; i++) {
        retPoly[outIndex] = lUpper[i];
        outIndex--;
    }

    for (int i = 1; i < lLowerSize - 1; i++) {
        retPoly[outIndex] = lLower[i];
        outIndex--;
    }
    // TODO: Add test harness which verify that all the points are inside the hull.
    return total;
}

/**
 * Test whether the 3 points form a counter clockwise turn.
 *
 * @return true if a right hand turn
 */
bool SpotShadow::ccw(float ax, float ay, float bx, float by, float cx, float cy) {
    return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax) > EPSILON;
}

/**
 * Sort points about a center point
 *
 * @param poly The in and out polyogon as a Vector2 array.
 * @param polyLength The number of vertices of the polygon.
 * @param center the center ctr[0] = x , ctr[1] = y to sort around.
 */
void SpotShadow::sort(Vector2* poly, int polyLength, const Vector2& center) {
    quicksortCirc(poly, 0, polyLength - 1, center);
}

/**
 * Swap points pointed to by i and j
 */
void SpotShadow::swap(Vector2* points, int i, int j) {
    Vector2 temp = points[i];
    points[i] = points[j];
    points[j] = temp;
}

/**
 * quick sort implementation about the center.
 */
void SpotShadow::quicksortCirc(Vector2* points, int low, int high, const Vector2& center) {
    int i = low, j = high;
    int p = low + (high - low) / 2;
    float pivot = angle(points[p], center);
    while (i <= j) {
        while (angle(points[i], center) > pivot) {
            i++;
        }
        while (angle(points[j], center) < pivot) {
            j--;
        }

        if (i <= j) {
            swap(points, i, j);
            i++;
            j--;
        }
    }
    if (low < j) quicksortCirc(points, low, j, center);
    if (i < high) quicksortCirc(points, i, high, center);
}

/**
 * Test whether a point is inside the polygon.
 *
 * @param testPoint the point to test
 * @param poly the polygon
 * @return true if the testPoint is inside the poly.
 */
bool SpotShadow::testPointInsidePolygon(const Vector2 testPoint, const Vector2* poly, int len) {
    bool c = false;
    float testx = testPoint.x;
    float testy = testPoint.y;
    for (int i = 0, j = len - 1; i < len; j = i++) {
        float startX = poly[j].x;
        float startY = poly[j].y;
        float endX = poly[i].x;
        float endY = poly[i].y;

        if (((endY > testy) != (startY > testy)) &&
            (testx < (startX - endX) * (testy - endY) / (startY - endY) + endX)) {
            c = !c;
        }
    }
    return c;
}

/**
 * Reverse the polygon
 *
 * @param polygon the polygon as a Vector2 array
 * @param len the number of points of the polygon
 */
void SpotShadow::reverse(Vector2* polygon, int len) {
    int n = len / 2;
    for (int i = 0; i < n; i++) {
        Vector2 tmp = polygon[i];
        int k = len - 1 - i;
        polygon[i] = polygon[k];
        polygon[k] = tmp;
    }
}

/**
 * Compute a horizontal circular polygon about point (x , y , height) of radius
 * (size)
 *
 * @param points number of the points of the output polygon.
 * @param lightCenter the center of the light.
 * @param size the light size.
 * @param ret result polygon.
 */
void SpotShadow::computeLightPolygon(int points, const Vector3& lightCenter, float size,
                                     Vector3* ret) {
    // TODO: Caching all the sin / cos values and store them in a look up table.
    for (int i = 0; i < points; i++) {
        float angle = 2 * i * M_PI / points;
        ret[i].x = cosf(angle) * size + lightCenter.x;
        ret[i].y = sinf(angle) * size + lightCenter.y;
        ret[i].z = lightCenter.z;
    }
}

/**
 * From light center, project one vertex to the z=0 surface and get the outline.
 *
 * @param outline The result which is the outline position.
 * @param lightCenter The center of light.
 * @param polyVertex The input polygon's vertex.
 *
 * @return float The ratio of (polygon.z / light.z - polygon.z)
 */
float SpotShadow::projectCasterToOutline(Vector2& outline, const Vector3& lightCenter,
                                         const Vector3& polyVertex) {
    float lightToPolyZ = lightCenter.z - polyVertex.z;
    float ratioZ = CASTER_Z_CAP_RATIO;
    if (lightToPolyZ != 0) {
        // If any caster's vertex is almost above the light, we just keep it as 95%
        // of the height of the light.
        ratioZ = MathUtils::clamp(polyVertex.z / lightToPolyZ, 0.0f, CASTER_Z_CAP_RATIO);
    }

    outline.x = polyVertex.x - ratioZ * (lightCenter.x - polyVertex.x);
    outline.y = polyVertex.y - ratioZ * (lightCenter.y - polyVertex.y);
    return ratioZ;
}

/**
 * Generate the shadow spot light of shape lightPoly and a object poly
 *
 * @param isCasterOpaque whether the caster is opaque
 * @param lightCenter the center of the light
 * @param lightSize the radius of the light
 * @param poly x,y,z vertexes of a convex polygon that occludes the light source
 * @param polyLength number of vertexes of the occluding polygon
 * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
 *                            empty strip if error.
 */
void SpotShadow::createSpotShadow(bool isCasterOpaque, const Vector3& lightCenter, float lightSize,
                                  const Vector3* poly, int polyLength, const Vector3& polyCentroid,
                                  VertexBuffer& shadowTriangleStrip) {
    if (CC_UNLIKELY(lightCenter.z <= 0)) {
        ALOGW("Relative Light Z is not positive. No spot shadow!");
        return;
    }
    if (CC_UNLIKELY(polyLength < 3)) {
#if DEBUG_SHADOW
        ALOGW("Invalid polygon length. No spot shadow!");
#endif
        return;
    }
    OutlineData outlineData[polyLength];
    Vector2 outlineCentroid;
    // Calculate the projected outline for each polygon's vertices from the light center.
    //
    //                       O     Light
    //                      /
    //                    /
    //                   .     Polygon vertex
    //                 /
    //               /
    //              O     Outline vertices
    //
    // Ratio = (Poly - Outline) / (Light - Poly)
    // Outline.x = Poly.x - Ratio * (Light.x - Poly.x)
    // Outline's radius / Light's radius = Ratio

    // Compute the last outline vertex to make sure we can get the normal and outline
    // in one single loop.
    projectCasterToOutline(outlineData[polyLength - 1].position, lightCenter, poly[polyLength - 1]);

    // Take the outline's polygon, calculate the normal for each outline edge.
    int currentNormalIndex = polyLength - 1;
    int nextNormalIndex = 0;

    for (int i = 0; i < polyLength; i++) {
        float ratioZ = projectCasterToOutline(outlineData[i].position, lightCenter, poly[i]);
        outlineData[i].radius = ratioZ * lightSize;

        outlineData[currentNormalIndex].normal = ShadowTessellator::calculateNormal(
                outlineData[currentNormalIndex].position, outlineData[nextNormalIndex].position);
        currentNormalIndex = (currentNormalIndex + 1) % polyLength;
        nextNormalIndex++;
    }

    projectCasterToOutline(outlineCentroid, lightCenter, polyCentroid);

    int penumbraIndex = 0;
    // Then each polygon's vertex produce at minmal 2 penumbra vertices.
    // Since the size can be dynamic here, we keep track of the size and update
    // the real size at the end.
    int allocatedPenumbraLength = 2 * polyLength + SPOT_MAX_EXTRA_CORNER_VERTEX_NUMBER;
    Vector2 penumbra[allocatedPenumbraLength];
    int totalExtraCornerSliceNumber = 0;

    Vector2 umbra[polyLength];

    // When centroid is covered by all circles from outline, then we consider
    // the umbra is invalid, and we will tune down the shadow strength.
    bool hasValidUmbra = true;
    // We need the minimal of RaitoVI to decrease the spot shadow strength accordingly.
    float minRaitoVI = FLT_MAX;

    for (int i = 0; i < polyLength; i++) {
        // Generate all the penumbra's vertices only using the (outline vertex + normal * radius)
        // There is no guarantee that the penumbra is still convex, but for
        // each outline vertex, it will connect to all its corresponding penumbra vertices as
        // triangle fans. And for neighber penumbra vertex, it will be a trapezoid.
        //
        // Penumbra Vertices marked as Pi
        // Outline Vertices marked as Vi
        //                                            (P3)
        //          (P2)                               |     ' (P4)
        //   (P1)'   |                                 |   '
        //         ' |                                 | '
        // (P0)  ------------------------------------------------(P5)
        //           | (V0)                            |(V1)
        //           |                                 |
        //           |                                 |
        //           |                                 |
        //           |                                 |
        //           |                                 |
        //           |                                 |
        //           |                                 |
        //           |                                 |
        //       (V3)-----------------------------------(V2)
        int preNormalIndex = (i + polyLength - 1) % polyLength;

        const Vector2& previousNormal = outlineData[preNormalIndex].normal;
        const Vector2& currentNormal = outlineData[i].normal;

        // Depending on how roundness we want for each corner, we can subdivide
        // further here and/or introduce some heuristic to decide how much the
        // subdivision should be.
        int currentExtraSliceNumber = ShadowTessellator::getExtraVertexNumber(
                previousNormal, currentNormal, SPOT_CORNER_RADIANS_DIVISOR);

        int currentCornerSliceNumber = 1 + currentExtraSliceNumber;
        totalExtraCornerSliceNumber += currentExtraSliceNumber;
#if DEBUG_SHADOW
        ALOGD("currentExtraSliceNumber should be %d", currentExtraSliceNumber);
        ALOGD("currentCornerSliceNumber should be %d", currentCornerSliceNumber);
        ALOGD("totalCornerSliceNumber is %d", totalExtraCornerSliceNumber);
#endif
        if (CC_UNLIKELY(totalExtraCornerSliceNumber > SPOT_MAX_EXTRA_CORNER_VERTEX_NUMBER)) {
            currentCornerSliceNumber = 1;
        }
        for (int k = 0; k <= currentCornerSliceNumber; k++) {
            Vector2 avgNormal =
                    (previousNormal * (currentCornerSliceNumber - k) + currentNormal * k) /
                    currentCornerSliceNumber;
            avgNormal.normalize();
            penumbra[penumbraIndex++] = outlineData[i].position + avgNormal * outlineData[i].radius;
        }

        // Compute the umbra by the intersection from the outline's centroid!
        //
        //       (V) ------------------------------------
        //           |          '                       |
        //           |         '                        |
        //           |       ' (I)                      |
        //           |    '                             |
        //           | '             (C)                |
        //           |                                  |
        //           |                                  |
        //           |                                  |
        //           |                                  |
        //           ------------------------------------
        //
        // Connect a line b/t the outline vertex (V) and the centroid (C), it will
        // intersect with the outline vertex's circle at point (I).
        // Now, ratioVI = VI / VC, ratioIC = IC / VC
        // Then the intersetion point can be computed as Ixy = Vxy * ratioIC + Cxy * ratioVI;
        //
        // When all of the outline circles cover the the outline centroid, (like I is
        // on the other side of C), there is no real umbra any more, so we just fake
        // a small area around the centroid as the umbra, and tune down the spot
        // shadow's umbra strength to simulate the effect the whole shadow will
        // become lighter in this case.
        // The ratio can be simulated by using the inverse of maximum of ratioVI for
        // all (V).
        float distOutline = (outlineData[i].position - outlineCentroid).length();
        if (CC_UNLIKELY(distOutline == 0)) {
            // If the outline has 0 area, then there is no spot shadow anyway.
            ALOGW("Outline has 0 area, no spot shadow!");
            return;
        }

        float ratioVI = outlineData[i].radius / distOutline;
        minRaitoVI = std::min(minRaitoVI, ratioVI);
        if (ratioVI >= (1 - FAKE_UMBRA_SIZE_RATIO)) {
            ratioVI = (1 - FAKE_UMBRA_SIZE_RATIO);
        }
        // When we know we don't have valid umbra, don't bother to compute the
        // values below. But we can't skip the loop yet since we want to know the
        // maximum ratio.
        float ratioIC = 1 - ratioVI;
        umbra[i] = outlineData[i].position * ratioIC + outlineCentroid * ratioVI;
    }

    hasValidUmbra = (minRaitoVI <= 1.0);
    float shadowStrengthScale = 1.0;
    if (!hasValidUmbra) {
#if DEBUG_SHADOW
        ALOGW("The object is too close to the light or too small, no real umbra!");
#endif
        for (int i = 0; i < polyLength; i++) {
            umbra[i] = outlineData[i].position * FAKE_UMBRA_SIZE_RATIO +
                       outlineCentroid * (1 - FAKE_UMBRA_SIZE_RATIO);
        }
        shadowStrengthScale = 1.0 / minRaitoVI;
    }

    int penumbraLength = penumbraIndex;
    int umbraLength = polyLength;

#if DEBUG_SHADOW
    ALOGD("penumbraLength is %d , allocatedPenumbraLength %d", penumbraLength,
          allocatedPenumbraLength);
    dumpPolygon(poly, polyLength, "input poly");
    dumpPolygon(penumbra, penumbraLength, "penumbra");
    dumpPolygon(umbra, umbraLength, "umbra");
    ALOGD("hasValidUmbra is %d and shadowStrengthScale is %f", hasValidUmbra, shadowStrengthScale);
#endif

    // The penumbra and umbra needs to be in convex shape to keep consistency
    // and quality.
    // Since we are still shooting rays to penumbra, it needs to be convex.
    // Umbra can be represented as a fan from the centroid, but visually umbra
    // looks nicer when it is convex.
    Vector2 finalUmbra[umbraLength];
    Vector2 finalPenumbra[penumbraLength];
    int finalUmbraLength = hull(umbra, umbraLength, finalUmbra);
    int finalPenumbraLength = hull(penumbra, penumbraLength, finalPenumbra);

    generateTriangleStrip(isCasterOpaque, shadowStrengthScale, finalPenumbra, finalPenumbraLength,
                          finalUmbra, finalUmbraLength, poly, polyLength, shadowTriangleStrip,
                          outlineCentroid);
}

/**
 * This is only for experimental purpose.
 * After intersections are calculated, we could smooth the polygon if needed.
 * So far, we don't think it is more appealing yet.
 *
 * @param level The level of smoothness.
 * @param rays The total number of rays.
 * @param rayDist (In and Out) The distance for each ray.
 *
 */
void SpotShadow::smoothPolygon(int level, int rays, float* rayDist) {
    for (int k = 0; k < level; k++) {
        for (int i = 0; i < rays; i++) {
            float p1 = rayDist[(rays - 1 + i) % rays];
            float p2 = rayDist[i];
            float p3 = rayDist[(i + 1) % rays];
            rayDist[i] = (p1 + p2 * 2 + p3) / 4;
        }
    }
}

// Index pair is meant for storing the tessellation information for the penumbra
// area. One index must come from exterior tangent of the circles, the other one
// must come from the interior tangent of the circles.
struct IndexPair {
    int outerIndex;
    int innerIndex;
};

// For one penumbra vertex, find the cloest umbra vertex and return its index.
inline int getClosestUmbraIndex(const Vector2& pivot, const Vector2* polygon, int polygonLength) {
    float minLengthSquared = FLT_MAX;
    int resultIndex = -1;
    bool hasDecreased = false;
    // Starting with some negative offset, assuming both umbra and penumbra are starting
    // at the same angle, this can help to find the result faster.
    // Normally, loop 3 times, we can find the closest point.
    int offset = polygonLength - 2;
    for (int i = 0; i < polygonLength; i++) {
        int currentIndex = (i + offset) % polygonLength;
        float currentLengthSquared = (pivot - polygon[currentIndex]).lengthSquared();
        if (currentLengthSquared < minLengthSquared) {
            if (minLengthSquared != FLT_MAX) {
                hasDecreased = true;
            }
            minLengthSquared = currentLengthSquared;
            resultIndex = currentIndex;
        } else if (currentLengthSquared > minLengthSquared && hasDecreased) {
            // Early break b/c we have found the closet one and now the length
            // is increasing again.
            break;
        }
    }
    if (resultIndex == -1) {
        ALOGE("resultIndex is -1, the polygon must be invalid!");
        resultIndex = 0;
    }
    return resultIndex;
}

// Allow some epsilon here since the later ray intersection did allow for some small
// floating point error, when the intersection point is slightly outside the segment.
inline bool sameDirections(bool isPositiveCross, float a, float b) {
    if (isPositiveCross) {
        return a >= -EPSILON && b >= -EPSILON;
    } else {
        return a <= EPSILON && b <= EPSILON;
    }
}

// Find the right polygon edge to shoot the ray at.
inline int findPolyIndex(bool isPositiveCross, int startPolyIndex, const Vector2& umbraDir,
                         const Vector2* polyToCentroid, int polyLength) {
    // Make sure we loop with a bound.
    for (int i = 0; i < polyLength; i++) {
        int currentIndex = (i + startPolyIndex) % polyLength;
        const Vector2& currentToCentroid = polyToCentroid[currentIndex];
        const Vector2& nextToCentroid = polyToCentroid[(currentIndex + 1) % polyLength];

        float currentCrossUmbra = currentToCentroid.cross(umbraDir);
        float umbraCrossNext = umbraDir.cross(nextToCentroid);
        if (sameDirections(isPositiveCross, currentCrossUmbra, umbraCrossNext)) {
#if DEBUG_SHADOW
            ALOGD("findPolyIndex loop %d times , index %d", i, currentIndex);
#endif
            return currentIndex;
        }
    }
    LOG_ALWAYS_FATAL("Can't find the right polygon's edge from startPolyIndex %d", startPolyIndex);
    return -1;
}

// Generate the index pair for penumbra / umbra vertices, and more penumbra vertices
// if needed.
inline void genNewPenumbraAndPairWithUmbra(const Vector2* penumbra, int penumbraLength,
                                           const Vector2* umbra, int umbraLength,
                                           Vector2* newPenumbra, int& newPenumbraIndex,
                                           IndexPair* verticesPair, int& verticesPairIndex) {
    // In order to keep everything in just one loop, we need to pre-compute the
    // closest umbra vertex for the last penumbra vertex.
    int previousClosestUmbraIndex =
            getClosestUmbraIndex(penumbra[penumbraLength - 1], umbra, umbraLength);
    for (int i = 0; i < penumbraLength; i++) {
        const Vector2& currentPenumbraVertex = penumbra[i];
        // For current penumbra vertex, starting from previousClosestUmbraIndex,
        // then check the next one until the distance increase.
        // The last one before the increase is the umbra vertex we need to pair with.
        float currentLengthSquared =
                (currentPenumbraVertex - umbra[previousClosestUmbraIndex]).lengthSquared();
        int currentClosestUmbraIndex = previousClosestUmbraIndex;
        int indexDelta = 0;
        for (int j = 1; j < umbraLength; j++) {
            int newUmbraIndex = (previousClosestUmbraIndex + j) % umbraLength;
            float newLengthSquared = (currentPenumbraVertex - umbra[newUmbraIndex]).lengthSquared();
            if (newLengthSquared > currentLengthSquared) {
                // currentClosestUmbraIndex is the umbra vertex's index which has
                // currently found smallest distance, so we can simply break here.
                break;
            } else {
                currentLengthSquared = newLengthSquared;
                indexDelta++;
                currentClosestUmbraIndex = newUmbraIndex;
            }
        }

        if (indexDelta > 1) {
            // For those umbra don't have  penumbra, generate new penumbra vertices by
            // interpolation.
            //
            // Assuming Pi for penumbra vertices, and Ui for umbra vertices.
            // In the case like below P1 paired with U1 and P2 paired with  U5.
            // U2 to U4 are unpaired umbra vertices.
            //
            // P1                                        P2
            // |                                          |
            // U1     U2                   U3     U4     U5
            //
            // We will need to generate 3 more penumbra vertices P1.1, P1.2, P1.3
            // to pair with U2 to U4.
            //
            // P1     P1.1                P1.2   P1.3    P2
            // |       |                   |      |      |
            // U1     U2                   U3     U4     U5
            //
            // That distance ratio b/t Ui to U1 and Ui to U5 decides its paired penumbra
            // vertex's location.
            int newPenumbraNumber = indexDelta - 1;

            float accumulatedDeltaLength[indexDelta];
            float totalDeltaLength = 0;

            // To save time, cache the previous umbra vertex info outside the loop
            // and update each loop.
            Vector2 previousClosestUmbra = umbra[previousClosestUmbraIndex];
            Vector2 skippedUmbra;
            // Use umbra data to precompute the length b/t unpaired umbra vertices,
            // and its ratio against the total length.
            for (int k = 0; k < indexDelta; k++) {
                int skippedUmbraIndex = (previousClosestUmbraIndex + k + 1) % umbraLength;
                skippedUmbra = umbra[skippedUmbraIndex];
                float currentDeltaLength = (skippedUmbra - previousClosestUmbra).length();

                totalDeltaLength += currentDeltaLength;
                accumulatedDeltaLength[k] = totalDeltaLength;

                previousClosestUmbra = skippedUmbra;
            }

            const Vector2& previousPenumbra = penumbra[(i + penumbraLength - 1) % penumbraLength];
            // Then for each unpaired umbra vertex, create a new penumbra by the ratio,
            // and pair them togehter.
            for (int k = 0; k < newPenumbraNumber; k++) {
                float weightForCurrentPenumbra = 1.0f;
                if (totalDeltaLength != 0.0f) {
                    weightForCurrentPenumbra = accumulatedDeltaLength[k] / totalDeltaLength;
                }
                float weightForPreviousPenumbra = 1.0f - weightForCurrentPenumbra;

                Vector2 interpolatedPenumbra = currentPenumbraVertex * weightForCurrentPenumbra +
                                               previousPenumbra * weightForPreviousPenumbra;

                int skippedUmbraIndex = (previousClosestUmbraIndex + k + 1) % umbraLength;
                verticesPair[verticesPairIndex].outerIndex = newPenumbraIndex;
                verticesPair[verticesPairIndex].innerIndex = skippedUmbraIndex;
                verticesPairIndex++;
                newPenumbra[newPenumbraIndex++] = interpolatedPenumbra;
            }
        }
        verticesPair[verticesPairIndex].outerIndex = newPenumbraIndex;
        verticesPair[verticesPairIndex].innerIndex = currentClosestUmbraIndex;
        verticesPairIndex++;
        newPenumbra[newPenumbraIndex++] = currentPenumbraVertex;

        previousClosestUmbraIndex = currentClosestUmbraIndex;
    }
}

// Precompute all the polygon's vector, return true if the reference cross product is positive.
inline bool genPolyToCentroid(const Vector2* poly2d, int polyLength, const Vector2& centroid,
                              Vector2* polyToCentroid) {
    for (int j = 0; j < polyLength; j++) {
        polyToCentroid[j] = poly2d[j] - centroid;
        // Normalize these vectors such that we can use epsilon comparison after
        // computing their cross products with another normalized vector.
        polyToCentroid[j].normalize();
    }
    float refCrossProduct = 0;
    for (int j = 0; j < polyLength; j++) {
        refCrossProduct = polyToCentroid[j].cross(polyToCentroid[(j + 1) % polyLength]);
        if (refCrossProduct != 0) {
            break;
        }
    }

    return refCrossProduct > 0;
}

// For one umbra vertex, shoot an ray from centroid to it.
// If the ray hit the polygon first, then return the intersection point as the
// closer vertex.
inline Vector2 getCloserVertex(const Vector2& umbraVertex, const Vector2& centroid,
                               const Vector2* poly2d, int polyLength, const Vector2* polyToCentroid,
                               bool isPositiveCross, int& previousPolyIndex) {
    Vector2 umbraToCentroid = umbraVertex - centroid;
    float distanceToUmbra = umbraToCentroid.length();
    umbraToCentroid = umbraToCentroid / distanceToUmbra;

    // previousPolyIndex is updated for each item such that we can minimize the
    // looping inside findPolyIndex();
    previousPolyIndex = findPolyIndex(isPositiveCross, previousPolyIndex, umbraToCentroid,
                                      polyToCentroid, polyLength);

    float dx = umbraToCentroid.x;
    float dy = umbraToCentroid.y;
    float distanceToIntersectPoly =
            rayIntersectPoints(centroid, dx, dy, poly2d[previousPolyIndex],
                               poly2d[(previousPolyIndex + 1) % polyLength]);
    if (distanceToIntersectPoly < 0) {
        distanceToIntersectPoly = 0;
    }

    // Pick the closer one as the occluded area vertex.
    Vector2 closerVertex;
    if (distanceToIntersectPoly < distanceToUmbra) {
        closerVertex.x = centroid.x + dx * distanceToIntersectPoly;
        closerVertex.y = centroid.y + dy * distanceToIntersectPoly;
    } else {
        closerVertex = umbraVertex;
    }

    return closerVertex;
}

/**
 * Generate a triangle strip given two convex polygon
**/
void SpotShadow::generateTriangleStrip(bool isCasterOpaque, float shadowStrengthScale,
                                       Vector2* penumbra, int penumbraLength, Vector2* umbra,
                                       int umbraLength, const Vector3* poly, int polyLength,
                                       VertexBuffer& shadowTriangleStrip, const Vector2& centroid) {
    bool hasOccludedUmbraArea = false;
    Vector2 poly2d[polyLength];

    if (isCasterOpaque) {
        for (int i = 0; i < polyLength; i++) {
            poly2d[i].x = poly[i].x;
            poly2d[i].y = poly[i].y;
        }
        // Make sure the centroid is inside the umbra, otherwise, fall back to the
        // approach as if there is no occluded umbra area.
        if (testPointInsidePolygon(centroid, poly2d, polyLength)) {
            hasOccludedUmbraArea = true;
        }
    }

    // For each penumbra vertex, find its corresponding closest umbra vertex index.
    //
    // Penumbra Vertices marked as Pi
    // Umbra Vertices marked as Ui
    //                                            (P3)
    //          (P2)                               |     ' (P4)
    //   (P1)'   |                                 |   '
    //         ' |                                 | '
    // (P0)  ------------------------------------------------(P5)
    //           | (U0)                            |(U1)
    //           |                                 |
    //           |                                 |(U2)     (P5.1)
    //           |                                 |
    //           |                                 |
    //           |                                 |
    //           |                                 |
    //           |                                 |
    //           |                                 |
    //       (U4)-----------------------------------(U3)      (P6)
    //
    // At least, like P0, P1, P2, they will find the matching umbra as U0.
    // If we jump over some umbra vertex without matching penumbra vertex, then
    // we will generate some new penumbra vertex by interpolation. Like P6 is
    // matching U3, but U2 is not matched with any penumbra vertex.
    // So interpolate P5.1 out and match U2.
    // In this way, every umbra vertex will have a matching penumbra vertex.
    //
    // The total pair number can be as high as umbraLength + penumbraLength.
    const int maxNewPenumbraLength = umbraLength + penumbraLength;
    IndexPair verticesPair[maxNewPenumbraLength];
    int verticesPairIndex = 0;

    // Cache all the existing penumbra vertices and newly interpolated vertices into a
    // a new array.
    Vector2 newPenumbra[maxNewPenumbraLength];
    int newPenumbraIndex = 0;

    // For each penumbra vertex, find its closet umbra vertex by comparing the
    // neighbor umbra vertices.
    genNewPenumbraAndPairWithUmbra(penumbra, penumbraLength, umbra, umbraLength, newPenumbra,
                                   newPenumbraIndex, verticesPair, verticesPairIndex);
    ShadowTessellator::checkOverflow(verticesPairIndex, maxNewPenumbraLength, "Spot pair");
    ShadowTessellator::checkOverflow(newPenumbraIndex, maxNewPenumbraLength, "Spot new penumbra");
#if DEBUG_SHADOW
    for (int i = 0; i < umbraLength; i++) {
        ALOGD("umbra i %d,  [%f, %f]", i, umbra[i].x, umbra[i].y);
    }
    for (int i = 0; i < newPenumbraIndex; i++) {
        ALOGD("new penumbra i %d,  [%f, %f]", i, newPenumbra[i].x, newPenumbra[i].y);
    }
    for (int i = 0; i < verticesPairIndex; i++) {
        ALOGD("index i %d,  [%d, %d]", i, verticesPair[i].outerIndex, verticesPair[i].innerIndex);
    }
#endif

    // For the size of vertex buffer, we need 3 rings, one has newPenumbraSize,
    // one has umbraLength, the last one has at most umbraLength.
    //
    // For the size of index buffer, the umbra area needs (2 * umbraLength + 2).
    // The penumbra one can vary a bit, but it is bounded by (2 * verticesPairIndex + 2).
    // And 2 more for jumping between penumbra to umbra.
    const int newPenumbraLength = newPenumbraIndex;
    const int totalVertexCount = newPenumbraLength + umbraLength * 2;
    const int totalIndexCount = 2 * umbraLength + 2 * verticesPairIndex + 6;
    AlphaVertex* shadowVertices = shadowTriangleStrip.alloc<AlphaVertex>(totalVertexCount);
    uint16_t* indexBuffer = shadowTriangleStrip.allocIndices<uint16_t>(totalIndexCount);
    int vertexBufferIndex = 0;
    int indexBufferIndex = 0;

    // Fill the IB and VB for the penumbra area.
    for (int i = 0; i < newPenumbraLength; i++) {
        AlphaVertex::set(&shadowVertices[vertexBufferIndex++], newPenumbra[i].x, newPenumbra[i].y,
                         PENUMBRA_ALPHA);
    }
    // Since the umbra can be a faked one when the occluder is too high, the umbra should be lighter
    // in this case.
    float scaledUmbraAlpha = UMBRA_ALPHA * shadowStrengthScale;

    for (int i = 0; i < umbraLength; i++) {
        AlphaVertex::set(&shadowVertices[vertexBufferIndex++], umbra[i].x, umbra[i].y,
                         scaledUmbraAlpha);
    }

    for (int i = 0; i < verticesPairIndex; i++) {
        indexBuffer[indexBufferIndex++] = verticesPair[i].outerIndex;
        // All umbra index need to be offseted by newPenumbraSize.
        indexBuffer[indexBufferIndex++] = verticesPair[i].innerIndex + newPenumbraLength;
    }
    indexBuffer[indexBufferIndex++] = verticesPair[0].outerIndex;
    indexBuffer[indexBufferIndex++] = verticesPair[0].innerIndex + newPenumbraLength;

    // Now fill the IB and VB for the umbra area.
    // First duplicated the index from previous strip and the first one for the
    // degenerated triangles.
    indexBuffer[indexBufferIndex] = indexBuffer[indexBufferIndex - 1];
    indexBufferIndex++;
    indexBuffer[indexBufferIndex++] = newPenumbraLength + 0;
    // Save the first VB index for umbra area in order to close the loop.
    int savedStartIndex = vertexBufferIndex;

    if (hasOccludedUmbraArea) {
        // Precompute all the polygon's vector, and the reference cross product,
        // in order to find the right polygon edge for the ray to intersect.
        Vector2 polyToCentroid[polyLength];
        bool isPositiveCross = genPolyToCentroid(poly2d, polyLength, centroid, polyToCentroid);

        // Because both the umbra and polygon are going in the same direction,
        // we can save the previous polygon index to make sure we have less polygon
        // vertex to compute for each ray.
        int previousPolyIndex = 0;
        for (int i = 0; i < umbraLength; i++) {
            // Shoot a ray from centroid to each umbra vertices and pick the one with
            // shorter distance to the centroid, b/t the umbra vertex or the intersection point.
            Vector2 closerVertex =
                    getCloserVertex(umbra[i], centroid, poly2d, polyLength, polyToCentroid,
                                    isPositiveCross, previousPolyIndex);

            // We already stored the umbra vertices, just need to add the occlued umbra's ones.
            indexBuffer[indexBufferIndex++] = newPenumbraLength + i;
            indexBuffer[indexBufferIndex++] = vertexBufferIndex;
            AlphaVertex::set(&shadowVertices[vertexBufferIndex++], closerVertex.x, closerVertex.y,
                             scaledUmbraAlpha);
        }
    } else {
        // If there is no occluded umbra at all, then draw the triangle fan
        // starting from the centroid to all umbra vertices.
        int lastCentroidIndex = vertexBufferIndex;
        AlphaVertex::set(&shadowVertices[vertexBufferIndex++], centroid.x, centroid.y,
                         scaledUmbraAlpha);
        for (int i = 0; i < umbraLength; i++) {
            indexBuffer[indexBufferIndex++] = newPenumbraLength + i;
            indexBuffer[indexBufferIndex++] = lastCentroidIndex;
        }
    }
    // Closing the umbra area triangle's loop here.
    indexBuffer[indexBufferIndex++] = newPenumbraLength;
    indexBuffer[indexBufferIndex++] = savedStartIndex;

    // At the end, update the real index and vertex buffer size.
    shadowTriangleStrip.updateVertexCount(vertexBufferIndex);
    shadowTriangleStrip.updateIndexCount(indexBufferIndex);
    ShadowTessellator::checkOverflow(vertexBufferIndex, totalVertexCount, "Spot Vertex Buffer");
    ShadowTessellator::checkOverflow(indexBufferIndex, totalIndexCount, "Spot Index Buffer");

    shadowTriangleStrip.setMeshFeatureFlags(VertexBuffer::kAlpha | VertexBuffer::kIndices);
    shadowTriangleStrip.computeBounds<AlphaVertex>();
}

#if DEBUG_SHADOW

#define TEST_POINT_NUMBER 128
/**
 * Calculate the bounds for generating random test points.
 */
void SpotShadow::updateBound(const Vector2 inVector, Vector2& lowerBound, Vector2& upperBound) {
    if (inVector.x < lowerBound.x) {
        lowerBound.x = inVector.x;
    }

    if (inVector.y < lowerBound.y) {
        lowerBound.y = inVector.y;
    }

    if (inVector.x > upperBound.x) {
        upperBound.x = inVector.x;
    }

    if (inVector.y > upperBound.y) {
        upperBound.y = inVector.y;
    }
}

/**
 * For debug purpose, when things go wrong, dump the whole polygon data.
 */
void SpotShadow::dumpPolygon(const Vector2* poly, int polyLength, const char* polyName) {
    for (int i = 0; i < polyLength; i++) {
        ALOGD("polygon %s i %d x %f y %f", polyName, i, poly[i].x, poly[i].y);
    }
}

/**
 * For debug purpose, when things go wrong, dump the whole polygon data.
 */
void SpotShadow::dumpPolygon(const Vector3* poly, int polyLength, const char* polyName) {
    for (int i = 0; i < polyLength; i++) {
        ALOGD("polygon %s i %d x %f y %f z %f", polyName, i, poly[i].x, poly[i].y, poly[i].z);
    }
}

/**
 * Test whether the polygon is convex.
 */
bool SpotShadow::testConvex(const Vector2* polygon, int polygonLength, const char* name) {
    bool isConvex = true;
    for (int i = 0; i < polygonLength; i++) {
        Vector2 start = polygon[i];
        Vector2 middle = polygon[(i + 1) % polygonLength];
        Vector2 end = polygon[(i + 2) % polygonLength];

        float delta = (float(middle.x) - start.x) * (float(end.y) - start.y) -
                      (float(middle.y) - start.y) * (float(end.x) - start.x);
        bool isCCWOrCoLinear = (delta >= EPSILON);

        if (isCCWOrCoLinear) {
            ALOGW("(Error Type 2): polygon (%s) is not a convex b/c start (x %f, y %f),"
                  "middle (x %f, y %f) and end (x %f, y %f) , delta is %f !!!",
                  name, start.x, start.y, middle.x, middle.y, end.x, end.y, delta);
            isConvex = false;
            break;
        }
    }
    return isConvex;
}

/**
 * Test whether or not the polygon (intersection) is within the 2 input polygons.
 * Using Marte Carlo method, we generate a random point, and if it is inside the
 * intersection, then it must be inside both source polygons.
 */
void SpotShadow::testIntersection(const Vector2* poly1, int poly1Length, const Vector2* poly2,
                                  int poly2Length, const Vector2* intersection,
                                  int intersectionLength) {
    // Find the min and max of x and y.
    Vector2 lowerBound = {FLT_MAX, FLT_MAX};
    Vector2 upperBound = {-FLT_MAX, -FLT_MAX};
    for (int i = 0; i < poly1Length; i++) {
        updateBound(poly1[i], lowerBound, upperBound);
    }
    for (int i = 0; i < poly2Length; i++) {
        updateBound(poly2[i], lowerBound, upperBound);
    }

    bool dumpPoly = false;
    for (int k = 0; k < TEST_POINT_NUMBER; k++) {
        // Generate a random point between minX, minY and maxX, maxY.
        float randomX = rand() / float(RAND_MAX);
        float randomY = rand() / float(RAND_MAX);

        Vector2 testPoint;
        testPoint.x = lowerBound.x + randomX * (upperBound.x - lowerBound.x);
        testPoint.y = lowerBound.y + randomY * (upperBound.y - lowerBound.y);

        // If the random point is in both poly 1 and 2, then it must be intersection.
        if (testPointInsidePolygon(testPoint, intersection, intersectionLength)) {
            if (!testPointInsidePolygon(testPoint, poly1, poly1Length)) {
                dumpPoly = true;
                ALOGW("(Error Type 1): one point (%f, %f) in the intersection is"
                      " not in the poly1",
                      testPoint.x, testPoint.y);
            }

            if (!testPointInsidePolygon(testPoint, poly2, poly2Length)) {
                dumpPoly = true;
                ALOGW("(Error Type 1): one point (%f, %f) in the intersection is"
                      " not in the poly2",
                      testPoint.x, testPoint.y);
            }
        }
    }

    if (dumpPoly) {
        dumpPolygon(intersection, intersectionLength, "intersection");
        for (int i = 1; i < intersectionLength; i++) {
            Vector2 delta = intersection[i] - intersection[i - 1];
            ALOGD("Intersetion i, %d Vs i-1 is delta %f", i, delta.lengthSquared());
        }

        dumpPolygon(poly1, poly1Length, "poly 1");
        dumpPolygon(poly2, poly2Length, "poly 2");
    }
}
#endif

};  // namespace uirenderer
};  // namespace android
