/// Part of my old D1 game library along with [arsd.screen] and [arsd.engine]. Do not use in new projects.
module arsd.audio;

import sdl.SDL;
import sdl.SDL_mixer;

import arsd.engine;

bool audioIsLoaded; // potential hack material

class Sound {
  public:
	this(char[] filename){
		if(!audioIsLoaded)
			return;
		sfx = Mix_LoadWAV((filename ~ "\0").ptr);
		if(sfx is null)
			throw new Exception(immutableString("Sound load " ~ filename));
	}

	/*
	this(Wav wav){
		auto w = wav.toMemory;
		SDL_RWops* a = SDL_RWFromMem(w, w.length)
		if(a is null) throw new Exception("sdl rw ops");
		scope(exit) SDL_FreeRW(a);
		sfx = Mix_LoadWAV_RW(a, 0);
		if(sfx is null) throw new Exception("loadwav rw");
	}
	*/

	~this(){
		if(sfx !is null)
			Mix_FreeChunk(sfx);
	}

  private:
	Mix_Chunk* sfx;
}

class Music {
  public:
	this(char[] filename){
		if(!audioIsLoaded)
			return;
		mus = Mix_LoadMUS((filename~"\0").ptr);
		if(mus is null)
			throw new Exception(immutableString("Music load " ~ filename));
	}

	~this(){
		if(mus !is null)
			Mix_FreeMusic(mus);
	}
  private:
	Mix_Music* mus;
}

class Audio{
  public:
	this(bool act = true){
		if(audioIsLoaded)
			throw new Exception("Cannot load audio twice");

		if(!act){
			audioIsLoaded = false;
			active = false;
			return;
		}
		if(Mix_OpenAudio(22050, AUDIO_S16SYS, 2, 4096/2 /* the /2 is new */) != 0){
			active = false; //throw new Error;
			error = true;
			audioIsLoaded = false;
		} else {
			active = true;
			error = false;
			audioIsLoaded = true;
		}

		sfxChannel = 1;

		careAboutErrors = false;
	}

	void activate(){
		if(!audioIsLoaded) return;
		if(!error)
			active = true;
	}

	void deactivate(){
		if(!audioIsLoaded) return;
		active = false;
	}

	void toggleActivation(){
		if(!audioIsLoaded) return;
		if(error)
			return;
		active = !active;
	}

	~this(){
		if(audioIsLoaded){
			Mix_HaltMusic();
			Mix_HaltChannel(-1);
			Mix_CloseAudio();
		}
	}

	void playEffect(Sound snd, bool loop = false){
		if(!active || snd is null)
			return;

		//if(Mix_Playing(sfxChannel))
		//	return;

		sfxChannel = Mix_PlayChannel(-1, snd.sfx, loop == true ? -1 : 0);

	}
	void stopEffect(){
		if(!active)
			return;

		Mix_HaltChannel(sfxChannel);
	}

	void playMusic(Music mus, bool loop = true){
		if(!active || mus is null)
			return;

		if(Mix_PlayMusic(mus.mus, loop == true ? -1 : 0) == -1)
			throw new Exception("play music");
		//	musicIsPlaying = false;
		else
			musicIsPlaying = true;
	}

	void pauseMusic(){
		if(!active)
			return;

		if(musicIsPlaying){
			Mix_PauseMusic();
			musicIsPaused = true;
		}
	}

	void unpauseMusic(){
		if(!active)
			return;

		if(musicIsPaused){
			Mix_ResumeMusic();
			musicIsPaused = false;
		}
	}

	void stopMusic(){
		if(!active)
			return;

		Mix_HaltMusic();
	}


	void stopAll(){
		if(!active)
			return;

		Mix_HaltMusic();
		Mix_HaltChannel(-1);
	}

  private:
  	int sfxChannel;
	bool active;
	bool error;

	bool musicIsPaused;
	bool musicIsPlaying;

	bool careAboutErrors;
}

	int Mix_PlayChannel(int channel, Mix_Chunk* chunk, int loops) {
		return Mix_PlayChannelTimed(channel,chunk,loops,-1);
	}
	Mix_Chunk * Mix_LoadWAV(in char *file) {
		return Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1);
	}