module br.sound;

private import br.gamemanager;
private import br.mainloop;
private import SDL_mixer;
private import SDL;

public enum se_kind{
	STAR ,DON ,MISS ,SPEEDUP ,BOMB ,BEEP ,WARNING ,REVERSE,
	V_0, V_1 ,V_2 ,V_3 ,V_4 ,V_5 ,V_6 ,V_7 ,V_8 ,V_9
};
public enum music_kind{
	MUSIC1 ,MUSIC2 ,MUSIC3 ,MUSIC4 ,MUSIC5 ,MUSIC6 ,MUSIC7 ,MUSIC8 ,MUSIC9
};
private int _Sound_PlayingMusic;
private bool _nosound = false;

Mix_Chunk* chunk_star;
Mix_Chunk* chunk_don;

Mix_Chunk* chunk_miss;
Mix_Chunk* chunk_speedup;
Mix_Chunk* chunk_bomb;
Mix_Chunk* chunk_beep;
Mix_Chunk* chunk_warning;
Mix_Chunk* chunk_reverse;
Mix_Chunk* voice_0;
Mix_Chunk* voice_1;
Mix_Chunk* voice_2;
Mix_Chunk* voice_3;
Mix_Chunk* voice_4;
Mix_Chunk* voice_5;
Mix_Chunk* voice_6;
Mix_Chunk* voice_7;
Mix_Chunk* voice_8;
Mix_Chunk* voice_9;
Mix_Music   *music1;
Mix_Music 	*music2;
Mix_Music	*music3;
Mix_Music	*music4;
Mix_Music	*music5;
Mix_Music	*music6;
Mix_Music	*music7;
Mix_Music	*music8;
Mix_Music	*music9;

public void Sound_init(){
	SDL_InitSubSystem(SDL_INIT_AUDIO);
	int audio_rate;
    Uint16 audio_format;
    int audio_channels;
    int audio_buffers;
	audio_rate = 44100;
    audio_format = AUDIO_S16;
    audio_channels = 2;
    audio_buffers = 2048;
	if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) < 0){
		_nosound = true;
		return ;
	}
	Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
	chunk_star = Mix_LoadWAV("se/cursor18.wav");
	chunk_don = Mix_LoadWAV("se/don18_d.wav");
	
	chunk_miss = Mix_LoadWAV("se/don20.wav");
	chunk_speedup = Mix_LoadWAV("se/power34.wav");
	chunk_bomb = Mix_LoadWAV("se/bom13_c.wav");
	chunk_beep = Mix_LoadWAV("se/beep00.wav");
	chunk_warning = Mix_LoadWAV("se/emergency.wav");
	chunk_reverse = Mix_LoadWAV("se/hit_s03_a.wav");
	voice_0 = Mix_LoadWAV("voice/FREQ_A500_0.wav");
	voice_1 = Mix_LoadWAV("voice/FREQ_A500_1.wav");
	voice_2 = Mix_LoadWAV("voice/FREQ_A500_2.wav");
	voice_3 = Mix_LoadWAV("voice/FREQ_A500_3.wav");
	voice_4 = Mix_LoadWAV("voice/FREQ_A500_4.wav");
	voice_5 = Mix_LoadWAV("voice/FREQ_A500_5.wav");
	voice_6 = Mix_LoadWAV("voice/FREQ_A500_6.wav");
	voice_7 = Mix_LoadWAV("voice/FREQ_A500_7.wav");
	voice_8 = Mix_LoadWAV("voice/FREQ_A500_8.wav");
	voice_9 = Mix_LoadWAV("voice/FREQ_A500_9.wav");
	
	
	music1 = Mix_LoadMUS("music/cyrf_ogg_difficulties.ogg");
	music2 = Mix_LoadMUS("music/cyrf_ogg_proving_area.ogg");
	music3 = Mix_LoadMUS("music/FREQ_loop002.ogg");
	music4 = Mix_LoadMUS("music/mix_loop004_3.ogg");
	music5 = Mix_LoadMUS("music/division_bell.ogg");
	music6 = Mix_LoadMUS("music/untitled.ogg");
	music7 = Mix_LoadMUS("music/splash_intro.ogg");
	music8 = Mix_LoadMUS("music/splash_main.ogg");
	music9 = Mix_LoadMUS("music/transmigration.ogg");
	
	_Sound_PlayingMusic = -1;
}

