//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

//            Based on Simple_VertexShader.c from
// Book:      OpenGL(R) ES 2.0 Programming Guide
// Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
// ISBN-10:   0321502795
// ISBN-13:   9780321502797
// Publisher: Addison-Wesley Professional
// URLs:      http://safari.informit.com/9780321563835
//            http://www.opengles-book.com

#include "SampleApplication.h"
#include "texture_utils.h"
#include "util/Matrix.h"
#include "util/geometry_utils.h"
#include "util/shader_utils.h"

#include <cmath>
#include <iostream>

class PostSubBufferSample : public SampleApplication
{
  public:
    PostSubBufferSample(int argc, char **argv) : SampleApplication("PostSubBuffer", argc, argv) {}

    bool initialize() override
    {
        mPostSubBufferNV = (PFNEGLPOSTSUBBUFFERNVPROC)eglGetProcAddress("eglPostSubBufferNV");
        if (!mPostSubBufferNV)
        {
            std::cerr << "Could not load eglPostSubBufferNV.";
            return false;
        }

        constexpr char kVS[] = R"(uniform mat4 u_mvpMatrix;
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
void main()
{
    gl_Position = u_mvpMatrix * a_position;
    v_texcoord = a_texcoord;
})";

        constexpr char kFS[] = R"(precision mediump float;
varying vec2 v_texcoord;
void main()
{
    gl_FragColor = vec4(v_texcoord.x, v_texcoord.y, 1.0, 1.0);
})";

        mProgram = CompileProgram(kVS, kFS);
        if (!mProgram)
        {
            return false;
        }

        // Get the attribute locations
        mPositionLoc = glGetAttribLocation(mProgram, "a_position");
        mTexcoordLoc = glGetAttribLocation(mProgram, "a_texcoord");

        // Get the uniform locations
        mMVPMatrixLoc = glGetUniformLocation(mProgram, "u_mvpMatrix");

        // Generate the geometry data
        GenerateCubeGeometry(0.5f, &mCube);

        // Set an initial rotation
        mRotation = 45.0f;

        // Clear the whole window surface to blue.
        glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        SampleApplication::swap();

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glCullFace(GL_BACK);
        glEnable(GL_CULL_FACE);

        return true;
    }

    void destroy() override { glDeleteProgram(mProgram); }

    void step(float dt, double totalTime) override
    {
        mRotation = fmod(mRotation + (dt * 40.0f), 360.0f);

        Matrix4 perspectiveMatrix = Matrix4::perspective(
            60.0f, float(getWindow()->getWidth()) / getWindow()->getHeight(), 1.0f, 20.0f);

        Matrix4 modelMatrix = Matrix4::translate(angle::Vector3(0.0f, 0.0f, -2.0f)) *
                              Matrix4::rotate(mRotation, angle::Vector3(1.0f, 0.0f, 1.0f));

        Matrix4 viewMatrix = Matrix4::identity();

        Matrix4 mvpMatrix = perspectiveMatrix * viewMatrix * modelMatrix;

        // Load the matrices
        glUniformMatrix4fv(mMVPMatrixLoc, 1, GL_FALSE, mvpMatrix.data);
    }

    void draw() override
    {
        // Set the viewport
        glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());

        // Clear the color buffer
        glClear(GL_COLOR_BUFFER_BIT);

        // Use the program object
        glUseProgram(mProgram);

        // Load the vertex position
        glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, mCube.positions.data());
        glEnableVertexAttribArray(mPositionLoc);

        // Load the texcoord data
        glVertexAttribPointer(mTexcoordLoc, 2, GL_FLOAT, GL_FALSE, 0, mCube.texcoords.data());
        glEnableVertexAttribArray(mTexcoordLoc);

        // Draw the cube
        glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mCube.indices.size()), GL_UNSIGNED_SHORT,
                       mCube.indices.data());
    }

    void swap() override
    {
        // Instead of letting the application call eglSwapBuffers, call eglPostSubBufferNV here
        // instead
        EGLint windowWidth  = static_cast<EGLint>(getWindow()->getWidth());
        EGLint windowHeight = static_cast<EGLint>(getWindow()->getHeight());
        EGLDisplay display  = getDisplay();
        EGLSurface surface  = getSurface();
        mPostSubBufferNV(display, surface, 60, 60, windowWidth - 120, windowHeight - 120);
    }

  private:
    // Handle to a program object
    GLuint mProgram;

    // Attribute locations
    GLint mPositionLoc;
    GLint mTexcoordLoc;

    // Uniform locations
    GLuint mMVPMatrixLoc;

    // Current rotation
    float mRotation;

    // Geometry data
    CubeGeometry mCube;

    // eglPostSubBufferNV entry point
    PFNEGLPOSTSUBBUFFERNVPROC mPostSubBufferNV;
};

int main(int argc, char **argv)
{
    PostSubBufferSample app(argc, argv);
    return app.run();
}
