/*******************************************************************************
 * Copyright (c) 2009, 2015 David Green and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     David Green - initial API and implementation
 *     Torkild U. Resheim - bugs 337405, 336592, 336683, 336813
 *******************************************************************************/

package org.eclipse.mylyn.wikitext.parser.builder;

import java.io.Writer;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Stack;
import java.util.TreeMap;
import java.util.logging.Logger;

import org.eclipse.mylyn.wikitext.parser.Attributes;
import org.eclipse.mylyn.wikitext.parser.ImageAttributes;
import org.eclipse.mylyn.wikitext.parser.LinkAttributes;
import org.eclipse.mylyn.wikitext.parser.ListAttributes;
import org.eclipse.mylyn.wikitext.parser.TableAttributes;
import org.eclipse.mylyn.wikitext.parser.TableCellAttributes;
import org.eclipse.mylyn.wikitext.parser.TableRowAttributes;
import org.eclipse.mylyn.wikitext.parser.css.CssParser;
import org.eclipse.mylyn.wikitext.parser.css.CssRule;
import org.eclipse.mylyn.wikitext.parser.outline.OutlineItem;
import org.eclipse.mylyn.wikitext.util.XmlStreamWriter;

/**
 * A document builder that produces XSL-FO output. XSL-FO is suitable for conversion to other formats such as PDF.
 *
 * @see XslfoDocumentBuilder.Configuration Configuration for configurable settings
 * @see <a href="http://www.w3.org/TR/2001/REC-xsl-20011015/">XSL-FO 1.0 specification</a>
 * @see <a href="http://en.wikipedia.org/wiki/XSL_Formatting_Objects">XSL-FO (WikiPedia)</a>
 * @see <a href="http://www.w3schools.com/xslfo/default.asp">XSL-FO Tutorial</a>
 * @author David Green
 * @author Torkild U. Resheim
 * @since 3.0
 */
public class XslfoDocumentBuilder extends AbstractXmlDocumentBuilder {

	private static final String CSS_RULE_BORDER_STYLE = "border-style"; //$NON-NLS-1$

	private static final String CSS_RULE_BORDER_WIDTH = "border-width";; //$NON-NLS-1$

	private static final String CSS_RULE_BORDER_COLOR = "border-color";; //$NON-NLS-1$

	private static final String CSS_RULE_BACKGROUND_COLOR = "background-color"; //$NON-NLS-1$

	private static final String CSS_RULE_COLOR = "color"; //$NON-NLS-1$

	private static final String CSS_RULE_VERTICAL_ALIGN = "vertical-align"; //$NON-NLS-1$

	private static final String CSS_RULE_TEXT_ALIGN = "text-align"; //$NON-NLS-1$

	private static final String CSS_RULE_TEXT_DECORATION = "text-decoration"; //$NON-NLS-1$

	private static final String CSS_RULE_FONT_FAMILY = "font-family"; //$NON-NLS-1$

	private static final String CSS_RULE_FONT_SIZE = "font-size"; //$NON-NLS-1$

	private static final String CSS_RULE_FONT_WEIGHT = "font-weight"; //$NON-NLS-1$

	private static final String CSS_RULE_FONT_STYLE = "font-style"; //$NON-NLS-1$

	private static final char[] BULLET_CHARS = new char[] { '\u2022' };

	private static Map<BlockType, String> blockTypeToCssStyles = new HashMap<BlockType, String>();
	static {
		blockTypeToCssStyles.put(BlockType.CODE, "font-family: monospace;"); //$NON-NLS-1$
		blockTypeToCssStyles.put(BlockType.PREFORMATTED, "font-family: monospace;"); //$NON-NLS-1$
		blockTypeToCssStyles.put(BlockType.TABLE_CELL_HEADER, "font-weight: bold;"); //$NON-NLS-1$
	}

	private static Map<SpanType, String> spanTypeToCssStyles = new HashMap<SpanType, String>();
	static {
		spanTypeToCssStyles.put(SpanType.STRONG, "font-weight: bold;"); //$NON-NLS-1$
		spanTypeToCssStyles.put(SpanType.BOLD, "font-weight: bold;"); //$NON-NLS-1$
		spanTypeToCssStyles.put(SpanType.MONOSPACE, "font-family: monospace;"); //$NON-NLS-1$
		spanTypeToCssStyles.put(SpanType.CODE, "font-family: monospace;"); //$NON-NLS-1$
		spanTypeToCssStyles.put(SpanType.CITATION, "font-style: italic;"); //$NON-NLS-1$
		spanTypeToCssStyles.put(SpanType.EMPHASIS, "font-style: italic;"); //$NON-NLS-1$
		spanTypeToCssStyles.put(SpanType.ITALIC, "font-style: italic;"); //$NON-NLS-1$
		spanTypeToCssStyles.put(SpanType.DELETED, "text-decoration: line-through;"); //$NON-NLS-1$
		spanTypeToCssStyles.put(SpanType.INSERTED, "text-decoration: underline;"); //$NON-NLS-1$
		spanTypeToCssStyles.put(SpanType.UNDERLINED, "text-decoration: underline;"); //$NON-NLS-1$
		spanTypeToCssStyles.put(SpanType.SUBSCRIPT, "vertical-align: sub;"); //$NON-NLS-1$
		spanTypeToCssStyles.put(SpanType.SUPERSCRIPT, "vertical-align: super;"); //$NON-NLS-1$
	}

	private final String foNamespaceUri = "http://www.w3.org/1999/XSL/Format"; //$NON-NLS-1$

	private boolean pageOpen = false;

	private int h1Count = 0;

	private final Stack<ElementInfo> elementInfos = new Stack<ElementInfo>();

	private Configuration configuration = new Configuration();

	private OutlineItem outline;

	public XslfoDocumentBuilder(Writer out) {
		super(out);
	}

	public XslfoDocumentBuilder(XmlStreamWriter writer) {
		super(writer);
	}

	@Override
	public void acronym(String text, String definition) {
		characters(text);
	}

	/**
	 *
	 */
	public OutlineItem getOutline() {
		return outline;
	}

	/**
	 * If an outline item is set, the document builder will output XSL:FO bookmarks at the beginning of the resulting
	 * document.
	 *
	 * @param outline
	 *            the root outline item.
	 */
	public void setOutline(OutlineItem outline) {
		this.outline = outline;
	}

	private static class ElementInfo {
		int size = 1;

	}

	private static class SpanInfo extends ElementInfo {
		@SuppressWarnings("unused")
		final SpanType type;

		public SpanInfo(SpanType type) {
			super();
			this.type = type;
		}
	}

	private static class BlockInfo extends ElementInfo {
		final BlockType type;

		int listItemCount;

		BlockInfo previousChild;

		public BlockInfo(BlockType type) {
			this.type = type;
		}

	}

