/*
 *  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 javax.annotation.Nullable;
import android.os.Handler;

/**
 * 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 {
  // 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;

  public TextureBufferImpl(int width, int height, Type type, int id, Matrix transformMatrix,
      Handler toI420Handler, YuvConverter yuvConverter, @Nullable Runnable releaseCallback) {
    this.unscaledWidth = width;
    this.unscaledHeight = height;
    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(releaseCallback);
  }

  private TextureBufferImpl(int unscaledWidth, int unscaledHeight, int width, int height, Type type,
      int id, Matrix transformMatrix, Handler toI420Handler, YuvConverter yuvConverter,
      @Nullable Runnable releaseCallback) {
    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(releaseCallback);
  }

  @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() {
    refCountDelegate.retain();
  }

  @Override
  public void release() {
    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;
  }

  /**
   * 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, this ::release);
  }
}
