/**
Load climate data sets for the SBEII
Two text files are loaded into two arrays: RO_refr.txt and RO_temp.txt

KV, BCL, 02/2010
**/

// Server.default = s = Server.internal; 
s.boot;

	////////////  mal alles einlesen
(
q = ();

q.myPath = Document.current.dir; 
q.refracfile = q.myPath ++ "/RO_refr.txt";
q.tempfile = q.myPath ++ "/RO_temp.txt";

// CHOOSE: TEMEPERATURE auf emphehlung der domain expertin
//q.myfile = q.refracfile;
q.myfile = q.tempfile;

a = FileReader.read(q.myfile);
//a.printAll;
// header: a[0..19].printAll;

// latitudes north (18)
q.latitudes = a[20..22].collect({|item| item.asFloat}).flat.removeEvery([0.0]);
//q.latitudes.size;

// header: a[23..24].printAll;
// height levels in m (9)
q.heightlevs = a[25..26].collect({|item| item.asFloat}).flat.removeEvery([0.0]);
//q.heightlevs.size;

// header: a[27..28];
// time steps (julian time)
q.timejul = a[29..49].collect({|item| item.asFloat}).flat.removeEvery([0.0]);
//q.timejul.size;

//header: a[50];
// time steps: calender time, YYYY-MM-DD
q.timecal = a[51..71].collect({|item, i| 
	var aii = Array.new; 
	item.do{|jtem| aii = aii ++ ([jtem.keep(4)++jtem[5..6]++jtem[8..9]]);}; 
	// 	change date to YYYYMMDD without "-"
	aii.asFloat;
}).flat.removeEvery([0.0]);
//q.timecal.size;

// header: a[72]
// first time step, 162 entries (18 latitudes x 9 heightlevs):
a[73..99].asFloat.collect({|item| item}).flat.removeEvery([0.0]);

q.blanks = (q.timejul.size).collect{|i| (73+(27*(i))+i-1) };
q.data = Array.fill(q.timejul.size);
//first entry:
//a[73..100].collect({|item| item.asFloat}).flat.removeEvery([0.0]);
// all the rest of data:
q.blanks.do{|bs, bi|
	if (bi < (q.timejul.size-1)) 
		{q.data[bi] = 
		(a[bs..(q.blanks[(bi+1)]-1)].collect({
			|item| item.asFloat
		}).flat.removeEvery([0.0])).clump(q.latitudes.size)}
		{// last data index
		q.data[bi] = 
		(a[bs..(a.lastIndex)].collect({
			|item| item.asFloat
		}).flat.removeEvery([0.0])).clump(q.latitudes.size)};
};

// remove first 8 months (which are Nans)
q.data = q.data[8..];

// remove first 8 months (which are Nans)
q.data = q.data.drop(-5);

// replace nans in the middle with interpolated! 

q.data[58] = q.data[57] + q.data[59] * 0.5;

q.datarange = [ q.data.flat.maxItem, q.data.flat.minItem];	// scaling info - 180 - 260

)
	// tests
q.data.shape;		// 83 monate, 9 hoehen, 18 breitengrade
q.data.flat.any(_.isNaN).not // true - alles OK

// 18th month, 5th height, equator:
q.data.slice(18, 5, 9)

// all months, 5th height, equator:
q.data.slice(nil, 5, 9)

(
q.makeBuf = {|ev, level = 6, latitude = 9| // (equator)
	// all months, 8th level, equator:
	q.topSlice = q.data.slice(nil, level, latitude);

	// value interpolation
	q.topSlice.detectIndex{|val| val.isNaN};
	// -> 58
	q.topSlice[58] = (q.topSlice[57] + q.topSlice[59]) * 0.5;

	if (q.topBuf.isNil) { 
		q.topBuf = Buffer.loadCollection(s, q.topSlice.normalize);
	} {
		q.topBuf.loadCollection(q.topSlice.normalize);
	}
}
)
/*	test
	q.topSlice.plot
*/	

q.makeBuf(6, 7)

// equator
q.makeBuf(6, 9)

// southpole
q.makeBuf(6, 0)

// northpole
q.makeBuf(6, 17)

// pole
q.makeBuf(6, 17)

q.topBuf

q.topBuf.play(loop: true)

(
Spec.add(\rate, ControlSpec(0.000001, 1, warp: \exp, step:0));
Spec.add(\filterOn, [0, 1]);

Ndef(\blip).edit;
Ndef(\blip, {|rate = 0.1, filterOn = 1, filtRQ = 0.1|
	var loopFreq = rate / (q.topBuf.duration);
	var freqs2Filter = loopFreq * [ 1, 2, 5, 6, 7, 8];
	var rawBuf = PlayBuf.ar(1, q.topBuf, rate: rate, loop: 1);
	var amp;
	var bufplay = rawBuf;
	freqs2Filter.do { |ff| 
		bufplay = (BRF.ar(bufplay, ff, filtRQ)) 
	};
	bufplay = (bufplay * filterOn) + (1 - filterOn * rawBuf);
	
	amp = Amplitude.kr(LeakDC.ar(bufplay), 0, 0.3).poll(1);
	
	Limiter.ar(
		LPF.ar(SinOsc.ar(bufplay.exprange(100, 400)), 2000) * amp ! 2
	)
})
)
Ndef(\blip).play(vol: 0);
Ndef(\blip).stop;

//////////////// versuch 2: 
	alle breiten gleichzeitig hoeren, 
	spaeter gewichtung / fokus einbauen
	
(
	// alle breiten
q.dataHLT = q.data.flop.collect(_.flop);
q.dataHLT.shape.postln;  // 9 heights. 18 lati-zones, 83 zeitwerte
q.hiBufs = q.dataHLT.collect { |height, i| 
	Buffer.loadCollection(s, height.flat - 180 / 75, height.size)
}	
)

(
Spec.add(\loopFreq, [0.01, 100, \exp]);
Spec.add(\buf, [0.01, 100, \exp]);
Spec.add(\playOn, [0, 1, \lin, 1]);
Spec.add(\shift, [0, 82, \lin]);
Spec.add(\buf, [q.hiBufs.collect(_.bufnum).minItem, q.hiBufs.collect(_.bufnum).maxItem, \lin, 1]);
Ndef(\alle, { |loopFreq = 1, playOn = 1, shift = 0, buf = 1 | 
	var index = Phasor.ar(0, loopFreq / s.sampleRate, 0, 1 * playOn) * 83;
	var temps = BufRd.ar(18, buf, (index + shift).poll(1));
	
	SplayAz.ar(
		6, 
		SinOsc.ar(temps.exprange(100, 4000))
		* LFPulse.kr(temps.range(5, 20), 0, 0.03)
	) * 0.1
}).playN(vol: 0);
Ndef(\alle).set(\buf.asSpec.minval);
Ndef(\alle).edit;
)
Ndef(\alle).set(\buf, q.hiBufs[0].bufnum)
Ndef(\alle).set(\buf, q.hiBufs[1].bufnum)
Ndef(\alle).set(\buf, q.hiBufs[3].bufnum)
Ndef(\alle).set(\buf, q.hiBufs[8].bufnum)