package main;

import com.softsynth.jsyn.*;

public class WaveForm extends SynthNote {
	
	EnvelopePlayer envPlayer;
	SynthEnvelope env;
	SynthInput envRate;
	SynthInput spectrum;
	int noOsc = 5;
	//Set random phase
	SineOscillator[] oscBank = new SineOscillator[noOsc];
	BusWriter[] busWriter = new BusWriter[noOsc];
	MultiplyUnit[] multAmp = new MultiplyUnit[noOsc];
	MultiplyUnit[] multFreq = new MultiplyUnit[noOsc];
	LineOut  lineOut;
	BusReader busReader;
	SynthDistributor freqDist = new SynthDistributor("frequency");
	SynthDistributor spectrumDist = new SynthDistributor("spectrum");
	double[] envData;
	SynthEnvelope glissEnv;
	
	public WaveForm() {
		super();
		add(envPlayer = new EnvelopePlayer());
		add(busReader = new BusReader());
		
		add(busWriter[0] = new BusWriter());
		add(oscBank[0] = new SineOscillator());
		add(lineOut = new LineOut());
		
		double randomPhase = Math.random();
		oscBank[0].phase.set(randomPhase);
		
		oscBank[0].frequency.connect(freqDist);
		oscBank[0].output.connect(busWriter[0].input);
		busWriter[0].busOutput.connect(busReader.busInput);
		
		
		for(int i = 1; i < noOsc; i++){
			add(busWriter[i] = new BusWriter());
			add(oscBank[i] = new SineOscillator());
			add(multFreq[i] = new MultiplyUnit());
			add(multAmp[i] = new MultiplyUnit());
			multFreq[i].inputA.set(i+1.);
			multFreq[i].inputB.connect(freqDist);
			multFreq[i].output.connect(oscBank[i].frequency);
			multAmp[i].inputA.set(1./(i+1.));
			multAmp[i].inputB.connect(spectrumDist);
			multAmp[i].output.connect(oscBank[i].amplitude);
			oscBank[i].output.connect(busWriter[i].input);
			busWriter[i].busOutput.connect(busReader.busInput);
			envPlayer.output.connect(busReader.amplitude);
			
			oscBank[i].phase.set(randomPhase);
		}
		
		addPort(amplitude = envPlayer.amplitude);
		addPort(frequency = freqDist);
		addPort(envRate = envPlayer.rate);
		addPort(output = busReader.output);
		addPort(spectrum = spectrumDist);
		
		//double[] envData = { .5, 1.0, .5, 0.0 };
		envData = new double[42];
		for (int i = 0; i < 21; i++) {
			envData[i*2] = 1/20.;
			envData[i*2+1] = (Math.cos(2*(1/20.*i)*Math.PI+Math.PI)+1)/2;
			//System.out.println(envData[i*2] + " " + envData[i*2+1]);
		}
		env = new SynthEnvelope(envData);
		
		frequency.set(400);
		amplitude.set(1.);
		spectrum.set(0);
	}
	
	public void grainOn(int t, double f, double a) {
		start(t);
		frequency.set(t, f);
		amplitude.set(t, a);
		//spectrum.set(arg0);
		envPlayer.envelopePort.clear(t);
		envPlayer.envelopePort.queue(env,0,env.getNumFrames(),Synth.FLAG_AUTO_STOP);
		//envPlayer.envelopePort.queueLoop(t, env, 1, 1);
		
	}
	
	public void clickOn(int t, double f, double a) {
		
		start(t);
		frequency.set(t, f);
		amplitude.set(t, a);
		//spectrum.set(arg0);
		envPlayer.envelopePort.clear(t);
		envPlayer.envelopePort.queue(env,0,env.getNumFrames(),Synth.FLAG_AUTO_STOP);
		//envPlayer.envelopePort.queueLoop(t, env, 1, 1);
		
	}
	
	public void glissOn(int t, double f, double a , double[] eD) {
		glissEnv = new SynthEnvelope(eD);
		start(t);
		frequency.set(t, f);
		amplitude.set(t, a);
		envPlayer.envelopePort.clear(t);
		envPlayer.envelopePort.queue(t,glissEnv,0,glissEnv.getNumFrames(), Synth.FLAG_AUTO_STOP);
		
	}
	
	
	public void glissOff(int t, double r) {
		envRate.set(t, r);
		envPlayer.envelopePort.clear(t);
		envPlayer.envelopePort.queue(t, glissEnv, glissEnv.getNumFrames() - 1, 1, Synth.FLAG_AUTO_STOP);
	}
}
