/*
 * libjingle
 * Copyright 2015 Google Inc.
 *
 * 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.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
 */

package org.webrtc;

import android.graphics.SurfaceTexture;
import android.view.Surface;

import org.webrtc.Logging;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;

/**
 * Holds EGL state and utility methods for handling an EGLContext, an EGLDisplay, and an EGLSurface.
 */
public final class EglBase {
  private static final String TAG = "EglBase";
  // These constants are taken from EGL14.EGL_OPENGL_ES2_BIT and EGL14.EGL_CONTEXT_CLIENT_VERSION.
  // https://android.googlesource.com/platform/frameworks/base/+/master/opengl/java/android/opengl/EGL14.java
  // This is similar to how GlSurfaceView does:
  // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/opengl/GLSurfaceView.java#760
  private static final int EGL_OPENGL_ES2_BIT = 4;
  private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
  // Android-specific extension.
  private static final int EGL_RECORDABLE_ANDROID = 0x3142;

  private final EGL10 egl;
  private EGLContext eglContext;
  private ConfigType configType;
  private EGLConfig eglConfig;
  private EGLDisplay eglDisplay;
  private EGLSurface eglSurface = EGL10.EGL_NO_SURFACE;

  // EGLConfig constructor type. Influences eglChooseConfig arguments.
  public static enum ConfigType {
    // No special parameters.
    PLAIN,
    // Configures with EGL_SURFACE_TYPE = EGL_PBUFFER_BIT.
    PIXEL_BUFFER,
    // Configures with EGL_RECORDABLE_ANDROID = 1.
    // Discourages EGL from using pixel formats that cannot efficiently be
    // converted to something usable by the video encoder.
    RECORDABLE
  }

  // Create root context without any EGLSurface or parent EGLContext. This can be used for branching
  // new contexts that share data.
  public EglBase() {
    this(EGL10.EGL_NO_CONTEXT, ConfigType.PLAIN);
  }

  // Create a new context with the specified config type, sharing data with sharedContext.
  public EglBase(EGLContext sharedContext, ConfigType configType) {
    this.egl = (EGL10) EGLContext.getEGL();
    this.configType = configType;
    eglDisplay = getEglDisplay();
    eglConfig = getEglConfig(eglDisplay, configType);
    eglContext = createEglContext(sharedContext, eglDisplay, eglConfig);
  }

  // Create EGLSurface from the Android Surface.
  public void createSurface(Surface surface) {
    createSurfaceInternal(surface);
  }

  // Create EGLSurface from the Android SurfaceTexture.
  public void createSurface(SurfaceTexture surfaceTexture) {
    createSurfaceInternal(surfaceTexture);
  }

  // Create EGLSurface from either Surface or SurfaceTexture.
  private void createSurfaceInternal(Object surface) {
    if (!(surface instanceof Surface) && !(surface instanceof SurfaceTexture)) {
      throw new IllegalStateException("Input must be either a Surface or SurfaceTexture");
    }
    checkIsNotReleased();
    if (configType == ConfigType.PIXEL_BUFFER) {
      Logging.w(TAG, "This EGL context is configured for PIXEL_BUFFER, but uses regular Surface");
    }
    if (eglSurface != EGL10.EGL_NO_SURFACE) {
      throw new RuntimeException("Already has an EGLSurface");
    }
    int[] surfaceAttribs = {EGL10.EGL_NONE};
    eglSurface = egl.eglCreateWindowSurface(eglDisplay, eglConfig, surface, surfaceAttribs);
    if (eglSurface == EGL10.EGL_NO_SURFACE) {
      throw new RuntimeException("Failed to create window surface");
    }
  }

  // Create dummy 1x1 pixel buffer surface so the context can be made current.
  public void createDummyPbufferSurface() {
    createPbufferSurface(1, 1);
  }

  public void createPbufferSurface(int width, int height) {
    checkIsNotReleased();
    if (configType != ConfigType.PIXEL_BUFFER) {
      throw new RuntimeException(
          "This EGL context is not configured to use a pixel buffer: " + configType);
    }
    if (eglSurface != EGL10.EGL_NO_SURFACE) {
      throw new RuntimeException("Already has an EGLSurface");
    }
    int[] surfaceAttribs = {EGL10.EGL_WIDTH, width, EGL10.EGL_HEIGHT, height, EGL10.EGL_NONE};
    eglSurface = egl.eglCreatePbufferSurface(eglDisplay, eglConfig, surfaceAttribs);
    if (eglSurface == EGL10.EGL_NO_SURFACE) {
      throw new RuntimeException("Failed to create pixel buffer surface");
    }
  }

  public EGLContext getContext() {
    return eglContext;
  }

