// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/android/vr/arcore_device/fake_arcore.h"

#include "base/android/android_hardware_buffer_compat.h"
#include "base/numerics/math_constants.h"
#include "base/single_thread_task_runner.h"
#include "ui/display/display.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gl/gl_image_ahardwarebuffer.h"

namespace device {

FakeArCore::FakeArCore()
    : gl_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {}

FakeArCore::~FakeArCore() = default;

bool FakeArCore::Initialize(
    base::android::ScopedJavaLocalRef<jobject> application_context) {
  DCHECK(IsOnGlThread());
  return true;
}

void FakeArCore::SetDisplayGeometry(
    const gfx::Size& frame_size,
    display::Display::Rotation display_rotation) {
  DCHECK(IsOnGlThread());

  display_rotation_ = display_rotation;
  frame_size_ = frame_size;
}

void FakeArCore::SetCameraTexture(GLuint texture) {
  DCHECK(IsOnGlThread());
  // This is a no-op for the FakeArCore implementation. We might want to
  // store the textureid for use in unit tests, but currently ArCoreDeviceTest
  // is using mocked image transport so the actual texture doesn't have to
  // be set. Current approach won't work for tests that rely on the texture.

  DVLOG(2) << __FUNCTION__ << ": camera texture=" << texture;
}

std::vector<float> FakeArCore::TransformDisplayUvCoords(
    const base::span<const float> uvs) {
  // Try to match ArCore's transfore values.
  //
  // Sample ArCore input: width=1080, height=1795, rotation=0,
  // vecs = (0, 0), (0, 1), (1, 0), (1, 1)
  // Sample ArCore output:
  //   (0.0325544, 1,
  //    0.967446, 1,
  //    0.0325543, 0,
  //    0.967446, 1.19209e-07)
  //
  // FakeArCoreDriver test_arcore;
  // test_arcore.SetCameraAspect(16.f / 9.f);
  // test_arcore.SetDisplayGeometry(0, 1080, 1795);
  // float in[8] = {0, 0, 0, 1, 1, 0, 1, 1};
  // float out[8];
  // test_arcore.TransformDisplayUvCoords(8, &in[0], &out[0]);
  //
  // Fake driver result:
  // TransformDisplayUvCoords: too wide. v0=0.0325521 vrange=0.934896
  //    uv[0]=(0.0325521, 1)
  //    uv[2]=(0.967448, 1)
  //    uv[4]=(0.0325521, 0)
  //    uv[6]=(0.967448, 0)
  //
  // TODO(klausw): move this to a unittest.

  // SetDisplayGeometry should have been called first.
  DCHECK(frame_size_.width());
  DCHECK(frame_size_.height());

  // Do clipping calculations in orientation ROTATE_0. screen U is left=0,
  // right=1. Screen V is bottom=0, top=1. We'll apply screen rotation later.

  float display_aspect =
      static_cast<float>(frame_size_.width()) / frame_size_.height();
  float target_aspect = camera_aspect_;

  // Simulate that the fake camera is rotated by 90 degrees from the usual
  // convention to match the Pixel camera. If the screen is in portrait mode
  // (ROTATION_0), the camera's UV origin is around the bottom right of the
  // screen, with camera +u going left and camera +v going up on the screen. So
  // use the original camera aspect in landscape/seascape, and the inverse
  // for portrait/upside-down orientation.
  if (display_rotation_ == display::Display::Rotation::ROTATE_0 ||
      display_rotation_ == display::Display::Rotation::ROTATE_180) {
    target_aspect = 1.0f / target_aspect;
  }
  DVLOG(3) << __FUNCTION__ << ": rotation=" << display_rotation_
           << " frame_size_.width=" << frame_size_.width()
           << " frame_size_.height=" << frame_size_.height()
           << " display_aspect=" << display_aspect
           << " target_aspect=" << target_aspect;

  float u0 = 0;
  float v0 = 0;
  float urange = 1;
  float vrange = 1;

  if (display_aspect > target_aspect) {
    // Display too wide. Fill width, crop V evenly at top/bottom.
    vrange = target_aspect / display_aspect;
    v0 = (1.f - vrange) / 2;
    DVLOG(3) << ": too wide. v0=" << v0 << " vrange=" << vrange;
  } else {
    // Display too narrow. Fill height, crop U evenly at sides.
    urange = display_aspect / target_aspect;
    u0 = (1.f - urange) / 2;
    DVLOG(3) << ": too narrow. u0=" << u0 << " urange=" << urange;
  }

  size_t num_elements = uvs.size();
  DCHECK(num_elements % 2 == 0);
  std::vector<float> uvs_out;
  uvs_out.reserve(num_elements);
  for (size_t i = 0; i < num_elements; i += 2) {
    float x = uvs[i];
    float y = uvs[i + 1];
    float u, v;
    switch (display_rotation_) {
      case display::Display::Rotation::ROTATE_90:
        u = u0 + x * urange;
        v = v0 + y * vrange;
        break;
      case display::Display::Rotation::ROTATE_180:
        u = 1.f - (v0 + y * vrange);
        v = u0 + x * urange;
        break;
      case display::Display::Rotation::ROTATE_270:
        u = 1.f - (u0 + x * urange);
        v = 1.f - (v0 + y * vrange);
        break;
      case display::Display::Rotation::ROTATE_0:
        u = v0 + y * vrange;
        v = 1.f - (u0 + x * urange);
        break;
    }
    uvs_out.push_back(u);
    uvs_out.push_back(v);
    DVLOG(2) << __FUNCTION__ << ": uv[" << i << "]=(" << u << ", " << v << ")";
  }
  return uvs_out;
}

gfx::Transform FakeArCore::GetProjectionMatrix(float near, float far) {
  DCHECK(IsOnGlThread());
  // Get a projection matrix matching the current screen orientation and
  // aspect. Currently, this uses a hardcoded FOV angle for the smaller screen
  // dimension, and adjusts the other angle to preserve the aspect. A better
  // simulation of ArCore should apply cropping to the underlying fixed-aspect
  // simulated camera image.
  constexpr float fov_half_angle_degrees = 30.f;
  float base_tan = tanf(fov_half_angle_degrees * base::kPiFloat / 180.f);
  float right_tan;
  float up_tan;
  if (display_rotation_ == display::Display::Rotation::ROTATE_0 ||
      display_rotation_ == display::Display::Rotation::ROTATE_180) {
    // portrait aspect
    right_tan = base_tan;
    up_tan = base_tan * frame_size_.height() / frame_size_.width();
  } else {
    // landscape aspect
    up_tan = base_tan;
    right_tan = base_tan * frame_size_.width() / frame_size_.height();
  }
  // Calculate a perspective matrix based on the FOV values.
  gfx::Transform result;
  result.matrix().set(0, 0, 1.f / right_tan);
  result.matrix().set(1, 1, 1.f / up_tan);
  result.matrix().set(2, 2, (near + far) / (near - far));
  result.matrix().set(3, 2, -1.0f);
  result.matrix().set(2, 3, (2.0f * far * near) / (near - far));
  result.matrix().set(3, 3, 0.0f);
  return result;
}

mojom::VRPosePtr FakeArCore::Update(bool* camera_updated) {
  DCHECK(IsOnGlThread());
  DCHECK(camera_updated);

  *camera_updated = true;

  // 1m up from the origin, neutral orientation facing forward.
  mojom::VRPosePtr pose = mojom::VRPose::New();
  pose->orientation.emplace(4);
  pose->position.emplace(3);
  pose->position.value()[0] = 0;
  pose->position.value()[1] = 1;
  pose->position.value()[2] = 0;
  pose->orientation.value()[0] = 0;
  pose->orientation.value()[1] = 0;
  pose->orientation.value()[2] = 0;
  pose->orientation.value()[3] = 1;

  return pose;
}

bool FakeArCore::RequestHitTest(
    const mojom::XRRayPtr& ray,
    const gfx::Size& image_size,
    std::vector<mojom::XRHitResultPtr>* hit_results) {
  mojom::XRHitResultPtr hit = mojom::XRHitResult::New();
  hit->hit_matrix.resize(16);
  // Identity matrix - no translation and default orientation.
  hit->hit_matrix.data()[0] = 1;
  hit->hit_matrix.data()[5] = 1;
  hit->hit_matrix.data()[10] = 1;
  hit->hit_matrix.data()[15] = 1;
  hit_results->push_back(std::move(hit));

  return true;
}

void FakeArCore::Pause() {
  DCHECK(IsOnGlThread());
}

void FakeArCore::Resume() {
  DCHECK(IsOnGlThread());
}

bool FakeArCore::IsOnGlThread() const {
  return gl_thread_task_runner_->BelongsToCurrentThread();
}

std::unique_ptr<ArCore> FakeArCoreFactory::Create() {
  return std::make_unique<FakeArCore>();
}

}  // namespace device
