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

//--------------------------------------------------------------------------------
// GLContext.cpp
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
// includes
//--------------------------------------------------------------------------------
#include <unistd.h>
#include "GLContext.h"
#include "gl3stub.h"

namespace ndk_helper
{

//--------------------------------------------------------------------------------
// eGLContext
//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
// Ctor
//--------------------------------------------------------------------------------
GLContext::GLContext() :
                display_( EGL_NO_DISPLAY ),
                surface_( EGL_NO_SURFACE ),
                context_( EGL_NO_CONTEXT ),
                screen_width_( 0 ),
                screen_height_( 0 ),
                es3_supported_( false ),
                egl_context_initialized_( false ),
                gles_initialized_( false )
{
}

void GLContext::InitGLES()
{
    if( gles_initialized_ )
        return;
    //
    //Initialize OpenGL ES 3 if available
    //
    const char* versionStr = (const char*) glGetString( GL_VERSION );
    if( strstr( versionStr, "OpenGL ES 3." ) && gl3stubInit() )
    {
        es3_supported_ = true;
        gl_version_ = 3.0f;
    }
    else
    {
        gl_version_ = 2.0f;
    }

    gles_initialized_ = true;
}

//--------------------------------------------------------------------------------
// Dtor
//--------------------------------------------------------------------------------
GLContext::~GLContext()
{
    Terminate();
}

bool GLContext::Init( ANativeWindow* window )
{
    if( egl_context_initialized_ )
        return true;

    //
    //Initialize EGL
    //
    window_ = window;
    InitEGLSurface();
    InitEGLContext();
    InitGLES();

    egl_context_initialized_ = true;

    return true;
}

bool GLContext::InitEGLSurface()
{
    display_ = eglGetDisplay( EGL_DEFAULT_DISPLAY );
    eglInitialize( display_, 0, 0 );

    /*
     * Here specify the attributes of the desired configuration.
     * Below, we select an EGLConfig with at least 8 bits per color
     * component compatible with on-screen windows
     */
    const EGLint attribs[] = { EGL_RENDERABLE_TYPE,
            EGL_OPENGL_ES2_BIT, //Request opengl ES2.0
            EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8,
            EGL_RED_SIZE, 8, EGL_DEPTH_SIZE, 24, EGL_NONE };
    color_size_ = 8;
    depth_size_ = 24;

    EGLint num_configs;
    eglChooseConfig( display_, attribs, &config_, 1, &num_configs );

    if( !num_configs )
    {
        //Fall back to 16bit depth buffer
        const EGLint attribs[] = { EGL_RENDERABLE_TYPE,
                EGL_OPENGL_ES2_BIT, //Request opengl ES2.0
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8,
                EGL_RED_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_NONE };
        eglChooseConfig( display_, attribs, &config_, 1, &num_configs );
        depth_size_ = 16;
    }

    if( !num_configs )
    {
        LOGW( "Unable to retrieve EGL config" );
        return false;
    }

    surface_ = eglCreateWindowSurface( display_, config_, window_, NULL );
    eglQuerySurface( display_, surface_, EGL_WIDTH, &screen_width_ );
    eglQuerySurface( display_, surface_, EGL_HEIGHT, &screen_height_ );

    return true;
}

bool GLContext::InitEGLContext()
{
    const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, //Request opengl ES2.0
            EGL_NONE };
    context_ = eglCreateContext( display_, config_, NULL, context_attribs );

    if( eglMakeCurrent( display_, surface_, surface_, context_ ) == EGL_FALSE )
    {
        LOGW( "Unable to eglMakeCurrent" );
        return false;
    }

    context_valid_ = true;
    return true;
}

EGLint GLContext::Swap()
{
    bool b = eglSwapBuffers( display_, surface_ );
    if( !b )
    {
        EGLint err = eglGetError();
        if( err == EGL_BAD_SURFACE )
        {
            //Recreate surface
            InitEGLSurface();
            return EGL_SUCCESS; //Still consider glContext is valid
        }
        else if( err == EGL_CONTEXT_LOST || err == EGL_BAD_CONTEXT )
        {
            //Context has been lost!!
            context_valid_ = false;
            Terminate();
            InitEGLContext();
        }
        return err;
    }
    return EGL_SUCCESS;
}

void GLContext::Terminate()
{
    if( display_ != EGL_NO_DISPLAY )
    {
        eglMakeCurrent( display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
        if( context_ != EGL_NO_CONTEXT )
        {
            eglDestroyContext( display_, context_ );
        }

        if( surface_ != EGL_NO_SURFACE )
        {
            eglDestroySurface( display_, surface_ );
        }
        eglTerminate( display_ );
    }

    display_ = EGL_NO_DISPLAY;
    context_ = EGL_NO_CONTEXT;
    surface_ = EGL_NO_SURFACE;
    context_valid_ = false;

}

EGLint GLContext::Resume( ANativeWindow* window )
{
    if( egl_context_initialized_ == false )
    {
        Init( window );
        return EGL_SUCCESS;
    }

    int32_t original_widhth = screen_width_;
    int32_t original_height = screen_height_;

    //Create surface
    window_ = window;
    surface_ = eglCreateWindowSurface( display_, config_, window_, NULL );
    eglQuerySurface( display_, surface_, EGL_WIDTH, &screen_width_ );
    eglQuerySurface( display_, surface_, EGL_HEIGHT, &screen_height_ );

    if( screen_width_ != original_widhth || screen_height_ != original_height )
    {
        //Screen resized
        LOGI( "Screen resized" );
    }

    if( eglMakeCurrent( display_, surface_, surface_, context_ ) == EGL_TRUE )
        return EGL_SUCCESS;

    EGLint err = eglGetError();
    LOGW( "Unable to eglMakeCurrent %d", err );

    if( err == EGL_CONTEXT_LOST )
    {
        //Recreate context
        LOGI( "Re-creating egl context" );
        InitEGLContext();
    }
    else
    {
        //Recreate surface
        Terminate();
        InitEGLSurface();
        InitEGLContext();
    }

    return err;

}

void GLContext::Suspend()
{
    if( surface_ != EGL_NO_SURFACE )
    {
        eglDestroySurface( display_, surface_ );
        surface_ = EGL_NO_SURFACE;
    }
}

bool GLContext::Invalidate()
{
    Terminate();

    egl_context_initialized_ = false;
    return true;
}

bool GLContext::CheckExtension( const char* extension )
{
    if( extension == NULL )
        return false;

    std::string extensions = std::string( (char*) glGetString( GL_EXTENSIONS ) );
    std::string str = std::string( extension );
    str.append( " " );

    size_t pos = 0;
    if( extensions.find( extension, pos ) != std::string::npos )
    {
        return true;
    }

    return false;
}

}   //namespace ndkHelper
