/*
    Raydium - CQFD Corp.
    http://raydium.org/
    Released under both BSD license and Lesser GPL library license.
    See "license.txt" file.
*/

#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/sound.h"
#endif

// proto
void raydium_path_resolv(char *in, char *out, char mode);
float raydium_video_sound_callback(void);

// There's way too much "#ifdef" in this file, but eh ... OpenAL becomes
// complex when you comes to portability ...

#ifndef ALUT_API_MAJOR_VERSION
#warning You must use OpenAL 1.1 or greater ! See configure script.
#endif

#ifndef ALchar
#define ALchar char
#endif

// music OGG infos

void raydium_sound_music_info_init(void)
{
strcpy(raydium_sound_music_info.artist,"Unkown artist");
strcpy(raydium_sound_music_info.album, "Unkown album" );
strcpy(raydium_sound_music_info.title, "Unkown title" );
}

void raydium_sound_music_info_refresh(void)
{
char **ptr;
char part1[RAYDIUM_MAX_NAME_LEN];
char part2[RAYDIUM_MAX_NAME_LEN];


// reset ogg infos
raydium_sound_music_info_init();

ptr=ov_comment(&raydium_sound_vf,-1)->user_comments;
while(*ptr)
    {
    part1[0]=0;
    part2[0]=0;
    raydium_parser_cut(*ptr,part1,part2,'=');

    if(!strcasecmp("title",part1))
        strcpy(raydium_sound_music_info.title,part2);

    if(!strcasecmp("album",part1))
        strcpy(raydium_sound_music_info.album,part2);

    if(!strcasecmp("artist",part1))
        strcpy(raydium_sound_music_info.artist,part2);

      ++ptr;
    }
}

// Sound core functions

//VERIFIES THAT THE LAST OPERATION DID NOT MAKE ANY ERROR
//IF AN ERROR IS DETECTED IT PRINTS THE caller NAME
void raydium_sound_verify(char *caller)
{
 int error;
 if ((error = alGetError()) != AL_NO_ERROR)
 {
  raydium_log("sound: ERROR : %s :%d",caller,error);
//  raydium_log("sound: Deleting buffers");
//   alDeleteBuffers(RAYDIUM_SOUND_NUM_BUFFERS,raydium_sound_buffer);
//  raydium_log("sound: Releasing OpenAL");
//   alutExit();
//   exit(1);
 }
}

int raydium_sound_Array3IsValid(ALfloat *a)
{
if( !raydium_math_isfloat(a[0]) ||
    !raydium_math_isfloat(a[1]) ||
    !raydium_math_isfloat(a[2]) )
        {
        raydium_log("sound : ERROR: invalid 3xALfloat array provided");
        return 0;
        }
return 1;
}

//INITS A SOURCE WITH DEFAULT VALUES
//TAKES A SOURCE NUMBER
void raydium_sound_InitSource(int src)
{
 ALfloat srcPos[]={ 0.0, 0.0, 0.0};
 ALfloat srcVel[]={ 0.0, 0.0, 0.0};

 alSourcef(raydium_sound_source[src],AL_PITCH,1.0f);                //SETS SOURCE PITCH
   raydium_sound_verify("setting source pitch");
 alSourcef(raydium_sound_source[src],AL_GAIN,1.0f);                 //SETS SOURCE GAIN
   raydium_sound_verify("setting source gain");
 alSourcef(raydium_sound_source[src],AL_REFERENCE_DISTANCE,1.f);
   raydium_sound_verify("setting source reference distance");
 alSourcef(raydium_sound_source[src],AL_ROLLOFF_FACTOR,1.f/raydium_sound_DefaultReferenceDistance);
   raydium_sound_verify("setting source rolloff factor");
 alSourcefv(raydium_sound_source[src],AL_POSITION,srcPos);          //SETS SOURCE POSITION
   raydium_sound_verify("setting source position");
 alSourcefv(raydium_sound_source[src],AL_VELOCITY,srcVel);          //SETS SOURCE VELOCITY
   raydium_sound_verify("setting source velocity");
 alSourcei(raydium_sound_source[src],AL_BUFFER,raydium_sound_buffer[src]);               //ATTACHS A SOURCE TO A BUFFER
   raydium_sound_verify("attaching source to buffer");
 alSourcei(raydium_sound_source[src],AL_LOOPING,AL_TRUE);           //SETS SOURCE LOOPING TO TRUE
   raydium_sound_verify("setting source loop state");

 raydium_sound_source_fade_factor[src]=0;
 raydium_sound_source_fade_tofile[src][0]=0;
}


//LOADS A WAV FILE
//RETURNS THE SOURCE NUMBER OR -1 IF IT FAILS
int raydium_sound_LoadWav(const char *fname)
{
 int snum;
 ALsizei size;
 ALenum format;
 ALvoid *data;
 FILE *fp;
 char translated[RAYDIUM_MAX_NAME_LEN];

#ifndef WIN32
#ifdef ALUT_API_MAJOR_VERSION
#define ALUT_API_MAJOR_VERSION_BUT_WIN32
#endif
#endif


 ALfloat freq;



 if(raydium_sound_top_buffer==RAYDIUM_SOUND_NUM_BUFFERS)
 {
  raydium_log("sound