/* jslint node: true */
'use strict';


function groupDecorations(line) {
	var groups = [], curGroup = null;
	for(var i = 0, l = line.inlines.length; i < l; i++) {
		var inline = line.inlines[i];
		var decoration = inline.decoration;
		if(!decoration) {
			curGroup = null;
			continue;
		}
		var color = inline.decorationColor || inline.color || 'black';
		var style = inline.decorationStyle || 'solid';
		decoration = Array.isArray(decoration) ? decoration : [ decoration ];
		for(var ii = 0, ll = decoration.length; ii < ll; ii++) {
			var deco = decoration[ii];
			if(!curGroup || deco !== curGroup.decoration ||
					style !== curGroup.decorationStyle || color !== curGroup.decorationColor ||
					deco === 'lineThrough') {
		
				curGroup = {
					line: line,
					decoration: deco, 
					decorationColor: color, 
					decorationStyle: style,
					inlines: [ inline ]
				};
				groups.push(curGroup);
			} else {
				curGroup.inlines.push(inline);
			}
		}
	}
	
	return groups;
}

function drawDecoration(group, x, y, pdfKitDoc) {
	function maxInline() {
		var max = 0;
		for (var i = 0, l = group.inlines.length; i < l; i++) {
			var inl = group.inlines[i];
			max = inl.fontSize > max ? i : max;
		}
		return group.inlines[max];
	}
	function width() {
		var sum = 0;
		for (var i = 0, l = group.inlines.length; i < l; i++) {
			sum += group.inlines[i].width;
		}
		return sum;
	}
	var firstInline = group.inlines[0],
		biggerInline = maxInline(),
		totalWidth = width(),
		lineAscent = group.line.getAscenderHeight(),
		ascent = biggerInline.font.ascender / 1000 * biggerInline.fontSize,
		height = biggerInline.height,
		descent = height - ascent;
	
	var lw = 0.5 + Math.floor(Math.max(biggerInline.fontSize - 8, 0) / 2) * 0.12;
	
	switch (group.decoration) {
		case 'underline':
			y += lineAscent + descent * 0.45;
			break;
		case 'overline':
			y += lineAscent - (ascent * 0.85);
			break;
		case 'lineThrough':
			y += lineAscent - (ascent * 0.25);
			break;
		default:
			throw 'Unkown decoration : ' + group.decoration;
	}
	pdfKitDoc.save();
	
	if(group.decorationStyle === 'double') {
		var gap = Math.max(0.5, lw*2);
		pdfKitDoc	.fillColor(group.decorationColor)
					.rect(x + firstInline.x, y-lw/2, totalWidth, lw/2).fill()
					.rect(x + firstInline.x, y+gap-lw/2, totalWidth, lw/2).fill();
	} else if(group.decorationStyle === 'dashed') {
		var nbDashes = Math.ceil(totalWidth / (3.96+2.84));
		var rdx = x + firstInline.x;
		pdfKitDoc.rect(rdx, y, totalWidth, lw).clip();
		pdfKitDoc.fillColor(group.decorationColor);
		for (var i = 0; i < nbDashes; i++) {
			pdfKitDoc.rect(rdx, y-lw/2, 3.96, lw).fill();
			rdx += 3.96 + 2.84;
		}
	} else if(group.decorationStyle === 'dotted') {
		var nbDots = Math.ceil(totalWidth / (lw*3));
		var rx = x + firstInline.x;
		pdfKitDoc.rect(rx, y, totalWidth, lw).clip();
		pdfKitDoc.fillColor(group.decorationColor);
		for (var ii = 0; ii < nbDots; ii++) {
			pdfKitDoc.rect(rx, y-lw/2, lw, lw).fill();
			rx += (lw*3);
		}
	} else if(group.decorationStyle === 'wavy') {
		var sh = 0.7, sv = 1;
		var nbWaves = Math.ceil(totalWidth / (sh*2))+1;
		var rwx = x + firstInline.x - 1;
		pdfKitDoc.rect(x + firstInline.x, y-sv, totalWidth, y+sv).clip();
		pdfKitDoc.lineWidth(0.24);
		pdfKitDoc.moveTo(rwx, y);
		for(var iii = 0; iii < nbWaves; iii++) {
			pdfKitDoc   .bezierCurveTo(rwx+sh, y-sv, rwx+sh*2, y-sv, rwx+sh*3, y)
						.bezierCurveTo(rwx+sh*4, y+sv, rwx+sh*5, y+sv, rwx+sh*6, y);
				rwx += sh*6;
			}
		pdfKitDoc.stroke(group.decorationColor);
		
	} else {
		pdfKitDoc	.fillColor(group.decorationColor)
					.rect(x + firstInline.x, y-lw/2, totalWidth, lw)
					.fill();
	}
	pdfKitDoc.restore();
}

function drawDecorations(line, x, y, pdfKitDoc) {
	var groups = groupDecorations(line);
	for (var i = 0, l = groups.length; i < l; i++) {
		drawDecoration(groups[i], x, y, pdfKitDoc);
	}
}

function drawBackground(line, x, y, pdfKitDoc) {
	var height = line.getHeight();
	for(var i = 0, l = line.inlines.length; i < l; i++) {
		var inline = line.inlines[i];
			if(inline.background) {
				pdfKitDoc	.fillColor(inline.background)
							.rect(x + inline.x, y, inline.width, height)
							.fill();
			}
	}
}

module.exports = {
	drawBackground: drawBackground,
	drawDecorations: drawDecorations
};