package juum.xikin;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;

import de.sciss.jcollider.Buffer;
import de.sciss.jcollider.Server;
import de.sciss.jcollider.UGenInfo;

import juum.ControllerListener;

public class JuumSCollider implements ControllerListener{

	public static Hashtable<String, Buffer> soundsList;
	public static Server scServer;
	private Buffer bRecorder;
	
	public JuumSCollider(){
		
		soundsList = new Hashtable<String, Buffer>(); //for a easy way to call the sounds
		
		try {
			scServer = new Server("juum");
			//Server.setProgram("/Applications/SuperCollider/scsynth");
			Server.setProgram("C:\\\\Archivos de programa\\SuperCollider\\scsynth.exe");
			//JFrame serverPanel = ServerPanel.makeWindow(scServer);
			scServer.boot(true);
			
			ServerOptions so = scServer.getOptions();
			
			//while(scServer.isBooting()){
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			//}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		//new Thread(this).start();
		run();
	}

	private void run(){
		try {
			UGenInfo.readBinaryDefinitions();
		} catch (IOException e2) {
			e2.printStackTrace();
		}
		
		//new SynthDefs();
		
		System.out.println("sending all the sounds");
		
		recursiveAddSounds(new File("materials/sounds/"));
	}
	
	private void recursiveAddSounds(File directory){
		addSoundFiles(directory);
		File[] childs = getChildDirectories(directory);
		for(File item : childs) recursiveAddSounds(item);
	}
	
	private File[] getChildDirectories(File directory){
		Vector<File> vecDir = new Vector<File>();
		File[] fileNames = directory.listFiles();
		for(File item : fileNames){
			if(item.isDirectory()) vecDir.add(item);
		}
		File[] vecArray = new File[]{};
		return vecDir.toArray(vecArray);
	}
	
	private void addSoundFiles(File directory){
		//send all the sounds in the specify directory to the sc server
		File[] fileNames = directory.listFiles(new AudioFileFilter());
		for(File item : fileNames){
			try {
				
				if(soundsList.containsKey(item.getName())) System.out.println("WARNING: Loading sounds with the same name");
				
				Buffer buffer = Buffer.read(scServer,item.getAbsolutePath());
				if(buffer != null) {
					soundsList.put(item.getName(), buffer);
					System.out.println("Creating buffer for " + item.getName());
				}
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void resetSC(){
		try {
			scServer.getDefaultGroup().freeAll();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void initPerformance() {
		/*
		try {
			new Synth("basic", 
			         new String[]{"buf"},
			         new float[]{soundsList.get("source.aif").getBufNum()},
			         scServer.getDefaultGroup());
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
			bRecorder = Buffer.alloc(scServer, 65536, 2);
			bRecorder.write(System.getProperty("user.dir") + "/documents/" + System.currentTimeMillis() + ".aif", "aiff","int16",0,0,true);
			new Synth("recorder",
					new String[]{"buf"},
					new float[] {bRecorder.getBufNum()},
					scServer.getDefaultGroup());
			System.out.println("recorder created");
		} catch (IOException e) {
			e.printStackTrace();
		}
		*/
	}

	public void quit() {
		System.out.println("I am quiting sq");
		try {
			scServer.quit();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void stopPerformance() {
		try {
			//bRecorder.close();
			scServer.getDefaultGroup().freeAll();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void updateValues() {
		
	}
	
	class AudioFileFilter implements FilenameFilter {
	    public boolean accept(File dir, String name) {
	        return (name.toLowerCase().endsWith(".aiff") ||
	        		name.toLowerCase().endsWith(".aif") ||
	        		name.toLowerCase().endsWith(".wav") );
	    }
	}

	public void changeInText() {
	}

}
