#include <stdio.h>
#include "allegro.h"
#include <alogg/alogg.h>
#include "MusicSound.h"
#include <string>
using namespace std;

MusicSound :: MusicSound ()
{
  soundInit = false;
  volGlobal = 0;
  volMusic = 0;
  volSfx = 0;

  musicPlaying = NULL;
  musicPlayingFilename = new string ("");
  musicQueued = NULL;

  beginFading = false;
  doneFading = false;
}

int MusicSound :: initAudio ()
{
  //returns 0 if sucessful.
  //returns -1 if failure.

  int result;

  result = install_sound (DIGI_AUTODETECT, MIDI_AUTODETECT, NULL);

  if (result != 0)
    {
      allegro_message ("Music/Sound Error: %s\n", allegro_error);
    }
  else
    soundInit = true;

  if (soundInit)
    {
      alogg_init ();
    }

  return 0;
}

int MusicSound :: getVolumeGlobal ()
{ return volGlobal; }

int MusicSound :: getVolumeMusic ()
{ return volMusic; }

int MusicSound :: getVolumeSfx ()
{ return volSfx; }

void MusicSound :: setVolumeGlobal (int v)
{ volGlobal = v; 
 if (soundInit)
   set_volume(volGlobal, -1);
}

void MusicSound :: setVolumeMusic (int v)
{ volMusic = v; }

void MusicSound :: setVolumeSfx (int v)
{ volSfx = v; }

void MusicSound :: playMusic (string * as)
{
  //call this first! updateMusic will work on this song.
  musicPlayingFilename -> assign (as -> c_str ());

  musicPlaying = alogg_start_streaming (musicPlayingFilename -> c_str (), 32768);
  //set the volume, too. Global * Music / 255.
  if (musicPlaying != NULL)
    {
    voice_set_volume (alogg_get_audio_stream(musicPlaying) -> voice, volMusic);

    voice_set_priority (alogg_get_audio_stream(musicPlaying) -> voice, 255);
    }
}

void MusicSound :: updateMusic ()
{
  //call this regularly to make sure that music is played.
  
  int updateStatus = 0;

  if (musicPlaying != NULL)
    {
      updateStatus = alogg_update_streaming (musicPlaying);

      //updateStatus = 0 means the song is done.
      if (musicPlaying != NULL && updateStatus == 0)
	{
	  //loop the song!
	  alogg_stop_streaming (musicPlaying);
	  musicPlaying = alogg_start_streaming (musicPlayingFilename -> c_str (), 32768);
	  voice_set_volume (alogg_get_audio_stream(musicPlaying) -> voice, volMusic);
	  voice_set_priority (alogg_get_audio_stream(musicPlaying) -> voice, 255);
	}
    }
}

void MusicSound :: stopMusic ()
{
  if (musicPlaying != NULL)
    alogg_stop_streaming (musicPlaying);

  musicPlaying = NULL;
}

void MusicSound :: pauseMusic ()
{
  if (musicPlaying != NULL)
    {
      voice_stop (alogg_get_audio_stream(musicPlaying) -> voice);
    }
}

void MusicSound :: restartMusic ()
{
  if (musicPlaying != NULL)
    {
      voice_start (alogg_get_audio_stream(musicPlaying) -> voice);
    }
}

void MusicSound :: fadeMusic ()
{
//fade the current music (note: audiostream -> voice returns the int voice of it, so you can do stuff to it., like void voice_set_volume (voice, volume)
//or, void voice_ramp_volume
  if (musicPlaying != NULL)
    voice_ramp_volume (alogg_get_audio_stream(musicPlaying) -> voice, 1000, 0);
}

void MusicSound :: playSfx (SAMPLE * spl, int pan, int freq)
{
  //plays the given sound effect at the given pan (0 = full left, 255 = full right.)
  play_sample (spl, volSfx, pan, freq, 0);
}


MusicSound :: ~MusicSound ()
{
  if (soundInit)
    {
      alogg_stop_streaming (musicPlaying);
      alogg_exit ();
    }
}
