/*
 *  Copyright 2015 The WebRTC 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 in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.webrtc;

import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.view.Surface;
import android.view.SurfaceHolder;

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 egl 1.0 EGLContext, an EGLDisplay,
 * and an EGLSurface.
 */
public final class EglBase10 extends EglBase {
  // This constant is taken from EGL14.EGL_CONTEXT_CLIENT_VERSION.
  private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;

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

  // EGL wrapper for an actual EGLContext.
  public static class Context extends EglBase.Context {
    private final EGLContext eglContext;

    public Context(EGLContext eglContext) {
      this.eglContext = eglContext;
    }
  }

  // Create a new context with the specified config type, sharing data with sharedContext.
  public EglBase10(Context sharedContext, int[] configAttributes) {
    this.egl = (EGL10) EGLContext.getEGL();
    eglDisplay = getEglDisplay();
    eglConfig = getEglConfig(eglDisplay, configAttributes);
    eglContext = createEglContext(sharedContext, eglDisplay, eglConfig);
  }

  @Override
  public void createSurface(Surface surface) {
    /**
     * We have to wrap Surface in a SurfaceHolder because for some reason eglCreateWindowSurface
     * couldn't actually take a Surface object until API 17. Older versions fortunately just call
     * SurfaceHolder.getSurface(), so we'll do that. No other methods are relevant.
     */
    class FakeSurfaceHolder implements SurfaceHolder {
      private final Surface surface;

      FakeSurfaceHolder(Surface surface) {
        this.surface = surface;
      }

      @Override
      public void addCallback(Callback callback) {}

      @Override
      public void removeCallback(Callback callback) {}

      @Override
      public boolean isCreating() {
        return false;
      }

      @Deprecated
      @Override
      public void setType(int i) {}

      @Override
      public void setFixedSize(int i, int i2) {}

      @Override
      public void setSizeFromLayout() {}

      @Override
      public void setFormat(int i) {}

      @Override
      public void setKeepScreenOn(boolean b) {}

      @Override
      public Canvas lockCanvas() {
        return null;
      }

      @Override
      public Canvas lockCanvas(Rect rect) {
        return null;
      }

      @Override
      public void unlockCanvasAndPost(Canvas canvas) {}

      @Override
      public Rect getSurfaceFrame() {
        return null;
      }

      @Override
      public Surface getSurface() {
        return surface;
      }
    }

    createSurfaceInternal(new FakeSurfaceHolder(surface));
  }

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

  // Create EGLSurface from either a SurfaceHolder or a SurfaceTexture.
  private void createSurfaceInternal(Object nativeWindow) {
    if (!(nativeWindow instanceof SurfaceHolder) && !(nativeWindow instanceof SurfaceTexture)) {
      throw new IllegalStateException("Input must be either a SurfaceHolder or SurfaceTexture");
    }
    checkIsNotReleased();
    if (eglSurface != EGL10.EGL_NO_SURFACE) {
      throw new RuntimeException("Already has an EGLSurface");
    }
    int[] surfaceAttribs = {EGL10.EGL_NONE};
    eglSurface = egl.eglCreateWindowSurface(eglDisplay, eglConfig, nativeWindow, surfaceAttribs);
    if (eglSurface == EGL10.EGL_NO_SURFACE) {
      throw new RuntimeException(
          "Failed to create window surface: 0x" + Integer.toHexString(egl.eglGetError()));
    }
  }

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

  @Override
  public void createPbufferSurface(int width, int height) {
    checkIsNotReleased();
    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 with size " + width + "x" + height
          + ": 0x" + Integer.toHexString(egl.eglGetError()));
    }
  }

  @Override
  public org.webrtc.EglBase.Context getEglBaseContext() {
    return new EglBase10.Context(eglContext);
  }

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

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

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

  @Override
  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");
    }
  }

  @Override
  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;
  }

  @Override
  public void makeCurrent() {
    checkIsNotReleased();
    if (eglSurface == EGL10.EGL_NO_SURFACE) {
      throw new RuntimeException("No EGLSurface - can't make current");
    }
    synchronized (EglBase.lock) {
      if (!egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
        throw new RuntimeException(
            "eglMakeCurrent failed: 0x" + Integer.toHexString(egl.eglGetError()));
      }
    }
  }

  // Detach the current EGL context, so that it can be made current on another thread.
  @Override
  public void detachCurrent() {
    synchronized (EglBase.lock) {
      if (!egl.eglMakeCurrent(
          eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT)) {
        throw new RuntimeException(
            "eglDetachCurrent failed: 0x" + Integer.toHexString(egl.eglGetError()));
      }
    }
  }

  @Override
  public void swapBuffers() {
    checkIsNotReleased();
    if (eglSurface == EGL10.EGL_NO_SURFACE) {
      throw new RuntimeException("No EGLSurface - can't swap buffers");
    }
    synchronized (EglBase.lock) {
      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: 0x" + Integer.toHexString(egl.eglGetError()));
    }
    int[] version = new int[2];
    if (!egl.eglInitialize(eglDisplay, version)) {
      throw new RuntimeException(
          "Unable to initialize EGL10: 0x" + Integer.toHexString(egl.eglGetError()));
    }
    return eglDisplay;
  }

  // Return an EGLConfig, or die trying.
  private EGLConfig getEglConfig(EGLDisplay eglDisplay, int[] configAttributes) {
    EGLConfig[] configs = new EGLConfig[1];
    int[] numConfigs = new int[1];
    if (!egl.eglChooseConfig(
        eglDisplay, configAttributes, configs, configs.length, numConfigs)) {
      throw new RuntimeException(
          "eglChooseConfig failed: 0x" + Integer.toHexString(egl.eglGetError()));
    }
    if (numConfigs[0] <= 0) {
      throw new RuntimeException("Unable to find any matching EGL config");
    }
    final EGLConfig eglConfig = configs[0];
    if (eglConfig == null) {
      throw new RuntimeException("eglChooseConfig returned null");
    }
    return eglConfig;
  }

  // Return an EGLConfig, or die trying.
  private EGLContext createEglContext(
      Context sharedContext, EGLDisplay eglDisplay, EGLConfig eglConfig) {
    if (sharedContext != null && sharedContext.eglContext == EGL10.EGL_NO_CONTEXT) {
      throw new RuntimeException("Invalid sharedContext");
    }
    int[] contextAttributes = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
    EGLContext rootContext =
        sharedContext == null ? EGL10.EGL_NO_CONTEXT : sharedContext.eglContext;
    final EGLContext eglContext;
    synchronized (EglBase.lock) {
      eglContext = egl.eglCreateContext(eglDisplay, eglConfig, rootContext, contextAttributes);
    }
    if (eglContext == EGL10.EGL_NO_CONTEXT) {
      throw new RuntimeException(
          "Failed to create EGL context: 0x" + Integer.toHexString(egl.eglGetError()));
    }
    return eglContext;
  }
}
