/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop.render.xml;

// Java
import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.AttributesImpl;

import org.apache.xmlgraphics.util.XMLizable;

import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.area.Area;
import org.apache.fop.area.AreaTreeObject;
import org.apache.fop.area.BeforeFloat;
import org.apache.fop.area.Block;
import org.apache.fop.area.BlockViewport;
import org.apache.fop.area.BodyRegion;
import org.apache.fop.area.BookmarkData;
import org.apache.fop.area.CTM;
import org.apache.fop.area.DestinationData;
import org.apache.fop.area.Footnote;
import org.apache.fop.area.LineArea;
import org.apache.fop.area.MainReference;
import org.apache.fop.area.NormalFlow;
import org.apache.fop.area.OffDocumentExtensionAttachment;
import org.apache.fop.area.OffDocumentItem;
import org.apache.fop.area.PageSequence;
import org.apache.fop.area.PageViewport;
import org.apache.fop.area.RegionReference;
import org.apache.fop.area.RegionViewport;
import org.apache.fop.area.Span;
import org.apache.fop.area.Trait;
import org.apache.fop.area.Trait.Background;
import org.apache.fop.area.Trait.InternalLink;
import org.apache.fop.area.inline.Container;
import org.apache.fop.area.inline.ForeignObject;
import org.apache.fop.area.inline.Image;
import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.area.inline.InlineBlockParent;
import org.apache.fop.area.inline.InlineParent;
import org.apache.fop.area.inline.Leader;
import org.apache.fop.area.inline.Space;
import org.apache.fop.area.inline.SpaceArea;
import org.apache.fop.area.inline.TextArea;
import org.apache.fop.area.inline.Viewport;
import org.apache.fop.area.inline.WordArea;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.extensions.ExtensionAttachment;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.render.PrintRenderer;
import org.apache.fop.render.Renderer;
import org.apache.fop.render.RendererContext;
import org.apache.fop.render.XMLHandler;
import org.apache.fop.util.ColorUtil;
import org.apache.fop.util.QName;

/**
 * Renderer that renders areas to XML for debugging purposes.
 * This creates an xml that contains the information of the area
 * tree. It does not output any state or derived information.
 * The output can be used to build a new area tree which can be 
 * rendered to any renderer.
 */
public class XMLRenderer extends PrintRenderer {

    /** XML MIME type */
    public static final String XML_MIME_TYPE = MimeConstants.MIME_FOP_AREA_TREE;

    /** Main namespace in use. */
    public static final String NS = "";

    /** CDATA type */
    public static final String CDATA = "CDATA";

    /** An empty Attributes object used when no attributes are needed. */
    public static final Attributes EMPTY_ATTS = new AttributesImpl();

    private boolean startedSequence = false;
    private RendererContext context;
    private boolean compactFormat = false;

    /** If not null, the XMLRenderer will mimic another renderer by using its font setup. */
    protected Renderer mimic;

    /** ContentHandler that the generated XML is written to */
    protected ContentHandler handler;

    /** AttributesImpl instance that can be used during XML generation. */
    protected AttributesImpl atts = new AttributesImpl();

    /** The OutputStream to write the generated XML to. */
    protected OutputStream out;

    /** A list of ExtensionAttachements received through processOffDocumentItem() */
    protected List extensionAttachments;

    /**
     * Creates a new XML renderer.
     */
    public XMLRenderer() {
        context = new RendererContext(this, XML_MIME_TYPE);
    }

    /**
     * {@inheritDoc}
     */
    public void setUserAgent(FOUserAgent agent) {
        super.setUserAgent(agent);

        XMLHandler xmlHandler = new XMLXMLHandler();
        userAgent.getXMLHandlerRegistry().addXMLHandler(xmlHandler);
        Boolean b = (Boolean)userAgent.getRendererOptions().get("compact-format");
        if (b != null) {
            setCompactFormat(b.booleanValue());
        }
    }

    /**
     * Call this method to make the XMLRenderer mimic a different renderer by using its font
     * setup. This is useful when working with the intermediate format parser.
     * @param renderer the renderer to mimic
     */
    public void mimicRenderer(Renderer renderer) {
        this.mimic = renderer;
    }

