/*
 * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer.
 * 2. Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer in the documentation and/or other materials
 *    provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "config.h"
#include "platform/graphics/filters/custom/CustomFilterMeshGenerator.h"

#ifndef NDEBUG
#include <stdio.h> // Needed for printf used in dumpBuffers.
#endif

namespace WebCore {

#ifndef NDEBUG
// Use "call 'WebCore::s_dumpCustomFilterMeshBuffers' = 1" in GDB to activate printing of the mesh buffers.
static bool s_dumpCustomFilterMeshBuffers = false;
#endif

CustomFilterMeshGenerator::CustomFilterMeshGenerator(unsigned columns, unsigned rows, const FloatRect& meshBox, CustomFilterMeshType meshType)
    : m_meshType(meshType)
    , m_points(columns + 1, rows + 1)
    , m_tiles(columns, rows)
    , m_tileSizeInPixels(meshBox.width() / m_tiles.width(), meshBox.height() / m_tiles.height())
    , m_tileSizeInDeviceSpace(1.0f / m_tiles.width(), 1.0f / m_tiles.height())
    , m_meshBox(meshBox)
{
    // Build the two buffers needed to draw triangles:
    // * m_vertices has a number of float attributes that will be passed to the vertex shader
    // for each computed vertex. This number is calculated in floatsPerVertex() based on the meshType.
    // * m_indices is a buffer that will have 3 indices per triangle. Each index will point inside
    // the m_vertices buffer.
    m_vertices.reserveCapacity(verticesCount() * floatsPerVertex());
    m_indices.reserveCapacity(indicesCount());

    // Based on the meshType there can be two types of meshes.
    // * attached: each triangle uses vertices from the neighbor triangles. This is useful to save some GPU memory
    // when there's no need to explode the tiles.
    // * detached: each triangle has its own vertices. This means each triangle can be moved independently and a vec3
    // attribute is passed, so that each vertex can be uniquely identified.
    if (m_meshType == MeshTypeAttached)
        generateAttachedMesh();
    else
        generateDetachedMesh();

#ifndef NDEBUG
    if (s_dumpCustomFilterMeshBuffers)
        dumpBuffers();
#endif
}

void CustomFilterMeshGenerator::addAttachedMeshIndex(int quadX, int quadY, int triangleX, int triangleY, int)
{
    m_indices.append((quadY + triangleY) * m_points.width() + (quadX + triangleX));
}

void CustomFilterMeshGenerator::generateAttachedMesh()
{
    for (int j = 0; j < m_points.height(); ++j) {
        for (int i = 0; i < m_points.width(); ++i)
            addAttachedMeshVertexAttributes(i, j);
    }

    for (int j = 0; j < m_tiles.height(); ++j) {
        for (int i = 0; i < m_tiles.width(); ++i)
            addTile<&CustomFilterMeshGenerator::addAttachedMeshIndex>(i, j);
    }
}

void CustomFilterMeshGenerator::addDetachedMeshVertexAndIndex(int quadX, int quadY, int triangleX, int triangleY, int triangle)
{
    addDetachedMeshVertexAttributes(quadX, quadY, triangleX, triangleY, triangle);
    m_indices.append(m_indices.size());
}

void CustomFilterMeshGenerator::generateDetachedMesh()
{
    for (int j = 0; j < m_tiles.height(); ++j) {
        for (int i = 0; i < m_tiles.width(); ++i)
            addTile<&CustomFilterMeshGenerator::addDetachedMeshVertexAndIndex>(i, j);
    }
}

void CustomFilterMeshGenerator::addPositionAttribute(int quadX, int quadY)
{
    // vec4 a_position
    m_vertices.append(m_tileSizeInPixels.width() * quadX - 0.5f + m_meshBox.x());
    m_vertices.append(m_tileSizeInPixels.height() * quadY - 0.5f + m_meshBox.y());
    m_vertices.append(0.0f); // z
    m_vertices.append(1.0f);
}

void CustomFilterMeshGenerator::addTexCoordAttribute(int quadX, int quadY)
{
    // vec2 a_texCoord
    m_vertices.append(m_tileSizeInPixels.width() * quadX + m_meshBox.x());
    m_vertices.append(m_tileSizeInPixels.height() * quadY + m_meshBox.y());
}

void CustomFilterMeshGenerator::addMeshCoordAttribute(int quadX, int quadY)
{
    // vec2 a_meshCoord
    m_vertices.append(m_tileSizeInDeviceSpace.width() * quadX);
    m_vertices.append(m_tileSizeInDeviceSpace.height() * quadY);
}

void CustomFilterMeshGenerator::addTriangleCoordAttribute(int quadX, int quadY, int triangle)
{
    // vec3 a_triangleCoord
    m_vertices.append(quadX);
    m_vertices.append(quadY);
    m_vertices.append(triangle);
}

void CustomFilterMeshGenerator::addAttachedMeshVertexAttributes(int quadX, int quadY)
{
    addPositionAttribute(quadX, quadY);
    addTexCoordAttribute(quadX, quadY);
    addMeshCoordAttribute(quadX, quadY);
}

void CustomFilterMeshGenerator::addDetachedMeshVertexAttributes(int quadX, int quadY, int triangleX, int triangleY, int triangle)
{
    addAttachedMeshVertexAttributes(quadX + triangleX, quadY + triangleY);
    addTriangleCoordAttribute(quadX, quadY, triangle);
}

#ifndef NDEBUG
void CustomFilterMeshGenerator::dumpBuffers() const
{
    printf("Mesh buffers: Points.width(): %d, Points.height(): %d meshBox: %f, %f, %f, %f, type: %s\n",
        m_points.width(), m_points.height(), m_meshBox.x(), m_meshBox.y(), m_meshBox.width(), m_meshBox.height(),
        (m_meshType == MeshTypeAttached) ? "Attached" : "Detached");
    printf("---Vertex:\n\t");
    for (unsigned i = 0; i < m_vertices.size(); ++i) {
        printf("%f ", m_vertices.at(i));
        if (!((i + 1) % floatsPerVertex()))
            printf("\n\t");
    }
    printf("\n---Indices: ");
    for (unsigned i = 0; i < m_indices.size(); ++i)
        printf("%d ", m_indices.at(i));
    printf("\n");
}
#endif

} // namespace WebCore
