/*
 *  Copyright 2017 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.Matrix;
import android.os.Handler;
import android.support.annotation.Nullable;

/**
 * Android texture buffer that glues together the necessary information together with a generic
 * release callback. ToI420() is implemented by providing a Handler and a YuvConverter.
 */
public class TextureBufferImpl implements VideoFrame.TextureBuffer {
  interface RefCountMonitor {
    void onRetain(TextureBufferImpl textureBuffer);
    void onRelease(TextureBufferImpl textureBuffer);
    void onDestroy(TextureBufferImpl textureBuffer);
  }

  // This is the full resolution the texture has in memory after applying the transformation matrix
  // that might include cropping. This resolution is useful to know when sampling the texture to
  // avoid downscaling artifacts.
  private final int unscaledWidth;
  private final int unscaledHeight;
  // This is the resolution that has been applied after cropAndScale().
  private final int width;
  private final int height;
  private final Type type;
  private final int id;
  private final Matrix transformMatrix;
  private final Handler toI420Handler;
  private final YuvConverter yuvConverter;
  private final RefCountDelegate refCountDelegate;
  private final RefCountMonitor refCountMonitor;

  public TextureBufferImpl(int width, int height, Type type, int id, Matrix transformMatrix,
      Handler toI420Handler, YuvConverter yuvConverter, @Nullable Runnable releaseCallback) {
    this(width, height, width, height, type, id, transformMatrix, toI420Handler, yuvConverter,
        new RefCountMonitor() {
          @Override
          public void onRetain(TextureBufferImpl textureBuffer) {}

          @Override
          public void onRelease(TextureBufferImpl textureBuffer) {}

          @Override
          public void onDestroy(TextureBufferImpl textureBuffer) {
            if (releaseCallback != null) {
              releaseCallback.run();
            }
          }
        });
  }

  TextureBufferImpl(int width, int height, Type type, int id, Matrix transformMatrix,
      Handler toI420Handler, YuvConverter yuvConverter, RefCountMonitor refCountMonitor) {
    this(width, height, width, height, type, id, transformMatrix, toI420Handler, yuvConverter,
        refCountMonitor);
  }

  private TextureBufferImpl(int unscaledWidth, int unscaledHeight, int width, int height, Type type,
      int id, Matrix transformMatrix, Handler toI420Handler, YuvConverter yuvConverter,
      RefCountMonitor refCountMonitor) {
    this.unscaledWidth = unscaledWidth;
    this.unscaledHeight = unscaledHeight;
    this.width = width;
    this.height = height;
    this.type = type;
    this.id = id;
    this.transformMatrix = transformMatrix;
    this.toI420Handler = toI420Handler;
    this.yuvConverter = yuvConverter;
    this.refCountDelegate = new RefCountDelegate(() -> refCountMonitor.onDestroy(this));
    this.refCountMonitor = refCountMonitor;
  }

  @Override
  public VideoFrame.TextureBuffer.Type getType() {
    return type;
  }

  @Override
  public int getTextureId() {
    return id;
  }

  @Override
  public Matrix getTransformMatrix() {
    return transformMatrix;
  }

  @Override
  public int getWidth() {
    return width;
  }

  @Override
  public int getHeight() {
    return height;
  }

  @Override
  public VideoFrame.I420Buffer toI420() {
    return ThreadUtils.invokeAtFrontUninterruptibly(
        toI420Handler, () -> yuvConverter.convert(this));
  }

  @Override
  public void retain() {
    refCountMonitor.onRetain(this);
    refCountDelegate.retain();
  }

  @Override
  public void release() {
    refCountMonitor.onRelease(this);
    refCountDelegate.release();
  }

  @Override
  public VideoFrame.Buffer cropAndScale(
      int cropX, int cropY, int cropWidth, int cropHeight, int scaleWidth, int scaleHeight) {
    final Matrix cropAndScaleMatrix = new Matrix();
    // In WebRTC, Y=0 is the top row, while in OpenGL Y=0 is the bottom row. This means that the Y
    // direction is effectively reversed.
    final int cropYFromBottom = height - (cropY + cropHeight);
    cropAndScaleMatrix.preTranslate(cropX / (float) width, cropYFromBottom / (float) height);
    cropAndScaleMatrix.preScale(cropWidth / (float) width, cropHeight / (float) height);

    return applyTransformMatrix(cropAndScaleMatrix,
        (int) Math.round(unscaledWidth * cropWidth / (float) width),
        (int) Math.round(unscaledHeight * cropHeight / (float) height), scaleWidth, scaleHeight);
  }

  /**
   * Returns the width of the texture in memory. This should only be used for downscaling, and you
   * should still respect the width from getWidth().
   */
  public int getUnscaledWidth() {
    return unscaledWidth;
  }

  /**
   * Returns the height of the texture in memory. This should only be used for downscaling, and you
   * should still respect the height from getHeight().
   */
  public int getUnscaledHeight() {
    return unscaledHeight;
  }

  public Handler getToI420Handler() {
    return toI420Handler;
  }

  public YuvConverter getYuvConverter() {
    return yuvConverter;
  }

  /**
   * Create a new TextureBufferImpl with an applied transform matrix and a new size. The
   * existing buffer is unchanged. The given transform matrix is applied first when texture
   * coordinates are still in the unmodified [0, 1] range.
   */
  public TextureBufferImpl applyTransformMatrix(
      Matrix transformMatrix, int newWidth, int newHeight) {
    return applyTransformMatrix(transformMatrix, /* unscaledWidth= */ newWidth,
        /* unscaledHeight= */ newHeight, /* scaledWidth= */ newWidth,
        /* scaledHeight= */ newHeight);
  }

  private TextureBufferImpl applyTransformMatrix(Matrix transformMatrix, int unscaledWidth,
      int unscaledHeight, int scaledWidth, int scaledHeight) {
    final Matrix newMatrix = new Matrix(this.transformMatrix);
    newMatrix.preConcat(transformMatrix);
    retain();
    return new TextureBufferImpl(unscaledWidth, unscaledHeight, scaledWidth, scaledHeight, type, id,
        newMatrix, toI420Handler, yuvConverter, new RefCountMonitor() {
          @Override
          public void onRetain(TextureBufferImpl textureBuffer) {
            refCountMonitor.onRetain(TextureBufferImpl.this);
          }

          @Override
          public void onRelease(TextureBufferImpl textureBuffer) {
            refCountMonitor.onRelease(TextureBufferImpl.this);
          }

          @Override
          public void onDestroy(TextureBufferImpl textureBuffer) {
            release();
          }
        });
  }
}
