package gameCanvasUtil;

import java.io.File;

import javax.sound.sampled.*;


/** サウンド(wav)を管理するクラス
 *
 * 連番のサウンドファイルをオンメモリに読み込んで管理を行う。
 */
public class soundManager implements soundManagerInterface{
	//サウンドを格納するオブジェクト
	private Clip audio[];
	
	//ファイル名　念のため保持
	private String fileName;
	

	/** サウンドの数などよきに計らえ **/
	public static final int NUMBER_AUTO_CULC = -1;
	/** サウンドリストをテキストから読み込みやがれ */
	public static final int READ_LIST_FROM_TEXT = -2;


	//サウンドの数
	private static final int SOUND_MAX_NUM=124;
	
	/** コンストラクタ
	 * 
	 * ここでは一気にファイルからサウンドを読み込んだりしちゃいます
	 * @param file 読み込む連番ファイル名の指定
	 * @param number サウンド数の指定。
	 * 何ファイルになるかわからない場合は"NUMBER_AUTO_CULC"を指定するとよきに計らいます。<br />
	 * また READ_LIST_FROM_TEXT を指定すると連番ファイル読み込みではなく、引数"file"を<br />
	 * サウンドのリストが書いてあるテキストファイルとして読み込み、そのリストに従ってサウンドを読み込みます。<br />
	 * (リストは一行に1ファイルずつ書いていく感じです。)
	 */
	public soundManager(String file,int number){
		this.fileName = file;
		
		if(number==NUMBER_AUTO_CULC){
			this.audio = new Clip[SOUND_MAX_NUM];
			this.loadNumberingSound(false);
		}else if(number==READ_LIST_FROM_TEXT){
			String list[] = saveDataUtil.readResourceStrings(file);
			this.audio = new Clip[list.length];
			for(int i=0;i<list.length;i++){
				this.audio[i] = this.loadSound(list[i]);
			}		
		}else{
			this.audio = new Clip[number];
			this.loadNumberingSound(true);
		}
		
	}
	
	/** 連番サウンドを読み込みます
	 * @param skip 読み込めなかった場合スキップするか？
	 * これがfalseだと、読み込めないと、そこで終了する。
	 */
	private void loadNumberingSound(boolean skip){
		for(int i=0;i<audio.length;i++){
			this.audio[i] = loadSound( fileName + i +".wav");
			if(this.audio[i]==null && !skip)
				break;
		}
	}
	
	/** ファイル名からクリップをロードする 
	 * @param file ファイル名
	 * @return 生成したクリップ
	 */
	private Clip loadSound(String file){
		Clip val = null;
		try{
			AudioInputStream audioInputStream = null;
			audioInputStream = AudioSystem.getAudioInputStream( this.getClass().getResourceAsStream("/"+file));
			
			 
			AudioFormat format = audioInputStream.getFormat(); 
			DataLine.Info info = new DataLine.Info( Clip.class , format ); 
			val = ( Clip ) AudioSystem.getLine( info );
			val.open(audioInputStream);
			audioInputStream.close();
		}catch(Exception e){
			System.out.println("loadSound Exception "+file+"::"+ e);
			return null;
		}
		return val;
	}
	
	/** サウンドの再生を行う
	 * @param id 再生する音のID
	 * @param loop ループを行うか？
	 */
	public void playSound(int id,boolean loop){
		try{
			if(audio[id].isActive()){ // 再生中ならとめる
				this.stopSound(id);
			}
			else if(audio[id].getFrameLength() == audio[id].getFramePosition()){	//最後まで行ったので巻き戻し
				audio[id].setFramePosition(0);			
			}
			if(loop){
				audio[id].loop(Clip. LOOP_CONTINUOUSLY);
			}else{
				audio[id].start();
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	/** サウンドの停止を行う
	 * @param id 停止する音のID
	 */
	public void stopSound(int id){
		try{
			audio[id].stop();
			//巻き戻し
			audio[id].setFramePosition(0);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	/** サウンドの一時停止を行う
	 * @param id 一時停止する音のID
	 */
	public void pauseSound(int id){
		try{
			audio[id].stop();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	/** 全てのサウンドを一時停止する
	 */
	public void pauseSound(){
		for(int i=0;i<audio.length;i++){
			pauseSound(i);
		}
	}
	
	/** 全てのサウンドを停止する
	 */
	public void stopSound(){
		for(int i=0;i<audio.length;i++){
			stopSound(i);
		}
	}
	/** 全てのサウンドの音量変更
	 */
	public void changeVolume(int vol){
		for(int i=0;i<audio.length;i++){
			changeVolume(i,vol);
		}
	}
	
	/** サウンドの音量を変更する
	 * @param id どの音を変更するか？
	 * @param vol　音の大きさを指定(0-100)
	 */
	public void changeVolume(int id,int vol){
		if(audio[id]==null)
			return;
		try{
			FloatControl control = (FloatControl)audio[id].getControl(FloatControl.Type.MASTER_GAIN);
			float range = control.getMaximum() - control.getMinimum();
			control.setValue( range * (float) Math.sqrt(vol / 100.0f) + control.getMinimum() );
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	/** サウンドの更新処理(何もしない)
	 */
	public void update(){
	}
}
