///
/// add() : Add a ColorSeries with "levels" levels to the stack.
///
void ColorSeriesStack::add(unsigned levels){
	
	
	// 2015.09.15.ET: "levels" here is the number of NON-MISSING levels and it is possible
	//                and in fact likely to only have one NON-MISSING level
	
	ColorSeries *pCS;
	
	unsigned n = _colorSeriesStack.size();
	
	if(n<DrawingMetrics::monochromat.size()){
		//
		// Use predefined color series based on DrawingMetrics colors:
		//
		switch(_type){
		case BLACKANDWHITE:
			pCS = new ColorSeries(levels,DrawingColor("black","#000"));
			break;
		case MONOCHROMATIC:
			pCS = new ColorSeries(levels,DrawingMetrics::monochromat[n]);
			break;
		case BICHROMATIC:
			pCS = new ColorSeries(levels,DrawingMetrics::monochromat[n],DrawingMetrics::bichromat[n]);
			break;
		}
	}else{
		
		if( _type==BLACKANDWHITE ){
			pCS = new ColorSeries(levels,DrawingColor("black","#000"));
		}else{
			//
			// Use random colors:
			//
			RandomGenerator r;
			DrawingColor color1;
			//
			// Randomly choose a color with at least 50% saturation and 50% value:
			// i.e., we choose relatively brighter and more saturated colors ...
			//
			color1.setFromHSV(r.getIntegerInRange(0,360),r.getIntegerInRange(50,100),r.getIntegerInRange(50,100));
			
			if(_type==BICHROMATIC){
				// Set color2 to the complement of color1:
				DrawingColor color2;
				color2.set(color1.getComplement());
				pCS = new ColorSeries(levels,color1,color2);
			}else{
				pCS = new ColorSeries(levels,color1);
			}
		}
	}
	_colorSeriesStack.push_back(pCS);
	
}
//
// Constructor:
//
ColorSeries::ColorSeries(unsigned levels,const DrawingColor &endColor,const DrawingColor &startColor){
	
	_levels   = levels;
	// Force series to have at least two levels always:
	if(_levels<2) _levels=2;
	
	_endColor   = endColor;
	_startColor = startColor;
	
	//
	// Create series:
	//
	double startH,startS,startV;
	startH = startColor.getHue();
	startS = startColor.getSaturation();
	startV = startColor.getValue();
	
	//
	// If the start color is not
	// white (the default), then
	// create a purely linear bichromatic
	// color series:
	//
	bool startColorIsWhite = ( startS==0.0 && startV==1.0);
	
	double endH,endS,endV;
	endH = endColor.getHue();
	endS = endColor.getSaturation();
	endV = endColor.getValue();
	
	//
	// Handle achromatic end points correctly:
	// If the start color is white, then the Hue is
	// undefined, so use the hue of the ending color
	// in order to get a smooth monochromatic color
	// series:
	//
	if( startH == -1) startH = endH;
	
	double deltaH,deltaS,deltaV;
	deltaH = endH - startH;
	deltaS = endS - startS;
	deltaV = endV - startV;
	
	double h,s,v,fraction;
	
	for(unsigned i=0;i<_levels;i++){
		
		if( startColorIsWhite && _levels<=5){
			//
			// When the start color is white and there
			// are five or fewer steps in the series,
			// use non-linearly spaced colors from the
			// saturations table:
			//
			h = startH + deltaH * _saturations[_levels][i];
			s = startS + deltaS * _saturations[_levels][i];
			v = startV + deltaV * _saturations[_levels][i];
			
		}else{
			// For bichromatic series or when there are
			// more than five levels, just use linear spacing
			// 
			// For monochromatic series, this works OK for 6
			// and maybe even 7 levels : More than 7 levels
			// is definitely not recommended:
			//
			fraction = (double)i/(double)(_levels-1);
			h = startH + deltaH * fraction;
			s = startS + deltaS * fraction;
			v = startV + deltaV * fraction;
			
		}
		_colorSeries.push_back( DrawingColor(endColor.getName(),h,s,v));
	}
}