///
/// DrawingCanvas::useWhiteInk()
///
///
///
bool DrawingCanvas::useWhiteInk(Individual *pIndividual){
	//
	// How many sections are there?
	//
	unsigned sections = pIndividual->getDataTable()->getIconColumnCount();
	if(!sections){
		return false;
	}else{
		const DataTable  * pDT = pIndividual->getDataTable();
		//
		// Well, we are only going to look at the first section of the pie
		// even if there are multiple sections ...
		//
		DataColumn * pDC = pDT->getColumn( pDT->getIconColumnIndex(0) );
		const UniqueList * pUL = pDC->getUniqueList();
		//
		// Only process if there are some non-missing levels present:
		//
		if(!pUL->getLevels()){
			
			return false;
			
		}else{
			//
			// What is the level and label in the UniqueList corresponding to the data value
			// for this individual?
			//
			unsigned level;
			std::string label;
			pUL->getOrdinalAndLabelForKey( pDC->getDataAtIndex( pIndividual->getRowIndex() ),label,level );
			//
			// UniqueList ordinals are 1-offset, so we should only get zero back
			// if the key was not found, which should never happen:
			//
			if(level==0) throw Exception("DrawingCanvas::useWhiteInk()","UniqueList returned ordinal 0.");
			//
			// Level is 1-offset, so subtract:
			//
			level--;
			//
			// Get the color series corresponding to this icon column:
			//
			ColorSeries *pCS;
			if(DrawingMetrics::getColor()){
				pCS = pDT->getColorSeriesFromStack(0);
			}else{
				pCS = pDT->getBlackAndWhiteSeriesFromStack(0);
			}
			if(pCS->useBlackInkAtLevel(level)){
				return false;
			}else{
				return true;
			}
		}
	}
}
///
/// iconPie(): Draws a pie with a given color on the individual icon. Each pie corresponds to one 
/// categorical variable. The color corresponds to the level in that variable. 
///
void DrawingCanvas::iconPie( double x, double y, Individual *pIndividual ){
	
	//
	// Handle virtual individuals:
	//
	if(pIndividual->isVirtual()){
		
		//_body << "<circle cx=\"" << x << "\" cy=\"" << y << "\" r=\"" << 0.5*DrawingMetrics::getScalingFactor() << "\"";
		//_body << " class=\"thinLine\"";
		//_body << "/>\n";
		return;
		
	}
	//
	// Get here if non-virtual:
	//
	
	//
	// How many sections are there?
	//
	unsigned sections = pIndividual->getDataTable()->getIconColumnCount();
	if(!sections){
		//
		// No affected fields : Draw a small circle in the middle:
		// (Nice for debugging -- otherwise comment out )
		//
		//_body << "<circle cx=\"" << x << "\" cy=\"" << y << "\" r=\"" << 0.5*DrawingMetrics::getScalingFactor() << "\"";
		//_body << " class=\"thinLine\"";
		//_body << "/>\n";
		return;
	}
	
	//
	// Setup clipping Id, if needed:
	//
	std::string clipId = pIndividual->getId().get() + "_clipPath";
	double radius=DrawingMetrics::getIconRadius();
	bool isMale = false;
	if( pIndividual->getGender().getEnum()==Gender::MALE ){
		
		setClipPath(x,y,clipId);
		//
		// Increase radius for clipping:
		//
		radius*=Number::SQRT_TWO;
		isMale = true;
		_body << "<g clip-path=\"url(#" << clipId << ")\">\n";
		
	}else{
		//
		// Empty g with no clipping for female:
		//
		_body << "<g>\n";
		
	}
	
	//
	// Iterate over _iconColumns:
	//
	const DataTable *pDT = pIndividual->getDataTable();
	double arcAngle = 2.0*Number::PI/sections;
	double startAngle = 0.5*Number::PI - arcAngle;
	double endAngle   = startAngle+arcAngle;
	for(unsigned i=0;i<sections;i++){
		//
		// Get the data column of the ith icon column:
		//
		DataColumn * pDC = pDT->getColumn( pDT->getIconColumnIndex(i) );
		//
		// Get the UniqueList for this column:
		//
		const UniqueList * pUL = pDC->getUniqueList();
		
		//
		// Only process if there are some non-missing levels
		// present:
		//
		if(!pUL->getLevels()) continue;
		
		//
		// What is the level and label in the UniqueList corresponding to the data value
		// for this individual?
		//
		unsigned level;
		std::string label;
		pUL->getOrdinalAndLabelForKey( pDC->getDataAtIndex( pIndividual->getRowIndex() ),label,level );
		//
		// UniqueList ordinals are 1-offset, so we should only get zero back
		// if the key was not found, which should never happen:
		//
		if(level==0) throw Exception("DrawingCanvas::iconPie()","UniqueList returned ordinal 0.");
		//
		// Level is 1-offset, so subtract:
		//
		level--;
		
		//
		// Get the color series corresponding to this icon column:
		//
		// NOTA BENE: (1) IF there is only one section, we use the 
		//                blackAndWhite series
		//                UNLESS there is a color override.
		//
		//            (2) OTHERWISE if there are more than one section, 
		//                we use the color series
		//                UNLESS there is a black-and-white override.
		//
		ColorSeries *pCS;
		if(sections==1){
			if(DrawingMetrics::getColor()) pCS = pDT->getColorSeriesFromStack(i);
			else                           pCS = pDT->getBlackAndWhiteSeriesFromStack(i);
		}else{
			if(DrawingMetrics::getBlackAndWhite()) pCS = pDT->getBlackAndWhiteSeriesFromStack(i);
			else                                   pCS = pDT->getColorSeriesFromStack(i);
		}
		//
		// Assume reversed for now:
		//
		bool reversed=true;
		std::string arcClass="blackInkLetter";
		if(!pCS->reversedSeriesUseBlackInkAtLevel(level)) arcClass="whiteInkLetter";
		
		//
		// If the number of sections is small, use a larger font size
		//
		
		if(sections == 1)      arcClass += "_1";
		else if(sections == 2) arcClass += "_2";
		else if(sections == 3) arcClass += "_3";
		arc(x,y,radius,startAngle,endAngle,(reversed?pCS->reversedSeriesGetColorAtLevel(level):pCS->getColorAtLevel(level)),label,arcClass,isMale);
		startAngle+=arcAngle;
		endAngle+=arcAngle;
		
		// For the first time draw the icon legend too:
		if(!_iconLegendFlag){
			_iconLegendFlag = true;
			_iconLegend.setPedigreeTable(pDT);
		}
		
	}
	_body << "</g>\n";
	return;
	
}
///
/// iconQuadrantFill(): Shade quadrants of the icon to indicate specific levels.
///                     This method has a limit of 16 distinct levels.
///
void DrawingCanvas::iconQuadrantFill( double x, double y, Individual *pIndividual ){
	
	//
	// Handle virtual individuals:
	//
	if(pIndividual->isVirtual()){
		
		return;
		
	}
	//
	// Get here if non-virtual:
	//
	
	//
	// How many sections are there?
	//
	unsigned sections = pIndividual->getDataTable()->getIconColumnCount();
	if(!sections){
		//
		// No affected fields : Draw a small circle in the middle:
		// (Nice for debugging -- otherwise comment out )
		//
		//_body << "<circle cx=\"" << x << "\" cy=\"" << y << "\" r=\"" << 0.5*DrawingMetrics::getScalingFactor() << "\"";
		//_body << " class=\"thinLine\"";
		//_body << "/>\n";
		return;
	}
	
	//
	// Setup clipping Id, if needed:
	//
	double radius=DrawingMetrics::getIconRadius();
	bool isMale = false;
	if( pIndividual->getGender().getEnum()==Gender::MALE ){
		
		std::string clipId = pIndividual->getId().get() + "_clipPath";
		setClipPath(x,y,clipId);
		//
		// Increase radius for clipping:
		//
		radius*=Number::SQRT_TWO;
		isMale = true;
		_body << "<g clip-path=\"url(#" << clipId << ")\">\n";
		
	}else{
		//
		// Empty g with no clipping for female:
		//
		_body << "<g>\n";
		
	}
	
	//
	// NOTA BENE: The quadrant fill method looks only at the 
	// FIRST iconColumn and ignores any additional icon columns:
	//
	const DataTable *pDT = pIndividual->getDataTable();
	//
	// Get the data column of the first icon column:
	//
	DataColumn * pDC = pDT->getColumn( pDT->getIconColumnIndex(0) );
	
	//
	// Get the UniqueList for this column:
	//
	const UniqueList * pUL = pDC->getUniqueList();
	//
	// Only process if there are some non-missing levels
	// present:
	//
	if(!pUL->getLevels()){
		_body << "</g>\n";
		return;
	}
	
	//
	// What is the level and label in the UniqueList corresponding to the data value
	// for this individual?
	//
	//unsigned level;
	//std::string label;
	//pUL->getOrdinalAndLabelForKey( pDC->getDataAtIndex( pIndividual->getRowIndex() ),label,level );
	//
	
	Data* data = pDC->getDataAtIndex( pIndividual->getRowIndex());
	//
	// Draw a dot for missing values:
	//
	if(data->isMissing()){
		drawText(x,y,".","blackInkLetter_1");
		_body << "</g>\n";
		return;
	}
	std::string label;
	std::string svalue = data->get();
	std::istringstream i(svalue);
	int level;
	bool converted = (i>>level);
	if(!converted || level<0 || level>15 ){
		//
		// (1) Unable to convert data string to integer, or
		// (2) integer value is out of range
		//
		double lineSpacing,xAdvance,yMinimum,yMaximum;
		_lasiWrapper.getDimensions(svalue,&lineSpacing,&xAdvance,&yMinimum,&yMaximum);
		y+= 0.5*(yMaximum-yMinimum);
		drawIconText(x,y,svalue,"blackInkLetter_1");
		_body << "</g>\n";
		return;
	}
	
	//
	// Fill arc for each quadrant based on level:
	// Note: Madeline's "arc()" method doesn't use the standard counter-clockwise quadrants
	// starting at 0, so the order of the 4 "if" statements below may appear mixed up but 
	// this actually results in shading of the quadrants according to standard notation:
	//
	if(level & 0x02 ){
		arc(x,y,radius,0,0.5*Number::PI,"#000",label,"whiteInkLetter",isMale);
	}
	if(level & 0x01 ){
		arc(x,y,radius,0.5*Number::PI,Number::PI,"#000",label,"whiteInkLetter",isMale);
	}
	if(level & 0x08 ){
		arc(x,y,radius,Number::PI,1.5*Number::PI,"#000",label,"whiteInkLetter",isMale);
	}
	if(level & 0x04 ){
		arc(x,y,radius,1.5*Number::PI,2.0*Number::PI,"#000",label,"whiteInkLetter",isMale);
	}
	
	//
	// For the first time draw the icon legend too:
	//
	//if(!_iconLegendFlag){
	//	_iconLegendFlag = true;
	//	_iconLegend.setPedigreeTable(pDT);
	//}
	
	_body << "</g>\n";
	return;
	
}