/* For general info, see Alpes-TaDa.rtf */

	// useful functions to have
(
q = q ? ();	// q is a Dictionary for storing things by name.

	// mac and linux only
q.localDir = Document.current.path.dirname; 
	// on win, put in the path where this textfile is
// 	q.localDir = "C:/Wherever/this/file/maybe";

	// a 10x10km grid of height values, 78x108 points (Alps);
q.readHeightData = { |q, path|
	var file = File(path, "rb");
	var array = FloatArray.newClear(78 * 108);
	file.read(array);
	array;
};

q.readRainDays = { |q, path, days|
	var array;
	if (days.size == 0, {days = [days]});
	array = Array.new(days.size);
	days.do({ |day|
		var da = FloatArray.newClear(78 * 108);
		var file = File(path, "rb");
		file.seek(day * 78 * 108 * 4, 0);
		file.read(da);
		array.add(da);
		file.close;
	});
	array.flatten;
};

q.readAllRainDays = { |q, path |
	var file = File(path, "rb");
	var array = FloatArray.newClear(78 * 108 * 4018);
	file.read(array);
	file.close;
	array;
};

	// MTX writer for Pure Data
q.writeMtx = { |q, path, data|
	var file = File(path, "w"); 
	file.write("matrix" ++ Char.tab ++ (data.size/(78*108)) ++ Char.tab ++ (78*108) ++ Char.nl);
	data.clump(78*108).flop.do({ |line| 
		line.do({ |x, i| file.write(x.asString); if( i<line.size,{ file.write(Char.tab) }) });
		file.write(Char.nl);
	});
	file.close;
};

		// make a window to show one frame of data. mac only.
q.makeWin = {	 
	q.pixsize = 3;
	q.win = SCWindow("The Alpes", Rect(0,0, 108 * q.pixsize, 78 * q.pixsize)).front;
	q.win.view.background_(Color.grey);
	q.win.drawHook = { 
		var black, white;
		black = Color.black; white = Color.white; 
		q.frontFrame.do { |line, i| 
			line.do { |val, j| 
				Color.grey(val).set;
				Pen.addArc( (j * q.pixsize)@(i * q.pixsize), 3, 0, 2pi);
				Pen.fill;
			}
		}
	};
	q.win.refresh;
};
q.makeWin;

q.toFront = { |q, frame| 
	q.frontFrame = frame.normalize(0,1).clump(108); 
	defer { try { q.win.refresh; } };
	frame;
};
)

// create MTX file for rain data (very big, very time consuming...)
q.writeMtx(q.localDir ++ "/RainData.mtx", q.readAllRainDays(q.localDir ++ "/Rain+HeightData/PRE24____.bin"));
q.writeMtx(q.localDir ++ "/RainDay0.mtx", q.readRainDays(q.localDir ++ "/Rain+HeightData/PRE24____.bin", 0));
q.writeMtx(q.localDir ++ "/RainDay1-3.mtx", q.readRainDays(q.localDir ++ "/Rain+HeightData/PRE24____.bin", [1, 2, 3]));
	
// read in the terrain & all rain data, display terrain
(
q.terrain = q.readHeightData(q.localDir ++ "/Rain+HeightData/TERRAIN__.bin");
q.writeMtx(q.localDir ++ "/Terrain.mtx", q.terrain);
q.toFront(q.terrain);
)

// show single rain days
(
q.rainDay = q.readRainDays(q.localDir ++ "/Rain+HeightData/PRE24____.bin", 0);
q.toFront(q.rainDay);
)

// show the first 20 rainy days...
(
Tdef(\show, {
	20.do({ |i|
		q.rainDay = q.readRainDays(q.localDir ++ "/Rain+HeightData/PRE24____.bin", i);
		q.toFront(q.rainDay);
		0.1.wait;
	});
	"done".postln;
}).play(AppClock);
)
Tdef(\show).play;
Tdef(\show).stop;

/****** Sonification sketches: *****/
/* what can we listen for? 

p = ProxySpace.push;

ProxySynthDef.sampleAccurate_(true);
(
~drop = { |freq=500, rise=1.4, sus=0.1, amp=0.1, pan=0.0, att=0.1|
	Pan2.ar(
		SinOsc.ar(XLine.kr(freq, freq * rise, 0.1), att * 0.5pi)
		* (XLine.kr(amp, amp * 0.01, sus, doneAction: 2)
			* AmpComp.ir(freq)),
		pan
	);
};
)

~drop.play;
~drop.spawn([\freq, 600]);
~drop.spawn([\freq, 800, \sus, 0.05]);
~drop.spawn([\freq, 800, \sus, 0.01]);

(			// 16-20% in proxyspace
Tdef(\rain, { 
	loop { 	
		~drop.spawn([
			\out, rrand(0, 24),
			\freq, rrand(300, 1000), 
			\sus, exprand(0.02, 0.03),
			\amp, exprand(0.001, 0.03),
			\pan, 1.0.rand2,
			\att, 0.0.rand
		]);
		(exprand(0.0001, 0.01) * 0.25).wait;
	}
}).play;
)

~drop.stop;