/*
 * Copyright (C) 2015 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.
 */

#ifndef ANDROID_HWUI_GLOP_H
#define ANDROID_HWUI_GLOP_H

#include "FloatColor.h"
#include "Matrix.h"
#include "Program.h"
#include "Rect.h"
#include "SkiaShader.h"
#include "utils/Macros.h"

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <SkXfermode.h>

namespace android {
namespace uirenderer {

class Program;
class RoundRectClipState;
class Texture;

/*
 * Enumerates optional vertex attributes
 *
 * Position is always enabled by MeshState, these other attributes
 * are enabled/disabled dynamically based on mesh content.
 */

namespace VertexAttribFlags {
    enum {
        None = 0,
        TextureCoord = 1 << 0,
        Color = 1 << 1,
        Alpha = 1 << 2,
    };
};

/*
 * Enumerates transform features
 */
namespace TransformFlags {
    enum {
        None = 0,

        // offset the eventual drawing matrix by a tiny amount to
        // disambiguate sampling patterns with non-AA rendering
        OffsetByFudgeFactor = 1 << 0,

        // Canvas transform isn't applied to the mesh at draw time,
        //since it's already built in.
        MeshIgnoresCanvasTransform = 1 << 1,
    };
};

/**
 * Structure containing all data required to issue an OpenGL draw
 *
 * Includes all of the mesh, fill, and GL state required to perform
 * the operation. Pieces of data are either directly copied into the
 * structure, or stored as a pointer or GL object reference to data
 * managed.
 *
 * Eventually, a Glop should be able to be drawn multiple times from
 * a single construction, up until GL context destruction. Currently,
 * vertex/index/Texture/RoundRectClipState pointers prevent this from
 * being safe.
 */
// TODO: PREVENT_COPY_AND_ASSIGN(...) or similar
struct Glop {
    struct Mesh {
        GLuint primitiveMode; // GL_TRIANGLES and GL_TRIANGLE_STRIP supported

        // buffer object and void* are mutually exclusive.
        // Only GL_UNSIGNED_SHORT supported.
        struct Indices {
            GLuint bufferObject;
            const void* indices;
        } indices;

        // buffer object and void*s are mutually exclusive.
        // TODO: enforce mutual exclusion with restricted setters and/or unions
        struct Vertices {
            GLuint bufferObject;
            int attribFlags;
            const void* position;
            const void* texCoord;
            const void* color;
            GLsizei stride;
        } vertices;

        int elementCount;
        TextureVertex mappedVertices[4];
    } mesh;

    struct Fill {
        Program* program;

        struct TextureData {
            Texture* texture;
            GLenum target;
            GLenum filter;
            GLenum clamp;
            Matrix4* textureTransform;
        } texture;

        bool colorEnabled;
        FloatColor color;

        ProgramDescription::ColorFilterMode filterMode;
        union Filter {
            struct Matrix {
                float matrix[16];
                float vector[4];
            } matrix;
            FloatColor color;
        } filter;

        SkiaShaderData skiaShaderData;
    } fill;

    struct Transform {
        // Orthographic projection matrix for current FBO
        // TODO: move out of Glop, since this is static per FBO
        Matrix4 ortho;

        // modelView transform, accounting for delta between mesh transform and content of the mesh
        // often represents x/y offsets within command, or scaling for mesh unit size
        Matrix4 modelView;

        // Canvas transform of Glop - not necessarily applied to geometry (see flags)
        Matrix4 canvas;
        int transformFlags;

       const Matrix4& meshTransform() const {
           return (transformFlags & TransformFlags::MeshIgnoresCanvasTransform)
                   ? Matrix4::identity() : canvas;
       }
    } transform;

    const RoundRectClipState* roundRectClipState;

    /**
     * Blending to be used by this draw - both GL_NONE if blending is disabled.
     *
     * Defined by fill step, but can be force-enabled by presence of kAlpha_Attrib
     */
    struct Blend {
        GLenum src;
        GLenum dst;
    } blend;

    /**
     * Bounds of the drawing command in layer space. Only mapped into layer
     * space once GlopBuilder::build() is called.
     */
    Rect bounds;

    /**
     * Additional render state to enumerate:
     * - scissor + (bits for whether each of LTRB needed?)
     * - stencil mode (draw into, mask, count, etc)
     */
};

} /* namespace uirenderer */
} /* namespace android */

#endif // ANDROID_HWUI_GLOP_H