public void Sound_PlaySe(uint kind){
	if(!nosound){
		switch(kind){
			case se_kind.STAR:Mix_PlayChannel(0 ,chunk_star ,0);break;
			case se_kind.DON:Mix_PlayChannel(1 ,chunk_don ,0);break;
			
			case se_kind.MISS:Mix_PlayChannel(2 ,chunk_miss ,0);break;
			case se_kind.SPEEDUP:Mix_PlayChannel(3 ,chunk_speedup ,0);break;
			case se_kind.BOMB:Mix_PlayChannel(2 ,chunk_bomb ,0);break;
			case se_kind.BEEP:Mix_PlayChannel(3 ,chunk_beep ,0);break;
			case se_kind.WARNING:Mix_PlayChannel(4 ,chunk_warning ,0);break;
			case se_kind.REVERSE:Mix_PlayChannel(5 ,chunk_reverse ,0);break;
			case se_kind.V_0:Mix_PlayChannel(6 ,voice_0 ,0);break;
			case se_kind.V_1:Mix_PlayChannel(6 ,voice_1 ,0);break;
			case se_kind.V_2:Mix_PlayChannel(6 ,voice_2 ,0);break;
			case se_kind.V_3:Mix_PlayChannel(6 ,voice_3 ,0);break;
			case se_kind.V_4:Mix_PlayChannel(6 ,voice_4 ,0);break;
			case se_kind.V_5:Mix_PlayChannel(6 ,voice_5 ,0);break;
			case se_kind.V_6:Mix_PlayChannel(6 ,voice_6 ,0);break;
			case se_kind.V_7:Mix_PlayChannel(6 ,voice_7 ,0);break;
			case se_kind.V_8:Mix_PlayChannel(6 ,voice_8 ,0);break;
			case se_kind.V_9:Mix_PlayChannel(6 ,voice_9 ,0);break;
			default:break;
		}
	}
	
}

public void Sound_PlayMusic(int kind ,int loop = -1){
	if(!nosound){
		if(Sound_PlayingMusic == kind)return;
		
		switch(kind){
			case music_kind.MUSIC1:Mix_PlayMusic(music1, loop);break;
			case music_kind.MUSIC2:Mix_PlayMusic(music2, loop);break;
			case music_kind.MUSIC3:Mix_PlayMusic(music3, loop);break;
			case music_kind.MUSIC4:Mix_PlayMusic(music4, loop);break;
			case music_kind.MUSIC5:Mix_PlayMusic(music5, loop);break;
			case music_kind.MUSIC6:Mix_PlayMusic(music6, loop);break;
			case music_kind.MUSIC7:Mix_PlayMusic(music7, loop);break;
			case music_kind.MUSIC8:Mix_PlayMusic(music8, loop);break;
			case music_kind.MUSIC9:Mix_PlayMusic(music9, loop);break;
			default:return;
		}
		_Sound_PlayingMusic = kind;
	}
}
public void Sound_FadeInMusic(int kind ,int ms, int loop = -1){
	if(!nosound){
		if(Sound_PlayingMusic == kind)return;
		
		switch(kind){
			case music_kind.MUSIC1:Mix_FadeInMusic(music1, loop, ms);break;
			case music_kind.MUSIC2:Mix_FadeInMusic(music2, loop, ms);break;
			case music_kind.MUSIC3:Mix_FadeInMusic(music3, loop, ms);break;
			case music_kind.MUSIC4:Mix_FadeInMusic(music4, loop, ms);break;
			case music_kind.MUSIC5:Mix_FadeInMusic(music5, loop, ms);break;
			case music_kind.MUSIC6:Mix_FadeInMusic(music6, loop, ms);break;
			case music_kind.MUSIC7:Mix_FadeInMusic(music7, loop, ms);break;
			case music_kind.MUSIC8:Mix_FadeInMusic(music8, loop, ms);break;
			case music_kind.MUSIC9:Mix_FadeInMusic(music9, loop, ms);break;
			default:return;
		}
		_Sound_PlayingMusic = kind;
	}
}
public void Sound_HaltMusic(){
	Mix_HaltMusic();
	_Sound_PlayingMusic = -1;
}
public void Sound_FadeOutMusic(int ms){
	Mix_FadeOutMusic(ms);
	_Sound_PlayingMusic = -1;
}

public void Sound_free(){
	Mix_FreeMusic(music1);
	Mix_FreeMusic(music2);
	Mix_FreeMusic(music3);
	Mix_FreeMusic(music4);
	Mix_FreeMusic(music5);
	Mix_FreeMusic(music6);
	Mix_FreeMusic(music7);
	Mix_FreeMusic(music8);
	Mix_FreeMusic(music9);
	Mix_FreeChunk(chunk_star);
	Mix_FreeChunk(chunk_don);
	
	Mix_FreeChunk(chunk_miss);
	Mix_FreeChunk(chunk_speedup);
	Mix_FreeChunk(chunk_bomb);
	Mix_FreeChunk(chunk_beep);
	Mix_FreeChunk(chunk_warning);
	Mix_FreeChunk(chunk_reverse);
	Mix_FreeChunk(voice_0);
	Mix_FreeChunk(voice_1);
	Mix_FreeChunk(voice_2);
	Mix_FreeChunk(voice_3);
	Mix_FreeChunk(voice_4);
	Mix_FreeChunk(voice_5);
	Mix_FreeChunk(voice_6);
	Mix_FreeChunk(voice_7);
	Mix_FreeChunk(voice_8);
	Mix_FreeChunk(voice_9);
}
public void nosound(bool s){
	_nosound = s;
	if(nosound){
		Sound_HaltMusic();
		
	}
//	prefManager.prefData.recordNoSound(_nosound);
}
public bool nosound(){
	return _nosound;
}

public int Sound_PlayingMusic(){
	if(Mix_PlayingMusic() == 0)_Sound_PlayingMusic = -1;
	return _Sound_PlayingMusic;
}