    /** {@inheritDoc} */
    public void setupFontInfo(FontInfo inFontInfo) {
        if (mimic != null) {
            mimic.setupFontInfo(inFontInfo);
        } else {
            super.setupFontInfo(inFontInfo);
        }
    }

    /**
     * Sets an outside TransformerHandler to use instead of the default one
     * create in this class in startRenderer().
     * @param handler Overriding TransformerHandler
     */
    public void setContentHandler(ContentHandler handler) {
        this.handler = handler;
    }

    public void setCompactFormat(boolean compact) {
        this.compactFormat = compact;
    }
    
    private boolean isDetailedFormat() {
        return !this.compactFormat;
    }

    /**
     * Handles SAXExceptions.
     * @param saxe the SAXException to handle
     */
    protected void handleSAXException(SAXException saxe) {
        throw new RuntimeException(saxe.getMessage());
    }

    /**
     * Writes a comment to the generated XML.
     * @param comment the comment
     */
    protected void comment(String comment) {
        if (handler instanceof LexicalHandler) { 
            try {
                ((LexicalHandler) handler).comment(comment.toCharArray(), 0, comment.length());
            } catch (SAXException saxe) {
                handleSAXException(saxe);
            }
        }
    }
    
    /**
     * Starts a new element (without attributes).
     * @param tagName tag name of the element
     */
    protected void startElement(String tagName) {
        startElement(tagName, EMPTY_ATTS);
    }

    /**
     * Starts a new element.
     * @param tagName tag name of the element
     * @param atts attributes to add
     */
    protected void startElement(String tagName, Attributes atts) {
        try {
            handler.startElement(NS, tagName, tagName, atts);
        } catch (SAXException saxe) {
            handleSAXException(saxe);
        }
    }

    /**
     * Ends an element.
     * @param tagName tag name of the element
     */
    protected void endElement(String tagName) {
        try {
            handler.endElement(NS, tagName, tagName);
        } catch (SAXException saxe) {
            handleSAXException(saxe);
        }
    }

    /**
     * Sends plain text to the XML
     * @param text the text
     */
    protected void characters(String text) {
        try {
            char[] ca = text.toCharArray();
            handler.characters(ca, 0, ca.length);
        } catch (SAXException saxe) {
            handleSAXException(saxe);
        }
    }

    /**
     * Adds a new attribute to the protected member variable "atts".
     * @param name name of the attribute
     * @param value value of the attribute
     */
    protected void addAttribute(String name, String value) {
        atts.addAttribute(NS, name, name, CDATA, value);
    }

    /**
     * Adds a new attribute to the protected member variable "atts".
     * @param name name of the attribute
     * @param value value of the attribute
     */
    protected void addAttribute(QName name, String value) {
        atts.addAttribute(name.getNamespaceURI(), name.getLocalName(), name.getQName(), 
                CDATA, value);
    }

    /**
     * Adds a new attribute to the protected member variable "atts".
     * @param name name of the attribute
     * @param value value of the attribute
     */
    protected void addAttribute(String name, int value) {
        addAttribute(name, Integer.toString(value));
    }

    /**
     * Adds a new attribute to the protected member variable "atts".
     * @param name name of the attribute
     * @param rect a Rectangle2D to format and use as attribute value
     */
    protected void addAttribute(String name, Rectangle2D rect) {
        addAttribute(name, createString(rect));
    }

    /**
     * Adds the general Area attributes.
     * @param area Area to extract attributes from
     */
    protected void addAreaAttributes(Area area) {
        addAttribute("ipd", area.getIPD());
        addAttribute("bpd", area.getBPD());
        if (isDetailedFormat()) {
            if (area.getIPD() != 0) {
                addAttribute("ipda", area.getAllocIPD());
            }
            if (area.getBPD() != 0) {
                addAttribute("bpda", area.getAllocBPD());
            }
            addAttribute("bap", area.getBorderAndPaddingWidthStart() + " "
                    + area.getBorderAndPaddingWidthEnd() + " "
                    + area.getBorderAndPaddingWidthBefore() + " "
                    + area.getBorderAndPaddingWidthAfter());
        }
    }

