//=============================================================================
// FILE: spatialaudio_utility.h
//
//                  Copyright (c) 2017 QUALCOMM Technologies Inc.
//                              All Rights Reserved.
//
//=============================================================================

#include "Q3DAudioClient.h"
#include <glm/glm.hpp>


namespace Svr
{
	class SvrGeometry;
	class SvrShader;
}


#define Q3D_AUDIO_HANDLE_VALID(h) (h >= 0)
#define Q3D_AUDIO_RESULT_SUCCESS(r) (r == Q3D_AUDIO_SUCCESS)
#define Q3D_AUDIO_MATERIAL_VALID(m) (m >= Q3D_AUDIO_MATERIAL_TRANSPARENT && m <= Q3D_AUDIO_MATERIAL_WOOD_PANEL)

#if defined(NDEBUG)
#define Q3D_AUDIO_ASSERT_HANDLE_VALID(h)
#define Q3D_AUDIO_ASSERT_SUCCESS(r)
#define Q3D_AUDIO_ASSERT_MATERIAL_VALID(m)
#else//debug build
#define Q3D_AUDIO_ASSERT_HANDLE_VALID(h) (assert(Q3D_AUDIO_HANDLE_VALID(h)))
#define Q3D_AUDIO_ASSERT_SUCCESS(r) (assert(Q3D_AUDIO_RESULT_SUCCESS(r)))
#define Q3D_AUDIO_ASSERT_MATERIAL_VALID(m) (assert(Q3D_AUDIO_MATERIAL_VALID(m)))
#endif//#if defined(NDEBUG)


q3d_audio_result Q3DAudioCreate(q3d_audio_client** client, JavaVM*const vm, jobject javaActivityObject);
q3d_audio_result Q3DAudioDestroy(q3d_audio_client**const pSpatialAudio);

q3d_audio_result Q3DAudioUpdate(q3d_audio_client* pSpatialAudio, const bool log);
q3d_audio_result Q3DAudioSetHeadPosition(
	q3d_audio_client*const pSpatialAudio,
	const glm::vec3& headPositionWorldSpace,
	const bool log);
q3d_audio_result Q3DAudioSetHeadRotation(
	q3d_audio_client*const pSpatialAudio,
	const glm::quat &playerHeadOrientationWorldSpace,
	const bool log);

bool Q3DAudioPreloadSoundFile(q3d_audio_client*const pSpatialAudio, const char*const pSoundFileName);
q3d_audio_result Q3DAudioUnloadSoundFile(q3d_audio_client*const pSpatialAudio, const char*const pFilename);

q3d_audio_sound_id Q3DAudioObjectCreate(q3d_audio_client*const pSpatialAudio, const char*const pFilename);
q3d_audio_sound_id Q3DAudioSoundfieldCreate(q3d_audio_client*const pSpatialAudio, const char*const pFilename);
q3d_audio_sound_id Q3DAudioSoundChannelCreate(q3d_audio_client*const pSpatialAudio, const char*const pFilename);

q3d_audio_result Q3DAudioSoundPlay(q3d_audio_client*const pSpatialAudio,const q3d_audio_sound_id soundId,const bool looping);
q3d_audio_result Q3DAudioSoundStopAndInvalidateHandle(q3d_audio_client*const pSpatialAudio, const q3d_audio_sound_id soundId);

q3d_audio_result Q3DAudioPauseSound(q3d_audio_client* const pSpatialAudio, const q3d_audio_sound_id soundId);
q3d_audio_result Q3DAudioResumeSound(q3d_audio_client* const pSpatialAudio, const q3d_audio_sound_id soundId);
bool Q3DAudioIsSoundPlaying(q3d_audio_client*const pSpatialAudio, const q3d_audio_sound_id soundId);

q3d_audio_result Q3DAudioSetObjectPosition(
	q3d_audio_client*const pSpatialAudio,
	const q3d_audio_sound_id soundId,
	const glm::vec3& position,
	const bool log);

q3d_audio_result Q3DAudioGetObjectPosition(
	q3d_audio_client*const pSpatialAudio,
	q3d_audio_vec3f* pPosition,
	const q3d_audio_sound_id soundId,
	const bool log);

void Q3DAudioSetSoundVolume(
	q3d_audio_client*const pSpatialAudio, 
	const q3d_audio_sound_id soundId, 
	const float volume, 
	const bool log);
q3d_audio_result Q3DAudioGetSoundVolume(
	q3d_audio_client*const pSpatialAudio,
	float& volume,
	const q3d_audio_sound_id soundId,
	const bool log);

q3d_audio_result Q3DAudioObjectSetRolloff(
	q3d_audio_client* const pSpatialAudio,
	const q3d_audio_sound_id soundId,
	const q3d_audio_distance_rolloff_type rolloffType,
	const float minDistance,
	const float maxDistance);

q3d_audio_result Q3DAudioSetSoundfieldRotation(
	q3d_audio_client*const pSpatialAudio,
	const q3d_audio_sound_id soundFieldId,
	const q3d_audio_quatf& orientation,
	const bool log);

q3d_audio_result Q3DAudioGetSoundfieldRotation(
	q3d_audio_client*const pSpatialAudio,
	q3d_audio_quatf*const pOrientation,
	const q3d_audio_sound_id soundFieldId,
	const bool log);

bool Q3DAudioSetReverb(
	q3d_audio_client* mpSpatialAudio,
	const bool enabled,
	const float gain,
	const float timeAdjust,
	const float brightnessAdjust,
	const glm::vec3& roomDimensions,
	const q3d_audio_material_type wallMaterial,
	const q3d_audio_material_type ceilingMaterial,
	const q3d_audio_material_type floorMaterial);


void InitializeModel(
	Svr::SvrGeometry**const pModelGeometry,
	Svr::SvrShader*const pShader,
	const char*const pAppExternalPath,
	const char*const pObjFileLocalPath,
	const char*const pVertexShaderFileRelativePath,
	const char*const pFragmentShaderFileRelativePath,
	const char*const pVertexShaderDebugName,
	const char*const pFragmentShaderDebugName);

void * GetFileBuffer(int*const pBufferSize, const char*const pAppExternalPath, const char*const pFileName);

void DestroyGeometry(Svr::SvrGeometry**const model);

void PositionsOnSphereCalculate(glm::vec3*const positions, const float radius);
glm::vec3 ColorCode(const glm::vec3& positionUnitLength);
q3d_audio_quatf GlmMat4ToSpatialAudioQuat(const glm::mat4& m);