	@Override
	public void beginBlock(BlockType type, Attributes attributes) {
		BlockInfo thisInfo = new BlockInfo(type);
		BlockInfo parentBlock = findCurrentBlock();

		String cssStyles = blockTypeToCssStyles.get(type);
		Map<String, String> attrs = cssStyles == null ? null : attributesFromCssStyles(cssStyles);
		if (attributes.getCssStyle() != null) {
			Map<String, String> otherAttrs = attributesFromCssStyles(attributes.getCssStyle());
			if (attrs == null) {
				attrs = otherAttrs;
			} else if (!otherAttrs.isEmpty()) {
				attrs.putAll(otherAttrs);
			}
		}

		switch (type) {
		case DEFINITION_LIST:
		case BULLETED_LIST:
		case NUMERIC_LIST:
			writer.writeStartElement(foNamespaceUri, "list-block"); //$NON-NLS-1$
			writer.writeAttribute("provisional-label-separation", "0.2em"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeAttribute("provisional-distance-between-starts", "1.2em"); //$NON-NLS-1$ //$NON-NLS-2$
			if (findBlockInfo(BlockType.LIST_ITEM) == null) {
				addSpaceBefore();
			}
			break;
		case DEFINITION_ITEM:
			if (parentBlock == null || parentBlock.type != BlockType.DEFINITION_LIST) {
				throw new IllegalStateException();
			}
			boolean firstItem = false;
			if (parentBlock.previousChild != null && parentBlock.previousChild.type == BlockType.DEFINITION_TERM) {
				firstItem = true;
				writer.writeEndElement(); // list-item-label
				--parentBlock.size;

				writer.writeStartElement(foNamespaceUri, "list-item-body"); //$NON-NLS-1$
				++parentBlock.size;
				writer.writeAttribute("start-indent", "body-start()"); //$NON-NLS-1$ //$NON-NLS-2$
				writer.writeEmptyElement(foNamespaceUri, "block"); //$NON-NLS-1$
			}
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			if (attrs == null || !attrs.containsKey("font-size")) { //$NON-NLS-1$
				configureFontSize(0);
			}
			writer.writeAttribute("space-before", firstItem ? "1.2em" : "0.2em"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			break;
		case DEFINITION_TERM:
			if (parentBlock == null || parentBlock.type != BlockType.DEFINITION_LIST) {
				throw new IllegalStateException();
			}
			if (parentBlock.previousChild != null && parentBlock.previousChild.type == BlockType.DEFINITION_ITEM) {
				writer.writeEndElement(); // list-item-body
				--parentBlock.size;
				writer.writeEndElement(); // list-item
				--parentBlock.size;
			}
			if (parentBlock.previousChild == null || parentBlock.previousChild.type != BlockType.DEFINITION_TERM) {
				writer.writeStartElement(foNamespaceUri, "list-item"); //$NON-NLS-1$
				writer.writeAttribute("space-before", "0.2em"); //$NON-NLS-1$ //$NON-NLS-2$
				++parentBlock.size;
				writer.writeStartElement(foNamespaceUri, "list-item-label"); //$NON-NLS-1$
				writer.writeAttribute("end-indent", "label-end()"); //$NON-NLS-1$ //$NON-NLS-2$
				++parentBlock.size;
			}
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			if (attrs == null || !attrs.containsKey("font-size")) { //$NON-NLS-1$
				configureFontSize(0);
			}
			if (attrs == null || !attrs.containsKey("font-weight")) { //$NON-NLS-1$
				writer.writeAttribute("font-weight", "bold"); //$NON-NLS-1$//$NON-NLS-2$
			}
			break;
		case LIST_ITEM:
			BlockInfo listInfo = getListBlockInfo();
			++listInfo.listItemCount;
			writer.writeStartElement(foNamespaceUri, "list-item"); //$NON-NLS-1$
//			addSpaceBefore();

			writer.writeStartElement(foNamespaceUri, "list-item-label"); //$NON-NLS-1$
			writer.writeAttribute("end-indent", "label-end()"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			configureFontSize(0);
			// FIXME: nested list numbering, list style
			if (listInfo.type == BlockType.NUMERIC_LIST) {
				if (attributes instanceof ListAttributes) {
					// start attribute
					ListAttributes listAttributes = (ListAttributes) attributes;
					if (listAttributes.getStart() != null) {
						try {
							thisInfo.listItemCount = Integer.parseInt(listAttributes.getStart(), 10) - 1;
						} catch (NumberFormatException e) {
							// ignore
						}
					}
				}
				writer.writeCharacters(String.format("%s.", listInfo.listItemCount)); //$NON-NLS-1$
			} else {
				writer.writeCharacters(BULLET_CHARS, 0, BULLET_CHARS.length);
			}
			writer.writeEndElement(); // block
			writer.writeEndElement(); // list-item-label

			writer.writeStartElement(foNamespaceUri, "list-item-body"); //$NON-NLS-1$
			++thisInfo.size;
			writer.writeAttribute("start-indent", "body-start()"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			configureFontSize(0);
			++thisInfo.size;

			break;
		case FOOTNOTE:
		case PARAGRAPH:
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			if (attrs == null || !attrs.containsKey("font-size")) { //$NON-NLS-1$
				configureFontSize(0);
			}
			addSpaceBefore();
			break;
		case CODE:
		case PREFORMATTED:
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			writer.writeAttribute("hyphenate", "false"); //$NON-NLS-1$ //$NON-NLS-2$
//			writer.writeAttribute("wrap-option", "no-wrap"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeAttribute("white-space-collapse", "false"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeAttribute("white-space-treatment", "preserve"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeAttribute("linefeed-treatment", "preserve"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeAttribute("text-align", "start"); //$NON-NLS-1$ //$NON-NLS-2$
			if (attrs == null || !attrs.containsKey("font-size")) { //$NON-NLS-1$
				configureFontSize(0);
			}
			addSpaceBefore();
			break;
		case QUOTE:
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			if (attrs == null || !attrs.containsKey("font-size")) { //$NON-NLS-1$
				configureFontSize(0);
			}
			// indent
			indentLeftAndRight(attrs, "2em"); //$NON-NLS-1$
			addSpaceBefore();
			break;
		case DIV:
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			if (attrs == null || !attrs.containsKey("font-size")) { //$NON-NLS-1$
				configureFontSize(0);
			}
			// no space before
			break;
		case INFORMATION:
		case NOTE:
		case TIP:
		case WARNING:
		case PANEL:
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			if (attrs == null || !attrs.containsKey("font-size")) { //$NON-NLS-1$
				configureFontSize(0);
			}
			indentLeftAndRight(attrs, "2em"); //$NON-NLS-1$
			addSpaceBefore();

			// create the titled panel effect if a title is specified
			if (attributes.getTitle() != null || configuration.panelText) {
				writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
				if (configuration.panelText) {
					String text = null;
					switch (type) {
					case NOTE:
						text = Messages.getString("XslfoDocumentBuilder.Note"); //$NON-NLS-1$
						break;
					case TIP:
						text = Messages.getString("XslfoDocumentBuilder.Tip"); //$NON-NLS-1$
						break;
					case WARNING:
						text = Messages.getString("XslfoDocumentBuilder.Warning"); //$NON-NLS-1$
						break;
					}
					if (text != null) {
						writer.writeStartElement(foNamespaceUri, "inline"); //$NON-NLS-1$
						writer.writeAttribute("font-style", "italic"); //$NON-NLS-1$//$NON-NLS-2$
						characters(text);
						writer.writeEndElement(); // inline
					}
				}
				if (attributes.getTitle() != null) {
					writer.writeStartElement(foNamespaceUri, "inline"); //$NON-NLS-1$
					writer.writeAttribute("font-weight", "bold"); //$NON-NLS-1$//$NON-NLS-2$
					characters(attributes.getTitle());
					writer.writeEndElement(); // inline
				}
				writer.writeEndElement(); // block
			}

			break;
		case TABLE:
			writer.writeStartElement(foNamespaceUri, "table"); //$NON-NLS-1$
			applyTableAttributes(attributes);
			writer.writeStartElement(foNamespaceUri, "table-body"); //$NON-NLS-1$
			++thisInfo.size;
			break;
		case TABLE_CELL_HEADER:
		case TABLE_CELL_NORMAL:
			writer.writeStartElement(foNamespaceUri, "table-cell"); //$NON-NLS-1$
			applyTableCellAttributes(attributes);
			writer.writeAttribute("padding-left", "2pt"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeAttribute("padding-right", "2pt"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeAttribute("padding-top", "2pt"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeAttribute("padding-bottom", "2pt"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			if (attrs == null || !attrs.containsKey("font-size")) { //$NON-NLS-1$
				configureFontSize(0);
			}
			++thisInfo.size;
			break;
		case TABLE_ROW:
			writer.writeStartElement(foNamespaceUri, "table-row"); //$NON-NLS-1$
			applyTableRowAttributes(attributes);
			break;
		default:
			throw new IllegalStateException(type.name());
		}

		if (attrs != null) {
			// output attributes with stable order
			for (Entry<String, String> ent : new TreeMap<String, String>(attrs).entrySet()) {
				writer.writeAttribute(ent.getKey(), ent.getValue());
			}
		}

		if (parentBlock != null) {
			parentBlock.previousChild = thisInfo;
		}
		elementInfos.push(thisInfo);
	}

	private void indentLeftAndRight(Map<String, String> attrs, String indentSize) {
		if (attrs == null || !attrs.containsKey("margin-left")) { //$NON-NLS-1$
			writer.writeAttribute("margin-left", indentSize); //$NON-NLS-1$
		}
		if (attrs == null || !attrs.containsKey("margin-right")) { //$NON-NLS-1$
			writer.writeAttribute("margin-right", indentSize); //$NON-NLS-1$
		}
	}

	private void configureFontSize(int level) {
		writer.writeAttribute("font-size", String.format("%spt", configuration.fontSizes[level])); //$NON-NLS-1$ //$NON-NLS-2$
	}

	private void addSpaceBefore() {
		writer.writeAttribute("space-before.optimum", "1em"); //$NON-NLS-1$ //$NON-NLS-2$
		writer.writeAttribute("space-before.minimum", "0.8em"); //$NON-NLS-1$ //$NON-NLS-2$
		writer.writeAttribute("space-before.maximum", "1.2em"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	@Override
	public void endBlock() {
		ElementInfo elementInfo = elementInfos.pop();
		if (!(elementInfo instanceof BlockInfo)) {
			throw new IllegalStateException();
		}
		close(elementInfo);
	}

	private void close(ElementInfo elementInfo) {
		while (elementInfo.size > 0) {
			--elementInfo.size;
			writer.writeEndElement();
		}
	}

	private void applyTableAttributes(Attributes attributes) {
		// applyAttributes(attributes);

		boolean haveWidth = false;
		if (attributes instanceof TableAttributes) {
			TableAttributes tableAttributes = (TableAttributes) attributes;
			if (tableAttributes.getBgcolor() != null) {
				writer.writeAttribute(CSS_RULE_BACKGROUND_COLOR, tableAttributes.getBgcolor());
			}

			// FIXME border
			// if (tableAttributes.getBorder() != null) {
			//				writer.writeAttribute("border", tableAttributes.getBorder()); //$NON-NLS-1$
			// }
			// if (tableAttributes.getCellpadding() != null) {
			//				writer.writeAttribute("cellpadding", tableAttributes.getCellpadding()); //$NON-NLS-1$
			// }
			// if (tableAttributes.getCellspacing() != null) {
			//				writer.writeAttribute("cellspacing", tableAttributes.getCellspacing()); //$NON-NLS-1$
			// }
			// if (tableAttributes.getFrame() != null) {
			//				writer.writeAttribute("frame", tableAttributes.getFrame()); //$NON-NLS-1$
			// }
			// if (tableAttributes.getRules() != null) {
			//				writer.writeAttribute("rules", tableAttributes.getRules()); //$NON-NLS-1$
			// }
			// if (tableAttributes.getSummary() != null) {
			//				writer.writeAttribute("summary", tableAttributes.getSummary()); //$NON-NLS-1$
			// }
			if (tableAttributes.getWidth() != null) {
				writer.writeAttribute("width", tableAttributes.getWidth()); //$NON-NLS-1$
				haveWidth = true;
			}
		}
		// FIXME default border
		if (!haveWidth) {
			writer.writeAttribute("width", "auto"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		writer.writeAttribute("border-collapse", "collapse"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	private void applyTableCellAttributes(Attributes attributes) {
		if (attributes instanceof TableCellAttributes) {
			TableCellAttributes cellAttributes = (TableCellAttributes) attributes;
			if (cellAttributes.getBgcolor() != null) {
				writer.writeAttribute(CSS_RULE_BACKGROUND_COLOR, cellAttributes.getBgcolor());
			}
			if (cellAttributes.getColspan() != null) {
				writer.writeAttribute("number-columns-spanned", cellAttributes.getColspan()); //$NON-NLS-1$
			}
			if (cellAttributes.getRowspan() != null) {
				writer.writeAttribute("number-rows-spanned", cellAttributes.getRowspan()); //$NON-NLS-1$
			}
			// Expecting values left, right, center, justify or inherit
			if (cellAttributes.getAlign() != null) {
				writer.writeAttribute("text-align", cellAttributes.getAlign()); //$NON-NLS-1$
			}
			// Vertical align may be top, middle and bottom
			if (cellAttributes.getValign() != null) {
				String value = cellAttributes.getAlign();
				if (cellAttributes.getValign().equals("top")) { //$NON-NLS-1$
					value = "before"; //$NON-NLS-1$
				} else if (cellAttributes.getValign().equals("middle")) { //$NON-NLS-1$
					value = "center"; //$NON-NLS-1$
				} else if (cellAttributes.getValign().equals("bottom")) { //$NON-NLS-1$
					value = "after"; //$NON-NLS-1$
				}
				if (value != null) {
					writer.writeAttribute("display-align", value); //$NON-NLS-1$
				}
			}
		}
	}

	private void applyTableRowAttributes(Attributes attributes) {
		if (attributes instanceof TableRowAttributes) {
			TableRowAttributes rowAttributes = (TableRowAttributes) attributes;
			if (rowAttributes.getBgcolor() != null) {
				writer.writeAttribute(CSS_RULE_BACKGROUND_COLOR, rowAttributes.getBgcolor());
			}
			// Vertical align may be top, middle and bottom
			if (rowAttributes.getValign() != null) {
				String value = rowAttributes.getAlign();
				if (rowAttributes.getValign().equals("top")) { //$NON-NLS-1$
					value = "before"; //$NON-NLS-1$
				} else if (rowAttributes.getValign().equals("middle")) { //$NON-NLS-1$
					value = "center"; //$NON-NLS-1$
				} else if (rowAttributes.getValign().equals("bottom")) { //$NON-NLS-1$
					value = "after"; //$NON-NLS-1$
				}
				if (value != null) {
					writer.writeAttribute("display-align", value); //$NON-NLS-1$
				}
			}
		}
	}

	private BlockInfo getListBlockInfo() {
		for (int x = elementInfos.size() - 1; x >= 0; --x) {
			ElementInfo elementInfo = elementInfos.get(x);
			if (elementInfo instanceof BlockInfo) {
				BlockInfo info = (BlockInfo) elementInfo;
				if (info.type == BlockType.BULLETED_LIST || info.type == BlockType.NUMERIC_LIST
						|| info.type == BlockType.DEFINITION_LIST) {
					return info;
				}
			}
		}
		return null;
	}

	private BlockInfo findBlockInfo(BlockType type) {
		for (int x = elementInfos.size() - 1; x >= 0; --x) {
			ElementInfo elementInfo = elementInfos.get(x);
			if (elementInfo instanceof BlockInfo) {
				BlockInfo info = (BlockInfo) elementInfo;
				if (info.type == type) {
					return info;
				}
			}
		}
		return null;
	}

	private BlockInfo findCurrentBlock() {
		for (int x = elementInfos.size() - 1; x >= 0; --x) {
			ElementInfo elementInfo = elementInfos.get(x);
			if (elementInfo instanceof BlockInfo) {
				return (BlockInfo) elementInfo;
			}
		}
		return null;
	}

	private void writeMargins(Margins margins, XmlStreamWriter writer) {
		if (margins == null) {
			return;
		}
		writer.writeAttribute("margin-top", String.format("%scm", margins.marginTop)); //$NON-NLS-1$ //$NON-NLS-2$
		writer.writeAttribute("margin-bottom", String.format("%scm", margins.marginBottom)); //$NON-NLS-1$ //$NON-NLS-2$
		writer.writeAttribute("margin-left", String.format("%scm", margins.marginLeft)); //$NON-NLS-1$ //$NON-NLS-2$
		writer.writeAttribute("margin-right", String.format("%scm", margins.marginRight)); //$NON-NLS-1$ //$NON-NLS-2$
	}

	private void writeRegion(Region region, XmlStreamWriter writer) {
		if (region == null) {
			return;
		}
		writer.writeEmptyElement(foNamespaceUri, "region-" + region.location); //$NON-NLS-1$
		writer.writeAttribute("extent", String.format("%scm", region.extent)); //$NON-NLS-1$//$NON-NLS-2$
		writer.writeAttribute("precedence", Boolean.toString(region.precedence)); //$NON-NLS-1$
		if (region.name != null) {
			writer.writeAttribute("region-name", region.name); //$NON-NLS-1$
		}
	}

	@Override
	public void beginDocument() {
		writer.setDefaultNamespace(foNamespaceUri);

		writer.writeStartElement(foNamespaceUri, "root"); //$NON-NLS-1$
		writer.writeNamespace("", foNamespaceUri); //$NON-NLS-1$

		writer.writeStartElement(foNamespaceUri, "layout-master-set"); //$NON-NLS-1$
		writer.writeStartElement(foNamespaceUri, "simple-page-master"); //$NON-NLS-1$
		writer.writeAttribute("master-name", "page-layout"); //$NON-NLS-1$ //$NON-NLS-2$
		writer.writeAttribute("page-height", String.format("%scm", configuration.pageHeight)); //$NON-NLS-1$ //$NON-NLS-2$
		writer.writeAttribute("page-width", String.format("%scm", configuration.pageWidth)); //$NON-NLS-1$ //$NON-NLS-2$

		if (configuration.getPageMargins() == null) {
			writer.writeAttribute("margin", String.format("%scm", configuration.pageMargin)); //$NON-NLS-1$ //$NON-NLS-2$
		} else {
			writeMargins(configuration.getPageMargins(), writer);
		}

		writer.writeEmptyElement(foNamespaceUri, "region-body"); //$NON-NLS-1$

		if (configuration.getBodyMargins() == null) {
			if (hasPageFooter()) {
				writer.writeAttribute("margin-bottom", "3cm"); //$NON-NLS-1$ //$NON-NLS-2$
			}
		} else {
			writeMargins(configuration.getBodyMargins(), writer);
		}
		if (configuration.bodyAfterRegion == null) {
			if (hasPageFooter()) {
				writeRegion(new Region("after", "footer", 2, false), writer); //$NON-NLS-1$ //$NON-NLS-2$
			}
		} else {
			writeRegion(configuration.getBodyAfterRegion(), writer);
		}

		writeRegion(configuration.getBodyBeforeRegion(), writer);
		writeRegion(configuration.getBodyEndRegion(), writer);
		writeRegion(configuration.getBodyStartRegion(), writer);

		writer.writeEndElement(); // simple-page-master
		writer.writeEndElement(); // layout-master-set

		if (outline != null && !outline.getChildren().isEmpty()) {
			writer.writeStartElement("bookmark-tree"); //$NON-NLS-1$
			emitToc(writer, outline.getChildren());
			writer.writeEndElement(); // bookmark-tree
		}

		if (configuration.getTitle() != null) {
			emitTitlePage();
		}

		openPage();
		openFlow(false);
	}

	private boolean hasPageFooter() {
		return configuration.copyright != null || configuration.pageNumbering;
	}

	private void emitTitlePage() {
		openPage();
		openFlow(true);
		writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$

		if (configuration.title != null) {
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			writer.writeAttribute("font-weight", "bold"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeAttribute("font-size", "25pt"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeAttribute("text-align", "center"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeAttribute("space-before", "19pt"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeCharacters(configuration.title);
			writer.writeEndElement(); // block
		}

		if (configuration.subTitle != null) {
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			writer.writeAttribute("font-weight", "bold"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeAttribute("font-size", "18pt"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeAttribute("text-align", "center"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeAttribute("space-before", "15pt"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeCharacters(configuration.subTitle);
			writer.writeEndElement(); // block
		}

		if (configuration.version != null) {
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			writer.writeAttribute("font-weight", "bold"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeAttribute("font-size", "14pt"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeAttribute("text-align", "center"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeAttribute("space-before", "13pt"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeCharacters(configuration.version);
			writer.writeEndElement(); // block
		}

		if (configuration.date != null) {
			writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
			writer.writeAttribute("font-weight", "bold"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeAttribute("font-size", "14pt"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeAttribute("text-align", "center"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeAttribute("space-before", "13pt"); //$NON-NLS-1$//$NON-NLS-2$
			writer.writeCharacters(configuration.date);
			writer.writeEndElement(); // block
		}

		writer.writeEmptyElement(foNamespaceUri, "block"); //$NON-NLS-1$
		writer.writeAttribute("break-after", "page"); //$NON-NLS-1$//$NON-NLS-2$
		writer.writeEndElement(); // block

		closeFlow();
		closePage();
	}

	private void openFlow(boolean titlePage) {
		if (hasPageFooter()) {
			final boolean hasCopyrightText = configuration.copyright != null
					&& configuration.copyright.trim().length() > 0;
			final boolean hasPageNumber = configuration.pageNumbering && !titlePage;
			if (hasCopyrightText || hasPageNumber) {
				writer.writeStartElement(foNamespaceUri, "static-content"); //$NON-NLS-1$
				writer.writeAttribute("flow-name", "footer"); //$NON-NLS-1$//$NON-NLS-2$

				if (hasCopyrightText) {
					writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
					configureFontSize(0);
					writer.writeAttribute("text-align", "center"); //$NON-NLS-1$//$NON-NLS-2$

					writer.writeCharacters(configuration.copyright);

					writer.writeEndElement(); // block
				}

				if (hasPageNumber) {
					writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
					configureFontSize(0);
					writer.writeAttribute("text-align", "outside"); //$NON-NLS-1$//$NON-NLS-2$
					//
					//				// output the section header into the footer using retrieve-marker
					//				writer.writeEmptyElement(foNamespaceUri, "retrieve-marker"); //$NON-NLS-1$
					//				writer.writeAttribute("retrieve-boundary", "page-sequence"); //$NON-NLS-1$//$NON-NLS-2$
					//				writer.writeAttribute("retrieve-position", "first-starting-within-page"); //$NON-NLS-1$//$NON-NLS-2$
					//				writer.writeAttribute("retrieve-class-name", "section-title"); //$NON-NLS-1$//$NON-NLS-2$

					writer.writeEmptyElement(foNamespaceUri, "page-number"); //$NON-NLS-1$

					writer.writeEndElement(); // block
				}
				writer.writeEndElement(); // static-content
			}
		}
		writer.writeStartElement(foNamespaceUri, "flow"); //$NON-NLS-1$
		writer.writeAttribute("flow-name", "xsl-region-body"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	private void closeFlow() {
		writer.writeEndElement(); // flow
	}

	private void openPage() {
		pageOpen = true;
		writer.writeStartElement(foNamespaceUri, "page-sequence"); //$NON-NLS-1$
		writer.writeAttribute("master-reference", "page-layout"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	private void closePage() {
		writer.writeEndElement(); // page-sequence
		pageOpen = false;
	}

	private void emitToc(XmlStreamWriter writer, List<OutlineItem> children) {
		for (OutlineItem item : children) {
			writer.writeStartElement("bookmark"); //$NON-NLS-1$
			writer.writeAttribute("internal-destination", item.getId()); //$NON-NLS-1$

			writer.writeStartElement("bookmark-title"); //$NON-NLS-1$
			writer.writeCharacters(item.getLabel());
			writer.writeEndElement();

			if (!item.getChildren().isEmpty()) {
				emitToc(writer, item.getChildren());
			}

			writer.writeEndElement(); // bookmark
		}
	}

	@Override
	public void endDocument() {
		if (pageOpen) {
			closeFlow();
			closePage();
		}
		writer.writeEndElement(); // root
		writer.close();
	}

	@Override
	public void beginHeading(int level, Attributes attributes) {
		if (level == 1 && ++h1Count > 1 && configuration.pageBreakOnHeading1) {
			if (pageOpen) {
				closeFlow();
				closePage();
			}
			openPage();
			openFlow(false);
		}

		writer.writeStartElement(foNamespaceUri, "block"); //$NON-NLS-1$
		writer.writeAttribute("keep-with-next.within-column", "always"); //$NON-NLS-1$ //$NON-NLS-2$
		writer.writeAttribute("font-weight", "bold"); //$NON-NLS-1$ //$NON-NLS-2$
		configureFontSize(level);
		writer.writeAttribute("space-before.optimum", "10pt"); //$NON-NLS-1$ //$NON-NLS-2$
		writer.writeAttribute("space-before.minimum", "10pt * 0.8"); //$NON-NLS-1$ //$NON-NLS-2$
		writer.writeAttribute("space-before.maximum", "10pt * 1.2"); //$NON-NLS-1$ //$NON-NLS-2$
		if (attributes.getId() != null) {
			writer.writeAttribute("id", attributes.getId()); //$NON-NLS-1$
		}
	}

	@Override
	public void endHeading() {
		writer.writeEndElement(); // block
	}

	private Map<String, String> attributesFromCssStyles(String styles) {
		if (styles == null) {
			return Collections.emptyMap();
		}
		List<CssRule> rules = new CssParser().parseBlockContent(styles);
		if (rules.isEmpty()) {
			return Collections.emptyMap();
		}
		Map<String, String> mapping = new HashMap<String, String>();
		for (CssRule rule : rules) {
			if (CSS_RULE_VERTICAL_ALIGN.equals(rule.name)) {
				String cssValue = rule.value;
				if (cssValue.equals("super")) { //$NON-NLS-1$
					mapping.put("font-size", "75%"); //$NON-NLS-1$ //$NON-NLS-2$
					mapping.put("baseline-shift", "super"); //$NON-NLS-1$ //$NON-NLS-2$
				} else if (cssValue.equals("sub")) { //$NON-NLS-1$
					mapping.put("font-size", "75%"); //$NON-NLS-1$ //$NON-NLS-2$
					mapping.put("baseline-shift", "sub"); //$NON-NLS-1$ //$NON-NLS-2$
				} else if (cssValue.equals("top")) { //$NON-NLS-1$
					mapping.put("display-align", "before"); //$NON-NLS-1$ //$NON-NLS-2$
				} else if (cssValue.equals("middle")) { //$NON-NLS-1$
					mapping.put("display-align", "center"); //$NON-NLS-1$ //$NON-NLS-2$
				} else if (cssValue.equals("bottom")) { //$NON-NLS-1$
					mapping.put("display-align", "after"); //$NON-NLS-1$ //$NON-NLS-2$
				}
			} else if (CSS_RULE_TEXT_DECORATION.equals(rule.name) || //
					CSS_RULE_FONT_FAMILY.equals(rule.name) || //
					CSS_RULE_FONT_SIZE.equals(rule.name) || //
					CSS_RULE_FONT_WEIGHT.equals(rule.name) || //
					CSS_RULE_FONT_STYLE.equals(rule.name) || //
					CSS_RULE_BACKGROUND_COLOR.equals(rule.name) || //
					CSS_RULE_COLOR.equals(rule.name)) {
				mapping.put(rule.name, rule.value);
			} else if (CSS_RULE_BORDER_STYLE.equals(rule.name)) {
				mapping.put(rule.name, rule.value);
			} else if (CSS_RULE_BORDER_WIDTH.equals(rule.name)) {
				mapping.put(rule.name, rule.value);
			} else if (CSS_RULE_BORDER_COLOR.equals(rule.name)) {
				mapping.put(rule.name, rule.value);
			} else if (CSS_RULE_TEXT_ALIGN.equals(rule.name)) {
				mapping.put(rule.name, rule.value);
			}
		}
		return mapping;
	}

	@Override
	public void beginSpan(SpanType type, Attributes attributes) {
		final SpanInfo info = new SpanInfo(type);
		elementInfos.push(info);

		if (type == SpanType.LINK && attributes instanceof LinkAttributes) {
			String href = ((LinkAttributes) attributes).getHref();
			emitLink(attributes, href);
		} else {
			writer.writeStartElement(foNamespaceUri, "inline"); //$NON-NLS-1$
		}
		String cssStyles = spanTypeToCssStyles.get(type);
		Map<String, String> attrs = cssStyles == null ? null : attributesFromCssStyles(cssStyles);
		if (attributes.getCssStyle() != null) {
			Map<String, String> otherAttrs = attributesFromCssStyles(attributes.getCssStyle());
			if (attrs == null) {
				attrs = otherAttrs;
			} else if (!otherAttrs.isEmpty()) {
				attrs.putAll(otherAttrs);
			}
		}
		if (attrs != null) {
			// output attributes with stable order
			for (Entry<String, String> ent : new TreeMap<String, String>(attrs).entrySet()) {
				writer.writeAttribute(ent.getKey(), ent.getValue());
			}
		}
	}

	@Override
	public void endSpan() {
		ElementInfo elementInfo = elementInfos.pop();
		if (!(elementInfo instanceof SpanInfo)) {
			throw new IllegalStateException();
		}
		close(elementInfo);
	}

	@Override
	public void characters(String text) {
		writer.writeCharacters(text);
	}

	@Override
	public void charactersUnescaped(String literal) {
		Logger.getLogger(XslfoDocumentBuilder.class.getName()).warning("escaping XML literal"); //$NON-NLS-1$
		writer.writeCharacters(literal);
	}

	@Override
	public void entityReference(String entity) {
		writer.writeEntityRef(entity);
	}

	@Override
	public void image(Attributes attributes, String url) {
		// <fo:external-graphic src="url(images/editor-command-help.png)" width="auto" height="auto" content-width="auto" content-height="auto"/>
		writer.writeEmptyElement(foNamespaceUri, "external-graphic"); //$NON-NLS-1$
		writer.writeAttribute("src", String.format("url(%s)", makeUrlAbsolute(url))); //$NON-NLS-1$//$NON-NLS-2$
		applyImageAttributes(attributes);
	}

	private void applyImageAttributes(Attributes attributes) {
		boolean sizeSpecified = false;
		boolean scaleToFit = true;
		if (attributes instanceof ImageAttributes) {
			ImageAttributes imageAttributes = (ImageAttributes) attributes;
			if (imageAttributes.getWidth() > 0) {
				sizeSpecified = true;
				emitImageSize("width", imageAttributes.getWidth(), imageAttributes.isWidthPercentage()); //$NON-NLS-1$
			}
			if (imageAttributes.getHeight() > 0) {
				sizeSpecified = true;
				emitImageSize("height", imageAttributes.getHeight(), imageAttributes.isHeightPercentage()); //$NON-NLS-1$
			}
		}
		if (!sizeSpecified) {
			writer.writeAttribute("width", "100%"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeAttribute("content-height", "100%"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		if (scaleToFit) {
			writer.writeAttribute("content-width", "scale-to-fit"); //$NON-NLS-1$ //$NON-NLS-2$
			writer.writeAttribute("scaling", "uniform"); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	private void emitImageSize(String attributeName, int units, boolean isPercentage) {
		writer.writeAttribute(attributeName, String.format("%s%s", units, isPercentage ? "%" : "px")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}

	@Override
	public void imageLink(Attributes linkAttributes, Attributes imageAttributes, String href, String imageUrl) {
		writer.writeStartElement(foNamespaceUri, "basic-link"); //$NON-NLS-1$
		String destinationUrl = makeUrlAbsolute(href);
		if (destinationUrl.startsWith("#")) { //$NON-NLS-1$
			writer.writeAttribute("internal-destination", destinationUrl.substring(1)); //$NON-NLS-1$
		} else {
			writer.writeAttribute("external-destination", String.format("url(%s)", destinationUrl)); //$NON-NLS-1$//$NON-NLS-2$
		}
		image(imageAttributes, imageUrl);
		writer.writeEndElement();// basic-link
	}

	@Override
	public void lineBreak() {
		// an empty block does the trick
		writer.writeEmptyElement(foNamespaceUri, "block"); //$NON-NLS-1$
	}

	@Override
	public void link(Attributes attributes, String hrefOrHashName, String text) {
		emitLink(attributes, hrefOrHashName);
		characters(text);
		writer.writeEndElement();// basic-link

	}

	private void emitLink(Attributes attributes, String hrefOrHashName) {
		writer.writeStartElement(foNamespaceUri, "basic-link"); //$NON-NLS-1$
		String destinationUrl = makeUrlAbsolute(hrefOrHashName);
		boolean internal = destinationUrl.startsWith("#"); //$NON-NLS-1$
		if (internal) {
			if (configuration.underlineLinks) {
				writer.writeAttribute("text-decoration", "underline"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			writer.writeAttribute("internal-destination", destinationUrl.substring(1)); //$NON-NLS-1$
		} else {
			if (configuration.showExternalLinks) {
				if (configuration.underlineLinks) {
					writer.writeAttribute("text-decoration", "underline"); //$NON-NLS-1$ //$NON-NLS-2$
				}
				writer.writeAttribute("external-destination", String.format("url(%s)", destinationUrl)); //$NON-NLS-1$//$NON-NLS-2$
			}
		}
	}

	/**
	 * The current configuration of this builder. The returned value is mutable and changes to it affect this builder's
	 * configuration.
	 *
	 * @see Configuration Configuration class for configurable settings
	 */
	public Configuration getConfiguration() {
		return configuration;
	}

	/**
	 * The current configuration of this builder.
	 *
	 * @see Configuration Configuration class for configurable settings
	 */
	public void setConfiguration(Configuration configuration) {
		if (configuration == null) {
			throw new IllegalArgumentException();
		}
		this.configuration = configuration;
	}

	/**
	 * This type represents a XSL:FO page region.
	 *
	 * @author Torkild U. Resheim, MARINTEK
	 */
	public static class Region implements Cloneable {

		private float extent = 3.0f;

		private boolean precedence = false;

		private String location = null;

		private String name = null;

		/**
		 * Creates a new region with default values.
		 */
		public Region() {
			// Only use default values here
		}

		public Region(String name, float extent, boolean precedence) {
			this.name = name;
			this.extent = extent;
			this.precedence = precedence;
		}

		public Region(String location, String name, float extent, boolean precedence) {
			this.location = location;
			this.extent = extent;
			this.precedence = precedence;
			this.name = name;
		}

		/**
		 * Sets the extent of the region in cm.
		 *
		 * @param extent
		 *            the region extent in cm
		 */
		public void setExtent(float extent) {
			this.extent = extent;
		}

		/**
		 * Return the region extent in cm. Defaults to 3cm.
		 *
		 * @return value of the region extent in cms
		 */
		public float getExtent() {
			return extent;
		}

		/**
		 * Sets the precedence of the region. Defaults to <code>false</code>
		 *
		 * @param precedence
		 *            the new precedence value
		 */
		public void setPrecedence(boolean precedence) {
			this.precedence = precedence;
		}

		/**
		 * Returns whether or not the region has precedence. Defaults to <code>false</code>.
		 *
		 * @return the region precedence
		 */
		public boolean isPrecedence() {
			return precedence;
		}

		/**
		 * Assigns a name to the region. The default is to have no name.
		 *
		 * @param name
		 *            the region name
		 */
		public void setName(String name) {
			this.name = name;
		}

		/**
		 * Returns the name of the region. The default is to have no name.
		 *
		 * @return the region name
		 */
		public String getName() {
			return name;
		}

	}

	/**
	 * This type represents a XSL:FO page or body margin.
	 *
	 * @author Torkild U. Resheim, MARINTEK
	 */
	public static class Margins implements Cloneable {

		private float marginTop = 1.5f;

		private float marginBottom = 1.5f;

		private float marginLeft = 1.5f;

		private float marginRight = 1.5f;

		/**
		 * Creates a new set of margins with the default values.
		 */
		public Margins() {
			// Use default values
		}

		/**
		 * Creates a new set of margins with the specified values.
		 *
		 * @param top
		 *            value of the top margin in cm
		 * @param bottom
		 *            value of the bottom margin in cm
		 * @param left
		 *            value of the left margin in cm
		 * @param right
		 *            value of the right margin in cm
		 */
		public Margins(float top, float bottom, float left, float right) {
			this.marginTop = top;
			this.marginBottom = bottom;
			this.marginLeft = left;
			this.marginRight = right;
		}

		/**
		 * Sets the <b>margin-top</b> property in cm. Defaults to 1.5cm.
		 *
		 * @param marginTop
		 *            new value of the top margin in cm
		 */
		public void setMarginTop(float marginTop) {
			this.marginTop = marginTop;
		}

		/**
		 * Returns the <b>margin-top</b> propert in cm. Defaults to 1.5cm.
		 *
		 * @return value of the top margin in cm.
		 */
		public float getMarginTop() {
			return marginTop;
		}

		/**
		 * Sets the <b>margin-bottom</b> property in cm. Defaults to 1.5cm.
		 *
		 * @param marginBottom
		 *            new value of the top margin in cm
		 */
		public void setMarginBottom(float marginBottom) {
			this.marginBottom = marginBottom;
		}

		/**
		 * Returns the <b>margin-bottom</b> property in cm. Defaults to 1.5cm.
		 *
		 * @return value of the bottom margin in cm.
		 */
		public float getMarginBottom() {
			return marginBottom;
		}

		/**
		 * Sets the <b>margin-left</b> property in cm. Defaults to 1.5cm.
		 *
		 * @param marginLeft
		 *            new value of the left margin in cm
		 */
		public void setMarginLeft(float marginLeft) {
			this.marginLeft = marginLeft;
		}

		/**
		 * Returns the <b>margin-left</b> property in cm. Defaults to 1.5cm.
		 *
		 * @return value of the left margin in cm.
		 */
		public float getMarginLeft() {
			return marginLeft;
		}

		/**
		 * Sets the <b>margin-right</b> property in cm. Defaults to 1.5cm.
		 *
		 * @param marginRight
		 *            new value of the right margin in cm
		 */
		public void setMarginRight(float marginRight) {
			this.marginRight = marginRight;
		}

		/**
		 * Returns the <b>margin-right</b> property of the master page in cm. Defaults to 1.5cm.
		 *
		 * @return the master page right margin in cm.
		 */
		public float getMarginRight() {
			return marginRight;
		}

	}

	/**
	 * A class that encapsulates all configurable settings of the {@link XslfoDocumentBuilder}. This class implements
	 * the template design pattern via {@link Configuration#clone()}.
	 *
	 * @author David Green
	 * @author Torkild U. Resheim, MARINTEK
	 */
	public static class Configuration implements Cloneable {

		private float[] fontSizes = new float[] { 12.0f, 18.0f, 15.0f, 13.2f, 12.0f, 10.4f, 8.0f };

		private final float[] fontSizeMultipliers = new float[] { 1.0f, 1.5f, 1.25f, 1.1f, 1.0f, 0.83f, 0.67f };

		private boolean pageBreakOnHeading1 = true;

		private boolean showExternalLinks = true;

		private boolean underlineLinks = false;

		private boolean panelText = true;

		private String title;

		private String subTitle;

		private String version;

		private String date;

		private String author;

		private String copyright;

		private boolean pageNumbering = true;

		private float pageMargin = 1.5f;

		private float pageHeight = 29.7f;

		private float pageWidth = 21.0f;

		private Margins pageMargins = null;

		private Margins bodyMargins = null;

		private Region bodyBeforeRegion = null;

		private Region bodyAfterRegion = null;

		private Region bodyStartRegion = null;

		private Region bodyEndRegion = null;

		private float referenceOrientation = 90f;

		public Configuration() {
			setFontSize(10.0f);
		}

		@Override
		public Configuration clone() {
			try {
				return (Configuration) super.clone();
			} catch (CloneNotSupportedException e) {
				throw new IllegalStateException(e);
			}
		}

		/**
		 * Set the base font size. The base font size is 10.0 by default
		 */
		public void setFontSize(float fontSize) {
			fontSizes = new float[fontSizeMultipliers.length];
			for (int x = 0; x < fontSizeMultipliers.length; ++x) {
				fontSizes[x] = fontSizeMultipliers[x] * fontSize;
			}
		}

		/**
		 * Get the base font size. The base font size is 10.0 by default
		 */
		public float getFontSize() {
			return fontSizes[0];
		}

		/**
		 * Set the font size multipliers. Multipliers are used to determine the actual size of fonts by multiplying the
		 * {@link #getFontSize() base font size} by the multiplier to determine the size of a font for a heading.
		 *
		 * @param fontSizeMultipliers
		 *            an array of size 7, where position 1-6 correspond to headings h1 to h6
		 */
		public void setFontSizeMultipliers(float[] fontSizeMultipliers) {
			if (fontSizeMultipliers.length != 7) {
				throw new IllegalArgumentException();
			}
			for (float fontSizeMultiplier : fontSizeMultipliers) {
				if (fontSizeMultiplier < 0.2) {
					throw new IllegalArgumentException();
				}
			}
			System.arraycopy(fontSizeMultipliers, 0, this.fontSizeMultipliers, 0, 7);
		}

		/**
		 * The font size multipliers. Multipliers are used to determine the actual size of fonts by multiplying the
		 * {@link #getFontSize() base font size} by the multiplier to determine the size of a font for a heading.
		 *
		 * @return an array of size 7, where position 1-6 correspond to headings h1 to h6
		 */
		public float[] getFontSizeMultipliers() {
			float[] values = new float[7];
			System.arraycopy(fontSizeMultipliers, 0, values, 0, 7);
			return values;
		}

		/**
		 * indicate if external link URLs should be emitted in the text. The default is true.
		 */
		public boolean isShowExternalLinks() {
			return showExternalLinks;
		}

		/**
		 * indicate if external link URLs should be emitted in the text. The default is true.
		 */
		public void setShowExternalLinks(boolean showExternalLinks) {
			this.showExternalLinks = showExternalLinks;
		}

		/**
		 * Indicate if links should be underlined. The default is false.
		 */
		public boolean isUnderlineLinks() {
			return underlineLinks;
		}

		/**
		 * Indicate if links should be underlined. The default is false.
		 */
		public void setUnderlineLinks(boolean underlineLinks) {
			this.underlineLinks = underlineLinks;
		}

		/**
		 * Indicate if h1 headings should start a new page. The default is true.
		 */
		public boolean isPageBreakOnHeading1() {
			return pageBreakOnHeading1;
		}

		/**
		 * Indicate if h1 headings should start a new page. The default is true.
		 */
		public void setPageBreakOnHeading1(boolean pageBreakOnHeading1) {
			this.pageBreakOnHeading1 = pageBreakOnHeading1;
		}

		/**
		 * a title to be emitted on the title page
		 */
		public String getTitle() {
			return title;
		}

		/**
		 * a title to be emitted on the title page
		 */
		public void setTitle(String title) {
			this.title = title;
		}

		/**
		 * a sub-title to be emitted on the title page
		 */
		public String getSubTitle() {
			return subTitle;
		}

		/**
		 * a sub-title to be emitted on the title page
		 */
		public void setSubTitle(String subTitle) {
			this.subTitle = subTitle;
		}

		/**
		 * indicate if the text 'Note: ', 'Tip: ', and 'Warning: ' should be added to blocks of type
		 * {@link BlockType#NOTE}, {@link BlockType#TIP}, and {@link BlockType#WARNING} respectively.
		 */
		public boolean isPanelText() {
			return panelText;
		}

		/**
		 * indicate if the text 'Note: ', 'Tip: ', and 'Warning: ' should be added to blocks of type
		 * {@link BlockType#NOTE}, {@link BlockType#TIP}, and {@link BlockType#WARNING} respectively.
		 */
		public void setPanelText(boolean panelText) {
			this.panelText = panelText;
		}

		/**
		 * a document version number to emit on the title page
		 */
		public String getVersion() {
			return version;
		}

		/**
		 * a document version number to emit on the title page
		 */
		public void setVersion(String version) {
			this.version = version;
		}

		/**
		 * a date to emit on the title page
		 */
		public String getDate() {
			return date;
		}

		/**
		 * a date to emit on the title page
		 */
		public void setDate(String date) {
			this.date = date;
		}

		/**
		 * an author to emit on the title page
		 */
		public String getAuthor() {
			return author;
		}

		/**
		 * an author to emit on the title page
		 */
		public void setAuthor(String author) {
			this.author = author;
		}

		/**
		 * a copyright to emit in the document page footer
		 */
		public String getCopyright() {
			return copyright;
		}

		/**
		 * a copyright to emit in the document page footer
		 */
		public void setCopyright(String copyright) {
			this.copyright = copyright;
		}

		/**
		 * indicate if pages should be numbered
		 */
		public boolean isPageNumbering() {
			return pageNumbering;
		}

		/**
		 * indicate if pages should be numbered
		 */
		public void setPageNumbering(boolean pageNumbering) {
			this.pageNumbering = pageNumbering;
		}

		/**
		 * The page margin in cm. Defaults to 1.5cm.
		 */
		public float getPageMargin() {
			return pageMargin;
		}

		/**
		 * The page margin in cm. Defaults to 1.5cm.
		 */
		public void setPageMargin(float pageMargin) {
			this.pageMargin = pageMargin;
		}

		/**
		 * The page height in cm. Defaults to A4 sizing (29.7cm)
		 */
		public float getPageHeight() {
			return pageHeight;
		}

		/**
		 * The page height in cm. Defaults to A4 sizing (29.7cm)
		 */
		public void setPageHeight(float pageHeight) {
			this.pageHeight = pageHeight;
		}

		/**
		 * The page width in cm. Defaults to A4 sizing (21.0cm)
		 */
		public float getPageWidth() {
			return pageWidth;
		}

		/**
		 * The page width in cm. Defaults to A4 sizing (21.0cm)
		 */
		public void setPageWidth(float pageWidth) {
			this.pageWidth = pageWidth;
		}

		/**
		 * Sets the <b>reference-orientation</b> property of the master page in degrees. Defaults to 90 degrees.
		 *
		 * @param referenceOrientation
		 *            the master page orientation in degrees.
		 */
		public void setReferenceOrientation(float referenceOrientation) {
			this.referenceOrientation = referenceOrientation;
		}

		/**
		 * The <b>reference-orientation</b> property of the master page in degrees. Defaults to 90 degrees.
		 *
		 * @return the master page orientation in degrees.
		 */
		public float getReferenceOrientation() {
			return referenceOrientation;
		}

		/**
		 * Returns the margins of the master page.
		 *
		 * @return master page margins
		 */
		public Margins getPageMargins() {
			return pageMargins;
		}

		/**
		 * Returns the body margins.
		 *
		 * @return body margins
		 */
		public Margins getBodyMargins() {
			return bodyMargins;
		}

		/**
		 * Sets the page margins. This method allows each margin to be specified individually.
		 *
		 * @param pageMargins
		 *            the page margins.
		 * @see #setPageMargin(float)
		 */
		public void setPageMargins(Margins pageMargins) {
			this.pageMargins = pageMargins;
		}

		/**
		 * Sets the body margins. This method allows each margin to be specified individually.
		 *
		 * @param boduMargins
		 *            the page margins.
		 */
		public void setBodyMargins(Margins bodyMargins) {
			this.bodyMargins = bodyMargins;
		}

		/**
		 *
		 */
		public void setBodyBeforeRegion(Region region) {
			region.setName("before"); //$NON-NLS-1$
			this.bodyBeforeRegion = region;
		}

		/**
		 *
		 */
		public Region getBodyBeforeRegion() {
			return bodyBeforeRegion;
		}

		/**
		 *
		 */
		public void setBodyAfterRegion(Region region) {
			region.setName("after"); //$NON-NLS-1$
			this.bodyAfterRegion = region;
		}

		/**
		 *
		 */
		public Region getBodyAfterRegion() {
			return bodyAfterRegion;
		}

		/**
		 *
		 */
		public void setBodyStartRegion(Region region) {
			region.setName("start"); //$NON-NLS-1$
			this.bodyStartRegion = region;
		}

		/**
		 *
		 */
		public Region getBodyStartRegion() {
			return bodyStartRegion;
		}

		/**
		 *
		 */
		public void setBodyEndRegion(Region region) {
			region.setName("end"); //$NON-NLS-1$
			this.bodyEndRegion = region;
		}

		/**
		 *
		 */
		public Region getBodyEndRegion() {
			return bodyEndRegion;
		}

	}
}