    /**
     * Adds attributes from traits of an Area.
     * @param area Area to extract traits from
     */
    protected void addTraitAttributes(Area area) {
        Map traitMap = area.getTraits();
        if (traitMap != null) {
            Iterator iter = traitMap.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry traitEntry = (Map.Entry) iter.next();
                Object key = traitEntry.getKey();
                String name = Trait.getTraitName(key);
                Class clazz = Trait.getTraitClass(key);
                if ("break-before".equals(name) || "break-after".equals(name)) {
                    continue;
                }
                Object value = traitEntry.getValue();
                if (key == Trait.FONT) {
                    FontTriplet triplet = (FontTriplet)value;
                    addAttribute("font-name", triplet.getName());
                    addAttribute("font-style", triplet.getStyle());
                    addAttribute("font-weight", triplet.getWeight());
                } else if (clazz.equals(InternalLink.class)) {
                    InternalLink iLink = (InternalLink)value;
                    addAttribute(name, iLink.xmlAttribute());
                } else if (clazz.equals(Background.class)) {
                    Background bkg = (Background)value;
                    //TODO Remove the following line (makes changes in the test checks necessary)
                    addAttribute(name, bkg.toString());
                    if (bkg.getColor() != null) {
                        addAttribute("bkg-color", bkg.getColor().toString());
                    }
                    if (bkg.getURL() != null) {
                        addAttribute("bkg-img", bkg.getURL());
                        String repString;
                        int repeat = bkg.getRepeat();
                        switch (repeat) {
                        case Constants.EN_REPEAT:
                            repString = "repeat";
                            break;
                        case Constants.EN_REPEATX:
                            repString = "repeat-x";
                            break;
                        case Constants.EN_REPEATY:
                            repString = "repeat-y";
                            break;
                        case Constants.EN_NOREPEAT:
                            repString = "no-repeat";
                            break;
                        default:
                            throw new IllegalStateException(
                                    "Illegal value for repeat encountered: " + repeat);
                        }
                        addAttribute("bkg-repeat", repString);
                        addAttribute("bkg-horz-offset", bkg.getHoriz());
                        addAttribute("bkg-vert-offset", bkg.getVertical());
                    }
                } else if (clazz.equals(Color.class)) {
                    Color c = (Color)value;
                    addAttribute(name, ColorUtil.colorToString(c));
                } else if (key == Trait.START_INDENT || key == Trait.END_INDENT) {
                    if (((Integer)value).intValue() != 0) {
                        addAttribute(name, value.toString());
                    }
                } else {
                    addAttribute(name, value.toString());
                }
            }
        }
        
