(
a = Collective.new;
b = Collective.new;

a.start;
b.start;

a.autoCollect;
b.autoCollect;
)

(
a.makeWin;
b.makeWin;
);

a.fixConnections; // just if the connections don't work.
a.postPairs;

(
var drawing;
var format = [340, 360];
var colors = [Color.black, Color.gray];
var penWidth = 1;

#e, f = [a, b].collect();

// based on example of SCUserView
drawing = { | collective, i |

	var w, v, txt, tmppoints, undone, all,  participation;
	tmppoints = (); // dictionary for temp data of each collaborator
	undone = ();
	all = ();
	w = GUI.window.new("draw on" + collective.myName, 
		Rect(128, 64 + (format[1] + 10 * i), format[0], format[1])
	);
	w.view.background= colors[1];
	
	participation = Participation(collective).start;
	
	participation.addResponder('/track', { |t,r,msg|
		var point = msg[2] @ msg[3];
		var name = msg[1];
		tmppoints[name] = tmppoints[name].add(point);
		defer { w.refresh };
	});
	participation.addResponder('/endTrack', { |t,r,msg|
		var name = msg[1];
		all[name] = all[name].add(tmppoints[name].copy);
		tmppoints[name] = [];
		defer { w.refresh };
	});
	participation.addResponder('/undo', { |t,r,msg|
		var name = msg[1];
		undone[name] = undone[name].add(all[name].pop);
		defer { w.refresh };
	});
	participation.addResponder('/redo', { |t,r,msg|
		var name = msg[1];
		var points = undone[name].pop;
		points !? { all[name].add(points) };
		defer { w.refresh };
	});
	v = GUI.userView.new(w, w.view.bounds)
		.mouseTrackFunc_({|v,x,y|
			if(participation.isListening) {
				collective.sendToEach('/track', collective.myName, x, y);
			}
		})
		.mouseEndTrackFunc_({|v,x,y|
			if(participation.isListening) {
				collective.sendToEach('/endTrack', collective.myName);
			}
		})
		.keyDownFunc_({|v, key|
			if(key == $z) {
				if(participation.isListening) {
					collective.sendToEach('/undo', collective.myName);
				}
			};
			if(key == $Z) {
				if(participation.isListening) {
					collective.sendToEach('/redo', collective.myName);
				}
			};
		});
	
	w.drawHook_{
		GUI.pen.use {	
			GUI.pen.width = penWidth;
			colors[0].set;
			GUI.pen.beginPath;
			
			tmppoints.do{	|points|
				points.do {|p, i|
					if(i == 0){
					GUI.pen.moveTo(p);
					}{
					GUI.pen.lineTo(p);
					}
				}
			};
			all.do {|pointList|
				pointList.do{|points|
					points.do{|p, i|
						if(i == 0){
							GUI.pen.moveTo(p);
						}{
							GUI.pen.lineTo(p);
						}
					};
				};
			};
			GUI.pen.stroke;
		};
	};

	w.front;
};

[a, b].do(drawing);
)

/////////////////// the end:

[a, b].do(_.stop);