/*
 * Copyright (C) 2013 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"

#include <math.h>
#include <utils/Log.h>
#include <utils/Vector.h>

#include "AmbientShadow.h"
#include "ShadowTessellator.h"
#include "Vertex.h"

namespace android {
namespace uirenderer {

/**
 * Calculate the shadows as a triangle strips while alpha value as the
 * shadow values.
 *
 * @param isCasterOpaque Whether the caster is opaque.
 * @param vertices The shadow caster's polygon, which is represented in a Vector3
 *                  array.
 * @param vertexCount The length of caster's polygon in terms of number of
 *                    vertices.
 * @param centroid3d The centroid of the shadow caster.
 * @param heightFactor The factor showing the higher the object, the lighter the
 *                     shadow.
 * @param geomFactor The factor scaling the geometry expansion along the normal.
 *
 * @param shadowVertexBuffer Return an floating point array of (x, y, a)
 *               triangle strips mode.
 */
void AmbientShadow::createAmbientShadow(bool isCasterOpaque,
        const Vector3* vertices, int vertexCount, const Vector3& centroid3d,
        float heightFactor, float geomFactor, VertexBuffer& shadowVertexBuffer) {
    const int rays = SHADOW_RAY_COUNT;
    // Validate the inputs.
    if (vertexCount < 3 || heightFactor <= 0 || rays <= 0
        || geomFactor <= 0) {
#if DEBUG_SHADOW
        ALOGW("Invalid input for createAmbientShadow(), early return!");
#endif
        return;
    }

    Vector<Vector2> dir; // TODO: use C++11 unique_ptr
    dir.setCapacity(rays);
    float rayDist[rays];
    float rayHeight[rays];
    calculateRayDirections(rays, vertices, vertexCount, centroid3d, dir.editArray());

    // Calculate the length and height of the points along the edge.
    //
    // The math here is:
    // Intersect each ray (starting from the centroid) with the polygon.
    for (int i = 0; i < rays; i++) {
        int edgeIndex;
        float edgeFraction;
        float rayDistance;
        calculateIntersection(vertices, vertexCount, centroid3d, dir[i], edgeIndex,
                edgeFraction, rayDistance);
        rayDist[i] = rayDistance;
        if (edgeIndex < 0 || edgeIndex >= vertexCount) {
#if DEBUG_SHADOW
            ALOGW("Invalid edgeIndex!");
#endif
            edgeIndex = 0;
        }
        float h1 = vertices[edgeIndex].z;
        float h2 = vertices[((edgeIndex + 1) % vertexCount)].z;
        rayHeight[i] = h1 + edgeFraction * (h2 - h1);
    }

    // The output buffer length basically is roughly rays * layers, but since we
    // need triangle strips, so we need to duplicate vertices to accomplish that.
    AlphaVertex* shadowVertices =
            shadowVertexBuffer.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT);

    // Calculate the vertex of the shadows.
    //
    // The math here is:
    // Along the edges of the polygon, for each intersection point P (generated above),
    // calculate the normal N, which should be perpendicular to the edge of the
    // polygon (represented by the neighbor intersection points) .
    // Shadow's vertices will be generated as : P + N * scale.
    const Vector2 centroid2d = Vector2(centroid3d.x, centroid3d.y);
    for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
        Vector2 normal(1.0f, 0.0f);
        calculateNormal(rays, rayIndex, dir.array(), rayDist, normal);

        // The vertex should be start from rayDist[i] then scale the
        // normalizeNormal!
        Vector2 intersection = dir[rayIndex] * rayDist[rayIndex] +
                centroid2d;

        // outer ring of points, expanded based upon height of each ray intersection
        float expansionDist = rayHeight[rayIndex] * heightFactor *
                geomFactor;
        AlphaVertex::set(&shadowVertices[rayIndex],
                intersection.x + normal.x * expansionDist,
                intersection.y + normal.y * expansionDist,
                0.0f);

        // inner ring of points
        float opacity = 1.0 / (1 + rayHeight[rayIndex] * heightFactor);
        AlphaVertex::set(&shadowVertices[rays + rayIndex],
                intersection.x,
                intersection.y,
                opacity);
    }

    if (isCasterOpaque) {
        // skip inner ring, calc bounds over filled portion of buffer
        shadowVertexBuffer.computeBounds<AlphaVertex>(2 * rays);
        shadowVertexBuffer.setMode(VertexBuffer::kOnePolyRingShadow);
    } else {
        // If caster isn't opaque, we need to to fill the umbra by storing the umbra's
        // centroid in the innermost ring of vertices.
        float centroidAlpha = 1.0 / (1 + centroid3d.z * heightFactor);
        AlphaVertex centroidXYA;
        AlphaVertex::set(&centroidXYA, centroid2d.x, centroid2d.y, centroidAlpha);
        for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
            shadowVertices[2 * rays + rayIndex] = centroidXYA;
        }
        // calc bounds over entire buffer
        shadowVertexBuffer.computeBounds<AlphaVertex>();
        shadowVertexBuffer.setMode(VertexBuffer::kTwoPolyRingShadow);
    }