        transferForeignObjects(area);
    }

    private void transferForeignObjects(AreaTreeObject ato) {
        Map prefixes = new java.util.HashMap();
        Iterator iter = ato.getForeignAttributes().entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry)iter.next();
            QName qname = (QName)entry.getKey();
            prefixes.put(qname.getPrefix(), qname.getNamespaceURI());
            addAttribute(qname, (String)entry.getValue());
        }
        //Namespace declarations
        iter = prefixes.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry)iter.next();
            String qn = "xmlns:" + (String)entry.getKey();
            atts.addAttribute("", (String)entry.getKey(), qn, 
                    CDATA, (String)entry.getValue());
        }
    }

    private String createString(Rectangle2D rect) {
        return "" + (int) rect.getX() + " " + (int) rect.getY() + " "
                  + (int) rect.getWidth() + " " + (int) rect.getHeight();
    }

    private void handleDocumentExtensionAttachments() {
        if (extensionAttachments != null && extensionAttachments.size() > 0) {
            handleExtensionAttachments(extensionAttachments);
            extensionAttachments.clear();
        }
    }

    /** {@inheritDoc} */
    public void processOffDocumentItem(OffDocumentItem oDI) {
        if (oDI instanceof BookmarkData) {
            renderBookmarkTree((BookmarkData) oDI);
        } else if (oDI instanceof DestinationData) {
            renderDestination((DestinationData) oDI);
        } else if (oDI instanceof OffDocumentExtensionAttachment) {
            ExtensionAttachment attachment = ((OffDocumentExtensionAttachment)oDI).getAttachment();
            if (extensionAttachments == null) {
                extensionAttachments = new java.util.ArrayList();
            }
            extensionAttachments.add(attachment);
        } else {
            String warn = "Ignoring OffDocumentItem: " + oDI;
            log.warn(warn);
        }
    }

    /**
     * Renders a BookmarkTree object
     * @param bookmarkRoot the BookmarkData object representing the top of the tree
     */
    protected void renderBookmarkTree(BookmarkData bookmarkRoot) {
        if (bookmarkRoot.getWhenToProcess() == OffDocumentItem.END_OF_DOC) {
            endPageSequence();
        }
        /* If this kind of handling is also necessary for other renderers, then
           better add endPageSequence to the Renderer interface and call it
           explicitly from model.endDocument() */

        startElement("bookmarkTree");
        for (int i = 0; i < bookmarkRoot.getCount(); i++) {
            renderBookmarkItem(bookmarkRoot.getSubData(i));
        }
        endElement("bookmarkTree");
    }

    private void renderBookmarkItem(BookmarkData bm) {
        atts.clear();
        addAttribute("title", bm.getBookmarkTitle());
        addAttribute("show-children", String.valueOf(bm.showChildItems()));
        PageViewport pv = bm.getPageViewport();
        String pvKey = pv == null ? null : pv.getKey();
        addAttribute("internal-link",
                     InternalLink.makeXMLAttribute(pvKey, bm.getIDRef()));
        startElement("bookmark", atts);
        for (int i = 0; i < bm.getCount(); i++) {
            renderBookmarkItem(bm.getSubData(i));
        }
        endElement("bookmark");
    }

    /**
     * Renders a DestinationData object (named destination)
     * @param destination the destination object
     */
    protected void renderDestination(DestinationData destination) {
        if (destination.getWhenToProcess() == OffDocumentItem.END_OF_DOC) {
            endPageSequence();
        }
        atts.clear();
        PageViewport pv = destination.getPageViewport();
        String pvKey = pv == null ? null : pv.getKey();
        addAttribute("internal-link",
                InternalLink.makeXMLAttribute(pvKey, destination.getIDRef()));
        startElement("destination", atts);
        endElement("destination");
    }

    /** {@inheritDoc} */
    public void startRenderer(OutputStream outputStream)
                throws IOException {
        log.debug("Rendering areas to Area Tree XML");

        if (this.handler == null) {
            SAXTransformerFactory factory
                = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
            try {
                TransformerHandler transformerHandler = factory.newTransformerHandler();
                this.handler = transformerHandler;
                StreamResult res = new StreamResult(outputStream);
                transformerHandler.setResult(res);
            } catch (TransformerConfigurationException tce) {
                throw new RuntimeException(tce.getMessage());
            }

            this.out = outputStream;
        }

        try {
            handler.startDocument();
        } catch (SAXException saxe) {
            handleSAXException(saxe);
        }
        if (userAgent.getProducer() != null) {
            comment("Produced by " + userAgent.getProducer());
        }
        startElement("areaTree");
    }

    /**
     * {@inheritDoc}
     */
    public void stopRenderer() throws IOException {
        endPageSequence();
        endElement("areaTree");
        try {
            handler.endDocument();
        } catch (SAXException saxe) {
            handleSAXException(saxe);
        }
        if (this.out != null) {
            this.out.flush();
        }
        log.debug("Written out Area Tree XML");
    }

    /**
     * {@inheritDoc}
     */
    public void renderPage(PageViewport page) throws IOException, FOPException {
        atts.clear();
        addAttribute("bounds", page.getViewArea());
        addAttribute("key", page.getKey());
        addAttribute("nr", page.getPageNumber());
        addAttribute("formatted-nr", page.getPageNumberString());
        if (page.getSimplePageMasterName() != null) {
            addAttribute("simple-page-master-name", page.getSimplePageMasterName());
        }
        if (page.isBlank()) {
            addAttribute("blank", "true");
        }
        transferForeignObjects(page);
        startElement("pageViewport", atts);
        startElement("page");

        handlePageExtensionAttachments(page);
        super.renderPage(page);

        endElement("page");
        endElement("pageViewport");
    }

    private void handleExtensionAttachments(List attachments) {
        if (attachments != null && attachments.size() > 0) {
            startElement("extension-attachments");
            Iterator i = attachments.iterator();
            while (i.hasNext()) {
                ExtensionAttachment attachment = (ExtensionAttachment)i.next();
                if (attachment instanceof XMLizable) {
                    try {
                        ((XMLizable)attachment).toSAX(this.handler);
                    } catch (SAXException e) {
                        log.error("Error while serializing Extension Attachment", e);
                    }
                } else {
                    String warn = "Ignoring non-XMLizable ExtensionAttachment: " + attachment;
                    log.warn(warn);
                }
            }
            endElement("extension-attachments");
        }
    }

    private void handlePageExtensionAttachments(PageViewport page) {
        handleExtensionAttachments(page.getExtensionAttachments());
    }

    /** {@inheritDoc} */
    public void startPageSequence(PageSequence pageSequence) {
        handleDocumentExtensionAttachments();
        endPageSequence();  // move this before handleDocumentExtensionAttachments() ?
        startedSequence = true;
        atts.clear();
        if (pageSequence.getLanguage() != null) {
            addAttribute("language", pageSequence.getLanguage());
        }
        if (pageSequence.getCountry() != null) {
            addAttribute("country", pageSequence.getCountry());
        }
        startElement("pageSequence", atts);
        LineArea seqTitle = pageSequence.getTitle();
        if (seqTitle != null) {
            startElement("title");
            List children = seqTitle.getInlineAreas();

            for (int count = 0; count < children.size(); count++) {
                InlineArea inline = (InlineArea) children.get(count);
                renderInlineArea(inline);
            }

            endElement("title");
        }
    }

    /**
     * Tells the renderer to finish the current PageSequence
     */
    public void endPageSequence() {
        if (startedSequence) {
            endElement("pageSequence");
        }
        startedSequence = false;
    }

    /**
     * {@inheritDoc}
     */
    protected void renderRegionViewport(RegionViewport port) {
        if (port != null) {
            atts.clear();
            addAreaAttributes(port);
            addTraitAttributes(port);
            addAttribute("rect", port.getViewArea());
            if (port.isClip()) {
                addAttribute("clipped", "true");
            }
            startElement("regionViewport", atts);
            RegionReference region = port.getRegionReference();
            atts.clear();
            addAreaAttributes(region);
            addTraitAttributes(region);
            addAttribute("name", region.getRegionName());
            addAttribute("ctm", region.getCTM().toString());
            if (region.getRegionClass() == FO_REGION_BEFORE) {
                startElement("regionBefore", atts);
                renderRegion(region);
                endElement("regionBefore");
            } else if (region.getRegionClass() == FO_REGION_START) {
                startElement("regionStart", atts);
                renderRegion(region);
                endElement("regionStart");
            } else if (region.getRegionClass() == FO_REGION_BODY) {
                BodyRegion body = (BodyRegion)region;
                if (body.getColumnCount() != 1) {
                    addAttribute("columnGap", body.getColumnGap());
                    addAttribute("columnCount", body.getColumnCount());
                }
                startElement("regionBody", atts);
                renderBodyRegion(body);
                endElement("regionBody");
            } else if (region.getRegionClass() == FO_REGION_END) {
                startElement("regionEnd", atts);
                renderRegion(region);
                endElement("regionEnd");
            } else if (region.getRegionClass() == FO_REGION_AFTER) {
                startElement("regionAfter", atts);
                renderRegion(region);
                endElement("regionAfter");
            }
            endElement("regionViewport");
        }
    }

    /** {@inheritDoc} */
    protected void startVParea(CTM ctm, Rectangle2D clippingRect) {
        //only necessary for graphical output
    }

    /** {@inheritDoc} */
    protected void endVParea() {
        //only necessary for graphical output
    }

    /**
     * {@inheritDoc}
     *          org.apache.fop.area.inline.InlineArea)
     */
    protected void renderInlineAreaBackAndBorders(InlineArea area) {
        //only necessary for graphical output
    }

    /**
     * {@inheritDoc}
     */
    protected void renderBeforeFloat(BeforeFloat bf) {
        startElement("beforeFloat");
        super.renderBeforeFloat(bf);
        endElement("beforeFloat");
    }

    /**
     * {@inheritDoc}
     */
    protected void renderFootnote(Footnote footnote) {
        startElement("footnote");
        super.renderFootnote(footnote);
        endElement("footnote");
    }

    /**
     * {@inheritDoc}
     */
    protected void renderMainReference(MainReference mr) {
        atts.clear();
        addAreaAttributes(mr);
        addTraitAttributes(mr);
        if (mr.getColumnCount() != 1) {
            addAttribute("columnGap", mr.getColumnGap());
        }
        startElement("mainReference", atts);

        Span span = null;
        List spans = mr.getSpans();
        for (int count = 0; count < spans.size(); count++) {
            span = (Span) spans.get(count);
            atts.clear();
            if (span.getColumnCount() != 1) {
                addAttribute("columnCount", span.getColumnCount());
            }
            addAreaAttributes(span);
            addTraitAttributes(span);
            startElement("span", atts);
            for (int c = 0; c < span.getColumnCount(); c++) {
                NormalFlow flow = (NormalFlow) span.getNormalFlow(c);

                renderFlow(flow);
            }
            endElement("span");
        }
        endElement("mainReference");
    }

    /**
     * {@inheritDoc}
     */
    protected void renderFlow(NormalFlow flow) {
        // the normal flow reference area contains stacked blocks
        atts.clear();
        addAreaAttributes(flow);
        addTraitAttributes(flow);
        startElement("flow", atts);
        super.renderFlow(flow);
        endElement("flow");
    }

    /**
     * {@inheritDoc}
     */
    protected void renderBlock(Block block) {
        atts.clear();
        addAreaAttributes(block);
        addTraitAttributes(block);
        int positioning = block.getPositioning();
        if (block instanceof BlockViewport) {
            BlockViewport bvp = (BlockViewport)block;
            boolean abspos = false;
            if (bvp.getPositioning() == Block.ABSOLUTE
                    || bvp.getPositioning() == Block.FIXED) {
                abspos = true;
            }
            if (abspos) {
                addAttribute("left-position", bvp.getXOffset());
                addAttribute("top-position", bvp.getYOffset());
            }
            addAttribute("ctm", bvp.getCTM().toString());
            if (bvp.getClip()) {
                addAttribute("clipped", "true");
            }
        } else {
            if (block.getXOffset() != 0) {
                addAttribute("left-offset", block.getXOffset());
            }
            if (block.getYOffset() != 0) {
                addAttribute("top-offset", block.getYOffset());
            }
        }
        switch (positioning) {
        case Block.RELATIVE:
            addAttribute("positioning", "relative");
            break;
        case Block.ABSOLUTE:
            addAttribute("positioning", "absolute");
            break;
        case Block.FIXED:
            addAttribute("positioning", "fixed");
            break;
        default: //nop
        }
        startElement("block", atts);
        super.renderBlock(block);
        endElement("block");
    }

    /**
     * {@inheritDoc}
     */
    protected void renderLineArea(LineArea line) {
        atts.clear();
        addAreaAttributes(line);
        addTraitAttributes(line);
        startElement("lineArea", atts);
        super.renderLineArea(line);
        endElement("lineArea");
    }

    /**
     * {@inheritDoc}
     */
    protected void renderInlineArea(InlineArea inlineArea) {
        atts.clear();
        if (inlineArea.getClass() == InlineArea.class) {
            // Generic inline area. This is implemented to allow the 0x0 "dummy"
            // area generated by fo:wrapper to pass its id.
            addAreaAttributes(inlineArea);
            addTraitAttributes(inlineArea);
            startElement("inline", atts);
            endElement("inline");
        } else {
            super.renderInlineArea(inlineArea);
            // calls specific renderers for Text, Space, Viewport, etc. etc.
        }
    }

    /**
     * {@inheritDoc}
     */
    protected void renderViewport(Viewport viewport) {
        atts.clear();
        addAreaAttributes(viewport);
        addTraitAttributes(viewport);
        addAttribute("offset", viewport.getOffset());
        addAttribute("pos", viewport.getContentPosition());
        if (viewport.getClip()) {
            addAttribute("clip", "true");
        }
        startElement("viewport", atts);
        super.renderViewport(viewport);
        endElement("viewport");
    }

    /**
     * {@inheritDoc}
     */
    public void renderImage(Image image, Rectangle2D pos) {
        atts.clear();
        addAreaAttributes(image);
        addTraitAttributes(image);
        addAttribute("url", image.getURL());
        //addAttribute("pos", pos);
        startElement("image", atts);
        endElement("image");
    }

    /**
     * {@inheritDoc}
     */
    public void renderContainer(Container cont) {
        startElement("container");
        super.renderContainer(cont);
        endElement("container");
    }

    /**
     * Renders an fo:foreing-object.
     * @param fo the foreign object
     * @param pos the position of the foreign object
     * @see org.apache.fop.render.AbstractRenderer#renderForeignObject(ForeignObject, Rectangle2D)
     */
    public void renderForeignObject(ForeignObject fo, Rectangle2D pos) {
        atts.clear();
        addAreaAttributes(fo);
        addTraitAttributes(fo);
        String ns = fo.getNameSpace();
        addAttribute("ns", ns);
        startElement("foreignObject", atts);
        Document doc = fo.getDocument();
        context.setProperty(XMLXMLHandler.HANDLER, handler);
        renderXML(context, doc, ns);
        endElement("foreignObject");
    }

    /**
     * {@inheritDoc}
     */
    protected void renderInlineSpace(Space space) {
        atts.clear();
        addAreaAttributes(space);
        addTraitAttributes(space);
        addAttribute("offset", space.getOffset());
        startElement("space", atts);
        endElement("space");
    }

    /**
     * {@inheritDoc}
     */
    protected void renderText(TextArea text) {
        atts.clear();
        if (text.getTextWordSpaceAdjust() != 0) {
            addAttribute("twsadjust", text.getTextWordSpaceAdjust());
        }
        if (text.getTextLetterSpaceAdjust() != 0) {
            addAttribute("tlsadjust", text.getTextLetterSpaceAdjust());
        }
        addAttribute("offset", text.getOffset());
        addAttribute("baseline", text.getBaselineOffset());
        addAreaAttributes(text);
        addTraitAttributes(text);
        startElement("text", atts);
        super.renderText(text);
        endElement("text");
    }

    /**
     * {@inheritDoc}
     */
    protected void renderWord(WordArea word) {
        atts.clear();
        addAttribute("offset", word.getOffset());
        int[] letterAdjust = word.getLetterAdjustArray(); 
        if (letterAdjust != null) {
            StringBuffer sb = new StringBuffer(64);
            boolean nonZeroFound = false;
            for (int i = 0, c = letterAdjust.length; i < c; i++) {
                if (i > 0) {
                    sb.append(' ');
                }
                sb.append(letterAdjust[i]);
                nonZeroFound |= (letterAdjust[i] != 0);
            }
            if (nonZeroFound) {
                addAttribute("letter-adjust", sb.toString());
            }
        }
        startElement("word", atts);
        characters(word.getWord());
        endElement("word");
        super.renderWord(word);
    }

    /**
     * {@inheritDoc}
     */
    protected void renderSpace(SpaceArea space) {
        atts.clear();
        addAttribute("offset", space.getOffset());
        if (!space.isAdjustable()) {
            addAttribute("adj", "false"); //default is true
        }
        startElement("space", atts);
        characters(space.getSpace());
        endElement("space");
        super.renderSpace(space);
    }

    /**
     * {@inheritDoc}
     */
    protected void renderInlineParent(InlineParent ip) {
        atts.clear();
        addAreaAttributes(ip);
        addTraitAttributes(ip);
        addAttribute("offset", ip.getOffset());
        startElement("inlineparent", atts);
        super.renderInlineParent(ip);
        endElement("inlineparent");
    }

    /**
     * {@inheritDoc}
     */
    protected void renderInlineBlockParent(InlineBlockParent ibp) {
        atts.clear();
        addAreaAttributes(ibp);
        addTraitAttributes(ibp);
        addAttribute("offset", ibp.getOffset());
        startElement("inlineblockparent", atts);
        super.renderInlineBlockParent(ibp);
        endElement("inlineblockparent");
    }

    /**
     * {@inheritDoc}
     */
    protected void renderLeader(Leader area) {
        atts.clear();
        addAreaAttributes(area);
        addTraitAttributes(area);
        addAttribute("offset", area.getOffset());
        addAttribute("ruleStyle", area.getRuleStyleAsString());
        addAttribute("ruleThickness", area.getRuleThickness());
        startElement("leader", atts);
        endElement("leader");
        super.renderLeader(area);
    }

    /** {@inheritDoc} */
    public String getMimeType() {
        return XML_MIME_TYPE;
    }

}

