//// by Lance Putnam
//// lance@uwalumni.com
//
//SCEnvelopeEdit : SCEnvelopeView {
//	var <env, <pointsPerSegment, viewPoints;
//	var <minLevel, <maxLevel, <minTime, <maxTime, totalDurRec, absTimes, numPoints;
//
//	*viewClass { ^SCEnvelopeView }
//
//	*new { arg parent, bounds, env, pointsPerSegment=10;
//		^super.new(parent, bounds).initSCEnvelopeEdit(env, pointsPerSegment)
//	}
//
//	initSCEnvelopeEdit { arg argEnv, argPPS;
//		env = argEnv;
//		pointsPerSegment = argPPS.asInteger;
//		minLevel = 0;
//		maxLevel = 1;
//		minTime = 0;
//		maxTime = env.times.sum;
//		totalDurRec = 1/(maxTime - minTime);
//
//		absTimes = Array.newClear(env.times.size + 1);
//		absTimes[0] = 0;
//		for(1, env.times.size, { arg i;
//			absTimes[i] = absTimes[i-1] + env.times[i-1];
//		});
//
//		numPoints = (pointsPerSegment * env.times.size) + 1;  // add 1 for the last point
//		viewPoints = Array.with(Array.newClear(numPoints), Array.newClear(numPoints));
//
//		this
//			.selectionColor_(Color.clear)
//			.drawLines_(true)	// resize broken when no lines drawn
//			.drawRects_(true)
//		;
//
//		this.action = { arg view;
//			var bp, bpm1, bpp1, bpLevel, timePos;
//
//			// if it's a breakpoint
//			if((view.index % pointsPerSegment) == 0, {
//				bp = view.index.div(pointsPerSegment);
//				bpm1 = bp - 1;
//				bpp1 = bp + 1;
//
//				bpLevel = view.currentvalue.linlin(0.0, 1.0, minLevel, maxLevel);
//				env.levels[bp] = bpLevel;
//
//				timePos = view.value[0][view.index].linlin(0.0, 1.0, minTime, maxTime);
//
//				// first breakpoint
//				if(bp == 0, {
//					if( timePos <= absTimes[bpp1], {
//						env.times[bp] = absTimes[bpp1] - timePos;
//						absTimes[bp] = timePos;
//					},{ // going past right break point
//						env.times[bp] = 0;
//						absTimes[bp] = absTimes[bpp1];
//					});
//					this.updateSegment(bp);
//				// end breakpoint
//				},{ if(bp == env.times.size, {
//					if( timePos >= absTimes[bpm1], {
//						env.times[bpm1] = timePos - absTimes[bpm1];
//						absTimes[bp] = timePos;
//					},{	// going past left break point
//						env.times[bpm1] = 0;
//						absTimes[bp] = absTimes[bpm1];
//					});
//					this.updateSegment(bpm1);
//				// a middle break point
//				},{
//					if(timePos > absTimes[bpp1], {	// past right break point
//						env.times[bpm1] = absTimes[bp] - absTimes[bpm1];
//						env.times[bp] = 0;
//						absTimes[bp] = absTimes[bpp1];
//					},{ if(timePos < absTimes[bpm1], { // past left break point
//						env.times[bpm1] = 0;
//						env.times[bp] = absTimes[bpp1] - absTimes[bp];
//						absTimes[bp] = absTimes[bpm1];
//					},{
//						// set left segment dur
//						env.times[bpm1] = timePos - absTimes[bpm1];
//
//						// set right segment dur
//						env.times[bp] = absTimes[bpp1] - timePos;
//
//						absTimes[bp] = timePos;
//					}); });
//					this.updateSegment(bpm1);
//					this.updateSegment(bp);
//					if((timePos <= absTimes[bpp1]) && (timePos >= absTimes[bpm1]), {
//
//
//					});
//				}); });
//
//				this.redraw;
//			});
//		};
//
//		this.updateAll;
//		this.redraw;
//
//		numPoints.do({ arg i;
//			// make a breakpoint
//			if((i%pointsPerSegment) == 0, {
//				this.setThumbSize(i, 6);
//
//				// color code breakpoints
//				if(i.div(pointsPerSegment) == env.releaseNode, {
//					this.setFillColor(i, Color.red(0.7));
//				},{
//					if(i.div(pointsPerSegment) == env.loopNode, {
//						this.setFillColor(i, Color.green(0.7));
//					},{
//						this.setFillColor(i, Color.blue(0.7));
//					});
//				});
//
//			// Other points should be hidden.
//			},{ this.setThumbSize(i, 0) });
//		});
//
//	}
//
//	redraw {
//		this.value = viewPoints;
//	}
//
//	refresh {
//		this.updateAll;
//		this.value = viewPoints;
//	}
//
//	updateAll {
//		env.times.size.do({ arg i;
//			this.updateSegment(i);
//		});
//	}
//
//	// updates segment values in viewPoints array
//	updateSegment { arg segNum;
//		var time, slope, index1, index2, timeOffset;
//
//		// update envelope cache
//		env.times = env.times;
//		env.levels = env.levels;
//		env.curves = env.curves;
//
//		segNum = segNum.asInteger;
//
//		time = absTimes[segNum];
//		timeOffset = absTimes[0];
//
//		slope = env.times[segNum] / pointsPerSegment;
//
//		index1 = pointsPerSegment * segNum;
//		index2 = index1 + pointsPerSegment - 1;
//
//		for(index1, index2, { arg i;
//			viewPoints[0][i] = time.linlin(minTime, maxTime, 0.0, 1.0);
//			viewPoints[1][i] = env[time - timeOffset].linlin(minLevel, maxLevel, 0.0, 1.0);
//			time = time + slope;
//		});
//
//		// draw break point at right level
//		if(slope == 0, {
//			viewPoints[1][index1] = env.levels[segNum].linlin(minLevel, maxLevel, 0.0, 1.0);
//		});
//
//		// the last segment has an extra point at the end
//		if(segNum == (env.times.size-1), {
//			index2 = index2 + 1;
//			viewPoints[0][index2] = time.linlin(minTime, maxTime, 0.0, 1.0);
//			viewPoints[1][index2] = env.levels.last.linlin(minLevel, maxLevel, 0.0, 1.0);
//		});
//	}
//
//	minLevel_ { arg level;
//		minLevel = level;
//		this.refresh;
//	}
//
//	maxLevel_ { arg level;
//		maxLevel = level;
//		this.refresh;
//	}
//
//	minTime_ { arg sec;
//		minTime = sec;
//		this.refresh;
//	}
//
//	maxTime_ { arg sec;
//		maxTime = sec;
//		this.refresh;
//	}
//}