#ifdef WIN32
#include <windows.h>
#endif

#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include <stdlib.h>
#include <SDL/SDL.h>

#ifdef HAVE_SDL_MIXER
# include <SDL/SDL_mixer.h>
#endif

#include "timers.h"
#include "world_geometry.h"
#include "hut.h"
#include "bonus.h"
#include "mango.h"
#include "world_building.h"
#include "texture.h"
#include "world_geometry.h"
#include "sector.h"
#include "map.h"
#include "hud.h"
#include "sounds.h"

extern game_data_t *world;
extern options_t *options;

#ifdef HAVE_SDL_MIXER

Mix_Chunk **menu_sounds;
Mix_Music *music = NULL;

const char *misc_sound_names[NUM_MISC_SOUNDS] = {

  SHXMAN_DATA "sounds/bonus/armaggedon_picked.wav",
  SHXMAN_DATA "sounds/bonus/shockwave_picked.wav",
  SHXMAN_DATA "sounds/bonus/highspeed_picked.wav",
  SHXMAN_DATA "sounds/bonus/stoptime_picked.wav",

  SHXMAN_DATA "sounds/player_dead.wav",
  SHXMAN_DATA "sounds/shmollux_dead.wav",
  SHXMAN_DATA "sounds/teleport.wav",

  SHXMAN_DATA "sounds/youwin.wav",
  SHXMAN_DATA "sounds/gameover.wav",

  SHXMAN_DATA "sounds/proximity.wav",

  SHXMAN_DATA "sounds/one_minute.wav",
  SHXMAN_DATA "sounds/countdown.wav"
};

const char *menus_sounds_names[NUM_MENU_SOUNDS] =
  {
    SHXMAN_DATA "sounds/menus/ok.wav",
    SHXMAN_DATA "sounds/menus/back.wav",
    SHXMAN_DATA "sounds/menus/arrow.wav",
    SHXMAN_DATA "sounds/menus/launch.wav",
    SHXMAN_DATA "sounds/menus/ok.wav"
  };

const char *music_name = SHXMAN_DATA "sounds/music.xm";

int load_misc_sounds()
{
  if (options->use_sound) {
    world->misc_sounds = new Mix_Chunk * [NUM_MISC_SOUNDS];
    for (int i=0; i < NUM_MISC_SOUNDS; i++)
      {
	world->misc_sounds[i] = Mix_LoadWAV(misc_sound_names[i]);
	if (world->misc_sounds[i] == NULL) {
	  fprintf(stderr, "Couldn't load: %s\n", SDL_GetError());
	  exit(1);
	}
      }
  }
  return 1;
}

int load_menu_sounds()
{ 
  if (options->use_sound) {
    menu_sounds = new Mix_Chunk * [NUM_MENU_SOUNDS];
    for (int i=0; i < NUM_MENU_SOUNDS; i++)
      {
	menu_sounds[i] = Mix_LoadWAV(menus_sounds_names[i]);
	if (menu_sounds[i] == NULL) {
	  fprintf(stderr, "Couldn't load: %s\n", SDL_GetError());
	  exit(1);
	}
      }
  }
  return 1;
}

int cleanup_menu_sounds()
{
  if (options->use_sound) {
    for (int i=0; i < NUM_MENU_SOUNDS; i++)
      {
	Mix_FreeChunk(menu_sounds[i]);
      }
    
    delete [] menu_sounds;
  }
  return 1;
}

void play_misc_sound(int which)
{
  if (options->use_sound) {
    if (which < NUM_MISC_SOUNDS)
      Mix_PlayChannel(CHANNEL_MISC, world->misc_sounds[which], 0);
  }
}

void play_menu_sound(int which)
{
  if (options->use_sound) {
    if (which < NUM_MENU_SOUNDS)
      Mix_PlayChannel(CHANNEL_BONUS, menu_sounds[which], 0);
  }
}

void play_time_warning_sound(int which)
{
  if (options->use_sound) {
    if (which < NUM_MISC_SOUNDS)
      Mix_PlayChannel(CHANNEL_WARNINGS, world->misc_sounds[which], 0);
  }
}

void halt_sounds_on_all_channels()
{
  if (options->use_sound) {
    Mix_HaltChannel(CHANNEL_WARNINGS);
    Mix_HaltChannel(CHANNEL_BONUS);
    Mix_HaltChannel(CHANNEL_MISC);
    Mix_HaltChannel(CHANNEL_AMBIANT);
  }
}

int load_music()
{
  if (options->use_sound) {
    music = Mix_LoadMUS(music_name);
    if ( music == NULL ) {
      fprintf(stderr, "Error: couldn't load %s: %s\n",
	      music_name, SDL_GetError());
      exit(1);
    }
  }
  return 1;
}

void play_music()
{
  if (options->use_sound) {
    Mix_PlayMusic(music,-1);
  }
}

void stop_music()
{
  if (options->use_sound) {
    Mix_HaltMusic();
  }
}

void pause_toggle_music()
{
  if (options->use_sound) {
    if (Mix_PausedMusic())
      Mix_ResumeMusic();

    else Mix_PauseMusic();
  }
}

void cleanup_music()
{
  if (options->use_sound) {
    Mix_FreeMusic(music);
  }
}


#else

int load_misc_sounds()
{
  printf("Not loading sounds (SDL_Mixer not available)\n");
  return 1;
}

int load_menu_sounds()
{
  printf("Not loading sounds (SDL_Mixer not available)\n");
  return 1;
}

int load_music()
{
  printf("Not loading music (SDL_Mixer not available)\n");
  return 1;
}


void play_misc_sound(int which)
{

}

void play_time_warning_sound(int which)
{

}

void play_menu_sound(int which)
{

}

void halt_sounds_on_all_channels()
{

}

int cleanup_menu_sounds()
{
  return 1;
}

int load_music()
{
  return 1;
}

void play_music()
{

}

void stop_music()
{

}

void pause_toggle_music()
{

}

void cleanup_music()
{

}

#endif /* HAVE_SDL_MIXER */