  public boolean hasSurface() {
    return eglSurface != EGL10.EGL_NO_SURFACE;
  }

  public int surfaceWidth() {
    final int widthArray[] = new int[1];
    egl.eglQuerySurface(eglDisplay, eglSurface, EGL10.EGL_WIDTH, widthArray);
    return widthArray[0];
  }

  public int surfaceHeight() {
    final int heightArray[] = new int[1];
    egl.eglQuerySurface(eglDisplay, eglSurface, EGL10.EGL_HEIGHT, heightArray);
    return heightArray[0];
  }

  public void releaseSurface() {
    if (eglSurface != EGL10.EGL_NO_SURFACE) {
      egl.eglDestroySurface(eglDisplay, eglSurface);
      eglSurface = EGL10.EGL_NO_SURFACE;
    }
  }

  private void checkIsNotReleased() {
    if (eglDisplay == EGL10.EGL_NO_DISPLAY || eglContext == EGL10.EGL_NO_CONTEXT
        || eglConfig == null) {
      throw new RuntimeException("This object has been released");
    }
  }

  public void release() {
    checkIsNotReleased();
    releaseSurface();
    detachCurrent();
    egl.eglDestroyContext(eglDisplay, eglContext);
    egl.eglTerminate(eglDisplay);
    eglContext = EGL10.EGL_NO_CONTEXT;
    eglDisplay = EGL10.EGL_NO_DISPLAY;
    eglConfig = null;
  }

  public void makeCurrent() {
    checkIsNotReleased();
    if (eglSurface == EGL10.EGL_NO_SURFACE) {
      throw new RuntimeException("No EGLSurface - can't make current");
    }
    if (!egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
      throw new RuntimeException("eglMakeCurrent failed");
    }
  }

  // Detach the current EGL context, so that it can be made current on another thread.
  public void detachCurrent() {
    if (!egl.eglMakeCurrent(
        eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT)) {
      throw new RuntimeException("eglMakeCurrent failed");
    }
  }

  public void swapBuffers() {
    checkIsNotReleased();
    if (eglSurface == EGL10.EGL_NO_SURFACE) {
      throw new RuntimeException("No EGLSurface - can't swap buffers");
    }
    egl.eglSwapBuffers(eglDisplay, eglSurface);
  }

  // Return an EGLDisplay, or die trying.
  private EGLDisplay getEglDisplay() {
    EGLDisplay eglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
    if (eglDisplay == EGL10.EGL_NO_DISPLAY) {
      throw new RuntimeException("Unable to get EGL10 display");
    }
    int[] version = new int[2];
    if (!egl.eglInitialize(eglDisplay, version)) {
      throw new RuntimeException("Unable to initialize EGL10");
    }
    return eglDisplay;
  }

  // Return an EGLConfig, or die trying.
  private EGLConfig getEglConfig(EGLDisplay eglDisplay, ConfigType configType) {
    // Always RGB888, GLES2.
    int[] configAttributes = {
      EGL10.EGL_RED_SIZE, 8,
      EGL10.EGL_GREEN_SIZE, 8,
      EGL10.EGL_BLUE_SIZE, 8,
      EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
      EGL10.EGL_NONE, 0,  // Allocate dummy fields for specific options.
      EGL10.EGL_NONE
    };

    // Fill in dummy fields based on configType.
    switch (configType) {
      case PLAIN:
        break;
      case PIXEL_BUFFER:
        configAttributes[configAttributes.length - 3] = EGL10.EGL_SURFACE_TYPE;
        configAttributes[configAttributes.length - 2] = EGL10.EGL_PBUFFER_BIT;
        break;
      case RECORDABLE:
        configAttributes[configAttributes.length - 3] = EGL_RECORDABLE_ANDROID;
        configAttributes[configAttributes.length - 2] = 1;
        break;
      default:
        throw new IllegalArgumentException();
    }

    EGLConfig[] configs = new EGLConfig[1];
    int[] numConfigs = new int[1];
    if (!egl.eglChooseConfig(
        eglDisplay, configAttributes, configs, configs.length, numConfigs)) {
      throw new RuntimeException("Unable to find RGB888 " + configType + " EGL config");
    }
    return configs[0];
  }

  // Return an EGLConfig, or die trying.
  private EGLContext createEglContext(
      EGLContext sharedContext, EGLDisplay eglDisplay, EGLConfig eglConfig) {
    int[] contextAttributes = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
    EGLContext eglContext =
        egl.eglCreateContext(eglDisplay, eglConfig, sharedContext, contextAttributes);
    if (eglContext == EGL10.EGL_NO_CONTEXT) {
      throw new RuntimeException("Failed to create EGL context");
    }
    return eglContext;
  }
}
