/*
 * 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.
 */

#define LOG_TAG "OpenGLRenderer"

// 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)

// For performance, we use (1 - alpha) value for the shader input.
#define TRANSFORMED_PENUMBRA_ALPHA 1.0f
#define TRANSFORMED_UMBRA_ALPHA 0.0f

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

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

// 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;
}

/**
 * Make the polygon turn clockwise.
 *
 * @param polygon the polygon as a Vector2 array.
 * @param len the number of points of the polygon
 */
void SpotShadow::makeClockwise(Vector2* polygon, int len) {
    if (polygon == nullptr  || len == 0) {
        return;
    }
    if (!ShadowTessellator::isClockwise(polygon, len)) {
        reverse(polygon, len);
    }
}

/**
 * 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 = MathUtils::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[newPenumbraNumber];
            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, TRANSFORMED_PENUMBRA_ALPHA);
    }
    for (int i = 0; i < umbraLength; i++) {
        AlphaVertex::set(&shadowVertices[vertexBufferIndex++], umbra[i].x, umbra[i].y,
                TRANSFORMED_UMBRA_ALPHA);
    }

    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, TRANSFORMED_UMBRA_ALPHA);
        }
    } 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, TRANSFORMED_UMBRA_ALPHA);
        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
