/*  TA3D, a remake of Total Annihilation
    Copyright (C) 2005  Roland BROCHARD

    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 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA*/

/*-----------------------------------------------------------------------------------\
|                                        sound.h                                     |
|   Ce module contient les structures, classes et fonctions nécessaires à la gestion |
| des sons.                                                                          |
|                                                                                    |
\-----------------------------------------------------------------------------------*/

#include <string.h>
#include <stdio.h>
#include "console.h"
#include "hpi.h"
#include "vector.h"

SAMPLE *load_memory_wav(byte *data,int size);

class SOUND_MANAGER
{
private:
	int			nb_sound;		// Nombre de sons joués
	SAMPLE		*sample[128];	// Sons joués par Allegro
	int			voice[128];		// Voix allouées pour jouer les sons
	VECTOR		pos[128];		// Position des sources sonores
	bool		sound3d[128];	// Indique si le son est localisé dans l'espace

public:
	void init()
	{
		nb_sound=0;
		for(int i=0;i<128;i++)
			sample[i]=NULL;
	}

	void destroy()
	{
		for(int i=0;i<nb_sound;i++)
			destroy_sample(sample[i]);
		init();
	}

	SOUND_MANAGER()
	{
		init();
	}

	~SOUND_MANAGER()
	{
		destroy();
	}

	inline void clean(VECTOR cam_pos,VECTOR side)
	{
		int e=0;
		for(int i=0;i+e<nb_sound;) {
			if(voice_get_position(voice[i+e])==-1) {			// Le son a fini d'être joué
				destroy_sample(sample[i+e]);
				e++;
				}
			else {
				sample[i]=sample[i+e];
				voice[i]=voice[i+e];
				pos[i]=pos[i+e];
				i++;
				}
			}
		nb_sound-=e;
		VECTOR o_d=cam_pos+side;
		VECTOR o_g=cam_pos-side;
		for(int i=0;i<nb_sound;i++) {
			if(sound3d[i]) {
				float i_d=25500000.0f/(pos[i]-o_d).Sq();
				float i_g=25500000.0f/(pos[i]-o_g).Sq();
				int volume=(int)(i_d+i_g);
				int pan= (volume==0) ? 0 : (int)(255*(i_d/(i_d+i_g)));
				if(volume>255)	volume=255;
				voice_set_volume(voice[i],volume);
				voice_set_pan(voice[i],pan);
				}
			else {
				voice_set_volume(voice[i],255);
				voice_set_pan(voice[i],127);
				}
			}
	}

	inline void play(char *filename,VECTOR Pos,bool s3d=true)
	{
		if(filename==NULL)	return;
		if(nb_sound>=128)	return;

		char real_filename[1000];
		real_filename[0]=0;
		strcat(real_filename,"/sounds/");
		strcat(real_filename,filename);
		strcat(real_filename,".wav");
		int size=0;
		byte *data=load_file(real_filename,&size);
		if(data) {
			sample[nb_sound]=load_memory_wav(data,size);
			free(data);
			if(sample[nb_sound]) {
				voice[nb_sound]=play_sample(sample[nb_sound], 255, 128, 1000, 0);
				pos[nb_sound]=Pos;
				sound3d[nb_sound]=s3d;
				nb_sound++;
				}
			}
	}
};

extern SOUND_MANAGER sound_manager;
