/*
 *  ofALSoundPlayer.cpp
 *  Mobile Frameworks
 *
 *  Created by Zach Gage on 9/6/08.
 *  Copyright 2008 stfj. All rights reserved.
 *
 */

#import "ofALSoundPlayer.h"

#import "SoundEngine.h"

bool SoundEngineInitialized = false;

UInt32	numSounds;


ofALSoundPlayer::ofALSoundPlayer()
{
	volume = 1.0f;
	pitch = 0.0f;
	pan = 1.0f;
	stopped=true;
	
	
	ofALSoundPlayer::initializeSoundEngine();
	
}

ofALSoundPlayer::~ofALSoundPlayer()
{
	
}

//--------------------

void ofALSoundPlayer::loadSound(string fileName)
{
	if(!SoundEngineInitialized)
	{
		ofALSoundPlayer::initializeSoundEngine();
	}
	
	myId = ofALSoundGetNextID(); //get the next ID to assosciate to a sound... 
	/*right now it wont remove old ID's, so once an ID is used its gone.. this should be fixed maybe?
	it wont really effect anything, its just used as a reference name for the sound, so as long as people
	dont load and unload thousands of sounds it should be fine...*/
	
	SoundEngine_LoadEffect(ofToDataPath(fileName).c_str(), &myId);

}

//--------------------

void ofALSoundPlayer::loadLoopingSound(string fileName)
{
	if(!SoundEngineInitialized)
	{
		ofALSoundPlayer::initializeSoundEngine();
	}
	
	myId = ofALSoundGetNextID(); //get the next ID to assosciate to a sound... 
	/*right now it wont remove old ID's, so once an ID is used its gone.. this should be fixed maybe?
	 it wont really effect anything, its just used as a reference name for the sound, so as long as people
	 dont load and unload thousands of sounds it should be fine...*/
	
	SoundEngine_LoadLoopingEffect(ofToDataPath(fileName).c_str(), NULL, NULL, &myId);
}

//--------------------

void ofALSoundPlayer::loadLoopingSound(string loopingFileName, string attackFileName, string decayFileName)
{
	if(!SoundEngineInitialized)
	{
		ofALSoundPlayer::initializeSoundEngine();
	}
	
	myId = ofALSoundGetNextID(); //get the next ID to assosciate to a sound... 
	/*right now it wont remove old ID's, so once an ID is used its gone.. this should be fixed maybe?
	 it wont really effect anything, its just used as a reference name for the sound, so as long as people
	 dont load and unload thousands of sounds it should be fine...*/
	
	SoundEngine_LoadLoopingEffect(ofToDataPath(loopingFileName).c_str(), ofToDataPath(attackFileName).c_str(), ofToDataPath(decayFileName).c_str(), &myId);
}

//--------------------

void ofALSoundPlayer::unloadSound()
{
	SoundEngine_UnloadEffect(myId);
}

//--------------------

void ofALSoundPlayer::play()
{
	SoundEngine_StartEffect(myId);
	stopped = false;
}

//--------------------

void ofALSoundPlayer::stop()
{
	SoundEngine_StopEffect(myId, false);
	stopped = true;
}

//--------------------

void ofALSoundPlayer::stopWithDecay()
{
	SoundEngine_StopEffect(myId, true);
	stopped = true;
}

//--------------------

void ofALSoundPlayer::vibrate()
{
	SoundEngine_Vibrate();
}

//--------------------

void ofALSoundPlayer::setVolume(float _vol)
{
	volume = _vol;
	SoundEngine_SetEffectLevel(myId, (Float32)volume);
}

//--------------------

void ofALSoundPlayer::setPan(float _pan) // this is totally legacy and shouldn't really be used. SetLocation is much better
{
	//also this could be confusing. In oF pan is between 0 and 1.0 with .5 as the center. in ofAL it is between -1.0 and 1.0.
	//i compensate for it here and in getPan, but im not sure if thats the best strategy. I guess it's ok as long as you don't
	//use setPan and setLocation in the same program
	_pan = _pan*2 - 1.0f;
	setLocation(_pan, 0, 0);
}

//--------------------

void ofALSoundPlayer::setPitch(float _pitch)
{
	pitch = _pitch;
	SoundEngine_SetEffectPitch(myId, (Float32)pitch);
}

//--------------------
/*
void ofALSoundPlayer::setMultiPlay(bool _multiPlay) //within the SoundEngine class I couldn't find a way to do this...
{
	//to do
}

//--------------------

void ofALSoundPlayer::setPosition(float pct)
{
	//to do
}
*/
//--------------------