#if DEBUG_SHADOW
    for (int i = 0; i < SHADOW_VERTEX_COUNT; i++) {
        ALOGD("ambient shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x,
                shadowVertices[i].y, shadowVertices[i].alpha);
    }
#endif
}

/**
 * Generate an array of rays' direction vectors.
 * To make sure the vertices generated are clockwise, the directions are from PI
 * to -PI.
 *
 * @param rays The number of rays shooting out from the centroid.
 * @param vertices Vertices of the polygon.
 * @param vertexCount The number of vertices.
 * @param centroid3d The centroid of the polygon.
 * @param dir Return the array of ray vectors.
 */
void AmbientShadow::calculateRayDirections(const int rays, const Vector3* vertices,
        const int vertexCount, const Vector3& centroid3d, Vector2* dir) {
    // If we don't have enough rays, then fall back to the uniform distribution.
    if (vertexCount * 2 > rays) {
        float deltaAngle = 2 * M_PI / rays;
        for (int i = 0; i < rays; i++) {
            dir[i].x = cosf(M_PI - deltaAngle * i);
            dir[i].y = sinf(M_PI - deltaAngle * i);
        }
        return;
    }

    // If we have enough rays, then we assign each vertices a ray, and distribute
    // the rest uniformly.
    float rayThetas[rays];

    const int uniformRayCount = rays - vertexCount;
    const float deltaAngle = 2 * M_PI / uniformRayCount;

    // We have to generate all the vertices' theta anyway and we also need to
    // find the minimal, so let's precompute it first.
    // Since the incoming polygon is clockwise, we can find the dip to identify
    // the minimal theta.
    float polyThetas[vertexCount];
    int maxPolyThetaIndex = 0;
    for (int i = 0; i < vertexCount; i++) {
        polyThetas[i] = atan2(vertices[i].y - centroid3d.y,
                vertices[i].x - centroid3d.x);
        if (i > 0 && polyThetas[i] > polyThetas[i - 1]) {
            maxPolyThetaIndex = i;
        }
    }

    // Both poly's thetas and uniform thetas are in decrease order(clockwise)
    // from PI to -PI.
    int polyThetaIndex = maxPolyThetaIndex;
    float polyTheta = polyThetas[maxPolyThetaIndex];
    int uniformThetaIndex = 0;
    float uniformTheta = M_PI;
    for (int i = 0; i < rays; i++) {
        // Compare both thetas and pick the smaller one and move on.
        bool hasThetaCollision = abs(polyTheta - uniformTheta) < MINIMAL_DELTA_THETA;
        if (polyTheta > uniformTheta || hasThetaCollision) {
            if (hasThetaCollision) {
                // Shift the uniformTheta to middle way between current polyTheta
                // and next uniform theta. The next uniform theta can wrap around
                // to exactly PI safely here.
                // Note that neither polyTheta nor uniformTheta can be FLT_MAX
                // due to the hasThetaCollision is true.
                uniformTheta = (polyTheta +  M_PI - deltaAngle * (uniformThetaIndex + 1)) / 2;
#if DEBUG_SHADOW
                ALOGD("Shifted uniformTheta to %f", uniformTheta);
#endif
            }
            rayThetas[i] = polyTheta;
            polyThetaIndex = (polyThetaIndex + 1) % vertexCount;
            if (polyThetaIndex != maxPolyThetaIndex) {
                polyTheta = polyThetas[polyThetaIndex];
            } else {
                // out of poly points.
                polyTheta = - FLT_MAX;
            }
        } else {
            rayThetas[i] = uniformTheta;
            uniformThetaIndex++;
            if (uniformThetaIndex < uniformRayCount) {
                uniformTheta = M_PI - deltaAngle * uniformThetaIndex;
            } else {
                // out of uniform points.
                uniformTheta = - FLT_MAX;
            }
        }
    }

    for (int i = 0; i < rays; i++) {
#if DEBUG_SHADOW
        ALOGD("No. %d : %f", i, rayThetas[i] * 180 / M_PI);
#endif
        // TODO: Fix the intersection precision problem and remvoe the delta added
        // here.
        dir[i].x = cosf(rayThetas[i] + MINIMAL_DELTA_THETA);
        dir[i].y = sinf(rayThetas[i] + MINIMAL_DELTA_THETA);
    }
}

