text: 'use strict';
  
  var isArray = require('./helpers').isArray;
  
  function groupDecorations(line) {
  	var groups = [], currentGroup = null;
  	for (var i = 0, l = line.inlines.length; i < l; i++) {
  		var inline = line.inlines[i];
  		var decoration = inline.decoration;
  		if (!decoration) {
  			currentGroup = null;
  			continue;
  		}
  		if (!isArray(decoration)) {
  			decoration = [decoration];
  		}
  		var color = inline.decorationColor || inline.color || 'black';
  		var style = inline.decorationStyle || 'solid';
  		for (var ii = 0, ll = decoration.length; ii < ll; ii++) {
  			var decorationItem = decoration[ii];
  			if (!currentGroup || decorationItem !== currentGroup.decoration ||
  				style !== currentGroup.decorationStyle || color !== currentGroup.decorationColor) {
  
  				currentGroup = {
  					line: line,
  					decoration: decorationItem,
  					decorationColor: color,
  					decorationStyle: style,
  					inlines: [inline]
  				};
  				groups.push(currentGroup);
  			} else {
  				currentGroup.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 inline = group.inlines[i];
  			max = inline.fontSize > max ? i : max;
  		}
  		return group.inlines[max];
  	}
  	function width() {
  		var sum = 0;
  		for (var i = 0, l = group.inlines.length; i < l; i++) {
  			var justifyShift = (group.inlines[i].justifyShift || 0);
  			sum += group.inlines[i].width + justifyShift;
  		}
  		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) {
  			continue;
  		}
  		var justifyShift = (inline.justifyShift || 0);
  		pdfKitDoc.fillColor(inline.background)
  			.rect(x + inline.x - justifyShift, y, inline.width + justifyShift, height)
  			.fill();
  	}
  }
  
  module.exports = {
  	drawBackground: drawBackground,
  	drawDecorations: drawDecorations
  };