void ofALSoundPlayer::setLocation(float x, float y, float z)
{
	pan = (x+1.0)/2; // this is where im compensating for the scale of oF... (pan in oF is 0-1.0, in ofAL it's -1.0 to 1.0)
	SoundEngine_SetEffectPosition(myId, x, y, z);
}


//---------------------------------------
// this should only be called once
void ofALSoundPlayer::initializeSoundEngine(){
	if(!SoundEngineInitialized){
		
		OSStatus err = SoundEngine_Initialize(44100);
		
		//SoundEngine_SetMasterVolume(0.2f);
		
		if(err)
		{
			printf("ERROR failed to initialize soundEngine.");
		}
		else
		{
			printf("SoundEngine initialized \n");
			numSounds=0;
			SoundEngineInitialized = true;
			OSStatus err = SoundEngine_SetListenerPosition(0.0f, 0.0f, 0.0f);
			if(err)
			{
				printf("ERROR failed to set listener position..\n (if you are running in the simulator, this is normal, sounds won't work.) \n");
			}
		}
	}
}


//---------------------------------------
void ofALSoundPlayer::closeSoundEngine(){
	if(SoundEngineInitialized){
		
		SoundEngine_Teardown();
		numSounds++;
		
		SoundEngineInitialized = false;
	}
}

float ofALSoundPlayer::getPitch()
{
	return pitch;
}

//---------------------------------------

float ofALSoundPlayer::getPan()
{
	return pan;
}

//---------------------------------------
void ofALSoundStopAll(){
	ofALSoundPlayer::initializeSoundEngine();
	
	//to do stop all sounds
}

//--------------------
void ofALSoundSetVolume(float vol){
	ofALSoundPlayer::initializeSoundEngine();
	
	SoundEngine_SetMasterVolume((Float32)vol);
}

//--------------------
void ofALSoundPlayer::ofALSoundSetListenerLocation(float x, float y, float z){
	ofALSoundPlayer::initializeSoundEngine();
	
	SoundEngine_SetListenerPosition(x, y, z);
}

//--------------------
void ofALSoundPlayer::ofALSoundSetListenerVelocity(float x, float y, float z){
	ofALSoundPlayer::initializeSoundEngine();
	
	SoundEngine_SetListenerVelocity(x, y, z);
}

//--------------------

void ofALSoundPlayer::ofALSoundSetListenerGain(float gain)
{
	SoundEngine_SetListenerGain(gain);
}

//--------------------

void ofALSoundPlayer::ofALSoundSetListenerPitch(float pitch)
{
	//SoundEngine_SetListenerPitch(pitch);
}

//--------------------

void ofALSoundPlayer::ofALSoundSetReferenceDistance(float dist)
{
	SoundEngine_SetReferenceDistance(dist);
}

//--------------------

void ofALSoundPlayer::ofALSoundSetMaxDistance(float dist)
{
	SoundEngine_SetMaxDistance(dist);
}

//--------------------

UInt32 ofALSoundPlayer::ofALSoundGetNextID()
{
	return numSounds++;
}

//--------------------

void ofALSoundPlayer::loadBackgroundMusic(string fileName, bool queue, bool loadAtOnce)
{
	
	if(!SoundEngineInitialized)
	{
		ofALSoundPlayer::initializeSoundEngine();
	}
	
	myId = ofALSoundGetNextID(); //get the next ID to assosciate to a sound... 
	/*right now it wont remove old ID's, so once an ID is used its gone.. this should be fixed maybe?
	 it wont really effect anything, its just used as a reference name for the sound, so as long as people
	 dont load and unload thousands of sounds it should be fine...*/
	
	SoundEngine_LoadBackgroundMusicTrack(ofToDataPath(fileName).c_str(), queue, loadAtOnce);

	
		
}

//--------------------

void ofALSoundPlayer::unloadAllBackgroundMusic()
{
	SoundEngine_UnloadBackgroundMusicTrack();
}

//--------------------

void ofALSoundPlayer::startBackgroundMusic()
{
	SoundEngine_StartBackgroundMusic();
}

//--------------------

void ofALSoundPlayer::stopBackgroundMusic(bool stopNow)
{
	SoundEngine_StopBackgroundMusic(!stopNow); //this is confusing but i think stopNow makes more sense than stopAtEnd in terms of how people will likely be calling this
}

//--------------------

void ofALSoundPlayer::setBackgroundMusicVolume(float bgVol)
{
	SoundEngine_SetBackgroundMusicVolume((Float32)bgVol);
}