/**
 * Calculate the intersection of a ray hitting the polygon.
 *
 * @param vertices The shadow caster's polygon, which is represented in a
 *                 Vector3 array.
 * @param vertexCount The length of caster's polygon in terms of number of vertices.
 * @param start The starting point of the ray.
 * @param dir The direction vector of the ray.
 *
 * @param outEdgeIndex Return the index of the segment (or index of the starting
 *                     vertex) that ray intersect with.
 * @param outEdgeFraction Return the fraction offset from the segment starting
 *                        index.
 * @param outRayDist Return the ray distance from centroid to the intersection.
 */
void AmbientShadow::calculateIntersection(const Vector3* vertices, int vertexCount,
        const Vector3& start, const Vector2& dir, int& outEdgeIndex,
        float& outEdgeFraction, float& outRayDist) {
    float startX = start.x;
    float startY = start.y;
    float dirX = dir.x;
    float dirY = dir.y;
    // Start the search from the last edge from poly[len-1] to poly[0].
    int p1 = vertexCount - 1;

    for (int p2 = 0; p2 < vertexCount; p2++) {
        float p1x = vertices[p1].x;
        float p1y = vertices[p1].y;
        float p2x = vertices[p2].x;
        float p2y = vertices[p2].y;

        // The math here is derived from:
        // f(t, v) = p1x * (1 - t) + p2x * t - (startX + dirX * v) = 0;
        // g(t, v) = p1y * (1 - t) + p2y * t - (startY + dirY * v) = 0;
        float div = (dirX * (p1y - p2y) + dirY * p2x - dirY * p1x);
        if (div != 0) {
            float t = (dirX * (p1y - startY) + dirY * startX - dirY * p1x) / (div);
            if (t > 0 && t <= 1) {
                float t2 = (p1x * (startY - p2y)
                            + p2x * (p1y - startY)
                            + startX * (p2y - p1y)) / div;
                if (t2 > 0) {
                    outEdgeIndex = p1;
                    outRayDist = t2;
                    outEdgeFraction = t;
                    return;
                }
            }
        }
        p1 = p2;
    }
    return;
};

/**
 * Calculate the normal at the intersection point between a ray and the polygon.
 *
 * @param rays The total number of rays.
 * @param currentRayIndex The index of the ray which the normal is based on.
 * @param dir The array of the all the rays directions.
 * @param rayDist The pre-computed ray distances array.
 *
 * @param normal Return the normal.
 */
void AmbientShadow::calculateNormal(int rays, int currentRayIndex,
        const Vector2* dir, const float* rayDist, Vector2& normal) {
    int preIndex = (currentRayIndex - 1 + rays) % rays;
    int postIndex = (currentRayIndex + 1) % rays;
    Vector2 p1 = dir[preIndex] * rayDist[preIndex];
    Vector2 p2 = dir[postIndex] * rayDist[postIndex];

    // Now the rays are going CW around the poly.
    Vector2 delta = p2 - p1;
    if (delta.length() != 0) {
        delta.normalize();
        // Calculate the normal , which is CCW 90 rotate to the delta.
        normal.x = - delta.y;
        normal.y = delta.x;
    }
}

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