/***************************************************************************
 *            sound.h
 *
 *  Fri May 13 19:01:29 2005
 *  Copyright  2005  Joe Venzon
 *  joe@venzon.net
 ****************************************************************************/

/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 
#ifndef _SOUND_H

#include <stdio.h>			// Header File For Standard Input/Output
#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>
#ifdef __APPLE__
#include <SDL_image/SDL_image.h>
#else
#include <SDL/SDL_image.h>
#endif
#include <string>
#include <iostream>
#include <fstream>
#include <cmath>
#include <cassert>
#include <stdlib.h>

#include <map>

#include "camera.h"
#include "utility.h"

//#include "backdrop.h"
//#include "weather.h"

#include "globals.h"

using namespace std;

#define MAX_BUFFERS 50

#ifdef __APPLE__
       #include <OpenAL/al.h>
       #include <OpenAL/alc.h>
       //#include <OpenAL/alut.h> // Mac OS X 10.4.7 broke alut
	   #include "alut.h"
#else
       #include <AL/al.h>
       #include <AL/alc.h>
       //#include <AL/alu.h>
       #include <AL/alut.h>
#endif

#define MAX_SOURCES 10

#define DISTANCE_FACTOR 0.025
//#define VELOCITY_FACTOR 1.0/DISTANCE_FACTOR
#define VELOCITY_FACTOR 1.5

class SOUNDMANAGER
{
private:
	// Buffers to hold sound data.
	/*ALuint * buffers;
	int buf_cur;
	string * buf_fn;
	
	// Sources are points of emitting sound.
	ALuint sources[MAX_SOURCES];
	bool source_free[MAX_SOURCES];

	bool muted;

	bool disable;

	float master_volume;*/

	ALCdevice* mSoundDevice;
	ALCcontext* mSoundContext;

	bool init;
	bool disabled;
	bool loaded;
	
	map <string, ALuint> buffers;
	vector <ALuint> sources;
	vector <bool> source_free;
	
	float master_volume;
	
	void Load();
	
	void LoadSoundFile(string filename);
	
	void UnloadWave(ALvoid* data);
	bool LoadWave(string fname, ALenum *format, ALvoid **data, ALsizei *size, ALsizei *freq, ALboolean *loop);
	bool IDMatchesString(const char * id, const char * str);
	
public:
	SOUNDMANAGER() {init=false;disabled=false;loaded=false;master_volume=1.0;}
	~SOUNDMANAGER() {Deinit();}
	
	void Init();
	void Deinit();
	void Reload();
	void Unload();
	void DisableAllSound() {disabled=true;}
	void SetMasterVolume(float newvol) {master_volume = newvol; if (master_volume < 0) master_volume = 0; if (master_volume > 1) master_volume = 1;}
	float GetMasterVolume() {return master_volume;}
	void UpdateSettings() { float sound_vol; settings.Get( "sound.volume", sound_vol ); SetMasterVolume( sound_vol ); }
	void MuteAll();
	void UnMuteAll();
	
	void SetListenerPos(VERTEX pos);
	void SetListenerVel(VERTEX vel);
	void SetListenerOrientation(VERTEX at, VERTEX up);
	void SetPosVel(int sid, VERTEX coord, VERTEX tvel);
	void SetListener(VERTEX campos, VERTEX camvel, VERTEX at, VERTEX up);
	void SetPitch(int sid, float pitch);
	void SetGain(int sid, float gain);
	void SetPos(int sid, VERTEX pos);
	void SetVel(int sid, VERTEX vel);
	
	ALuint NewSource(string buffername);
	ALuint NewSource(string buffername, bool & error);
	void StopSource(int sid);
	void PlaySource(int idx);
	void Update() {}
	
	// Gentoo
	/*ALCdevice* mSoundDevice;
	ALCcontext* mSoundContext;
	
	void Load();
	void LoadAllSoundFiles();
	void LoadSoundFile(string filename);
	~SOUNDMANAGER();
	SOUNDMANAGER();

	void SetListenerPos(VERTEX pos);
	void SetListenerVel(VERTEX vel);
	void SetListenerOrientation(VERTEX at, VERTEX up);

	void SetMasterVolume(float newvol) {master_volume = newvol; if (master_volume < 0) master_volume = 0; if (master_volume > 1) master_volume = 1;}
	float GetMasterVolume() {return master_volume;}

	void UpdateSettings() { float sound_vol; settings.Get( "sound.volume", sound_vol ); SetMasterVolume( sound_vol ); }

	ALuint NewSource(string buffername);

	void PlaySource(int idx);
	void SetPitch(int sid, float pitch);
	void SetGain(int sid, float gain);
	void SetPos(int sid, VERTEX pos);
	void SetVel(int sid, VERTEX vel);

	void MuteAll();
	void UnMuteAll();
	//ALuint GetSource(string buffername);
	
	void Update() {}
	void StopSource(int sid);

	void DisableAllSound();
	void EnableAllSound();
		
	void SetPosVel(int sid, VERTEX coord, VERTEX tvel);
	void SetListener(VERTEX campos, VERTEX camvel, VERTEX at, VERTEX up);*/
};

#define _SOUND_H
#endif
