/* Copyright 2018 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef HELLOVRBETA_APP_SRC_MAIN_JNI_HELLO_VR_BETA_APP_H_  // NOLINT
#define HELLOVRBETA_APP_SRC_MAIN_JNI_HELLO_VR_BETA_APP_H_  // NOLINT

#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <android/asset_manager.h>
#include <jni.h>

#include <memory>
#include <string>
#include <thread>  // NOLINT
#include <vector>

#include "controllers.h"  // NOLINT
#include "shader_program.h"  // NOLINT
#include "util.h"  // NOLINT
#include "vr/gvr/capi/include/gvr.h"
#include "vr/gvr/capi/include/gvr_audio.h"
#include "vr/gvr/capi/include/gvr_controller.h"
#include "vr/gvr/capi/include/gvr_types.h"

namespace ndk_hello_vr_beta {

/**
 * This is a sample app for the GVR NDK. It loads a simple environment and
 * objects that you can click on.
 */
class HelloVrBetaApp {
 public:
  /**
   * Creates a HelloVrBetaApp using a given |gvr_context|.
   *
   * @param env The JNI environment.
   * @param asset_mgr_obj The asset manager object.
   * @param gvr_api The (non-owned) gvr_context.
   * @param gvr_audio_api The (owned) gvr::AudioApi context.
   */
  HelloVrBetaApp(JNIEnv* env, jobject asset_mgr_obj, gvr_context* gvr_context,
                 std::unique_ptr<gvr::AudioApi> gvr_audio_api);

  ~HelloVrBetaApp();

  /**
   * Initializes any GL-related objects. This should be called on the rendering
   * thread with a valid GL context.
   */
  void OnSurfaceCreated(JNIEnv* env);

  /**
   * Draws the scene. This should be called on the rendering thread.
   */
  void OnDrawFrame();

  /**
   * Pauses head tracking.
   */
  void OnPause();

  /**
   * Resumes head tracking, refreshing viewer parameters if necessary.
   */
  void OnResume();

 private:
  /**
   * Draws all world-space objects.
   */
  void DrawWorld(const gvr::Mat4f view[2], const gvr::Mat4f view_projection[2]);

  /**
   * Draws the target object.
   *
   * We've set all of our transformation matrices. Now we simply pass them
   * into the shader.
   */
  void DrawTarget(const gvr::Mat4f view_projection[2]);

  /**
   * Draws the room.
   */
  void DrawRoom(const gvr::Mat4f view_projection[2]);

  /**
   * Finds a new random position for the target object.
   */
  void GenerateNewTargetPosition();

  /**
   * Checks if user is pointing or looking at the target object by calculating
   * whether the angle between the user's gaze or controller orientation and the
   * vector pointing towards the object is lower than some threshold.
   *
   * @return true if the user is pointing at the target object.
   */
  bool IsPointingAtTarget();

  /**
   * Preloads the target object sound sample and starts the spatialized playback
   * at the current target location. This method is executed from a separate
   * thread to avoid any delay during construction and app initialization.
   */
  void LoadAndPlayTargetObjectSound();

  /**
   * Generate a new target if the controller is pointing at it.
   */
  void OnTrigger(int controller_index);

  /**
   * Grab the target if the controller is pointing at it.
   */
  void OnGrabTarget(int controller_index);

  /**
   * Release the target if we are holding one.
   */
  void OnReleaseTarget(int controller_index);

  void SetTargetPosition(const gvr::Vec3f& position);
  float GetFloorOffset();

  gvr_context* context_;

  std::unique_ptr<gvr::GvrApi> gvr_api_;
  std::unique_ptr<gvr::AudioApi> gvr_audio_api_;
  std::unique_ptr<gvr::BufferViewportList> viewport_list_;
  std::array<gvr::BufferViewport, 2> viewports_;
  std::unique_ptr<gvr::SwapChain> swapchain_;
  Controllers controllers_;

  int controller_on_target_index_;
  bool target_held_;

  TexturedMesh room_;
  Texture room_texture_;
  TexturedMesh target_object_mesh_;
  Texture target_object_not_selected_texture_;
  Texture target_object_selected_texture_;

  TexturedShaderProgram shader_;

  gvr::Mat4f model_target_;
  gvr::Sizei render_size_;

  gvr::AudioSourceId audio_source_id_;
  gvr::AudioSourceId success_source_id_;

  std::thread audio_initialization_thread_;

  jobject java_asset_mgr_;
  AAssetManager* asset_mgr_;
};

}  // namespace ndk_hello_vr_beta

#endif  // HELLOVRBETA_APP_SRC_MAIN_JNI_HELLO_VR_BETA_APP_H_  // NOLINT
