package org.apache.maven.doxia.module.fo;

/*
 * 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.
 */

import java.io.IOException;
import java.io.Writer;

import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Stack;

import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML.Tag;

import org.apache.maven.doxia.document.DocumentCover;
import org.apache.maven.doxia.document.DocumentMeta;
import org.apache.maven.doxia.document.DocumentModel;
import org.apache.maven.doxia.document.DocumentTOC;
import org.apache.maven.doxia.document.DocumentTOCItem;
import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
import org.apache.maven.doxia.util.DoxiaUtils;
import org.apache.maven.doxia.util.HtmlTools;

import org.codehaus.plexus.util.StringUtils;

/**
 * A Doxia Sink that produces an aggregated FO model. The usage is similar to the following:
 * <pre>
 * FoAggregateSink sink = new FoAggregateSink( writer );
 * sink.setDocumentModel( documentModel );
 * sink.beginDocument();
 * sink.coverPage();
 * sink.toc();
 * ...
 * sink.endDocument();
 * </pre>
 * <b>Note</b>: the documentModel object contains several
 * <a href="https://maven.apache.org/doxia/doxia/doxia-core/document.html">document metadata</a>, but only a few
 * of them are used in this sink (i.e. author, confidential, date and title), the others are ignored.
 *
 * @author ltheussl
 * @version $Id$
 * @since 1.1
 */
public class FoAggregateSink
    extends FoSink
{
    /**
     * No Table Of Content.
     *
     * @see #setDocumentModel(DocumentModel, int)
     */
    public static final int TOC_NONE = 0;

    /**
     * Table Of Content at the start of the document.
     *
     * @see #setDocumentModel(DocumentModel, int)
     */
    public static final int TOC_START = 1;

    /**
     * Table Of Content at the end of the document.
     *
     * @see #setDocumentModel(DocumentModel, int)
     */
    public static final int TOC_END = 2;

    // TODO: make configurable
    private static final String COVER_HEADER_HEIGHT = "1.5in";

    /**
     * The document model to be used by this sink.
     */
    private DocumentModel docModel;

    /**
     * Counts the current chapter level.
     */
    private int chapter = 0;

    /**
     * Name of the source file of the current document, relative to the source root.
     */
    private String docName;

    /**
     * Title of the chapter, used in the page header.
     */
    private String docTitle = "";

    /**
     * Content in head is ignored in aggregated documents.
     */
    private boolean ignoreText;

    /**
     * Current position of the TOC, see {@link #TOC_POSITION}
     */
    private int tocPosition;

    /**
     * Used to get the current position in the TOC.
     */
    private final Stack<NumberedListItem> tocStack = new Stack<>();

    /**
     * Constructor.
     *
     * @param writer The writer for writing the result.
     */
    public FoAggregateSink( Writer writer )
    {
        super( writer );
    }

    /**
     * {@inheritDoc}
     */
    public void head()
    {
        head( null );
    }

    /**
     * {@inheritDoc}
     */
    public void head( SinkEventAttributes attributes )
    {
        init();

        ignoreText = true;
    }

    /**
     * {@inheritDoc}
     */
    public void head_()
    {
        ignoreText = false;
        writeEOL();
    }

    /**
     * {@inheritDoc}
     */
    public void title()
    {
        title( null );
    }

    /**
     * {@inheritDoc}
     */
    public void title( SinkEventAttributes attributes )
    {
        // ignored
    }

    /**
     * {@inheritDoc}
     */
    public void title_()
    {
        // ignored
    }

    /**
     * {@inheritDoc}
     */
    public void author()
    {
        author( null );
    }

    /**
     * {@inheritDoc}
     */
    public void author( SinkEventAttributes attributes )
    {
        // ignored
    }

    /**
     * {@inheritDoc}
     */
    public void author_()
    {
        // ignored
    }

    /**
     * {@inheritDoc}
     */
    public void date()
    {
        date( null );
    }

    /**
     * {@inheritDoc}
     */
    public void date( SinkEventAttributes attributes )
    {
        // ignored
    }

    /**
     * {@inheritDoc}
     */
    public void date_()
    {
        // ignored
    }

    /**
     * {@inheritDoc}
     */
    public void body()
    {
        body( null );
    }

    /**
     * {@inheritDoc}
     */
    public void body( SinkEventAttributes attributes )
    {
        chapter++;

        resetSectionCounter();

        startPageSequence( getHeaderText(), getFooterText() );

        if ( docName == null )
        {
            getLog().warn( "No document root specified, local links will not be resolved correctly!" );
        }
        else
        {
            writeStartTag( BLOCK_TAG, "" );
        }

    }

    /**
     * {@inheritDoc}
     */
    public void body_()
    {
        writeEOL();
        writeEndTag( BLOCK_TAG );
        writeEndTag( FLOW_TAG );
        writeEndTag( PAGE_SEQUENCE_TAG );

        // reset document name
        docName = null;
    }

    /**
     * Sets the title of the current document. This is used as a chapter title in the page header.
     *
     * @param title the title of the current document.
     */
    public void setDocumentTitle( String title )
    {
        this.docTitle = title;

        if ( title == null )
        {
            this.docTitle = "";
        }
    }

    /**
     * Sets the name of the current source document, relative to the source root.
     * Used to resolve links to other source documents.
     *
     * @param name the name for the current document.
     */
    public void setDocumentName( String name )
    {
        this.docName = getIdName( name );
    }

    /**
     * Sets the DocumentModel to be used by this sink. The DocumentModel provides all the meta-information
     * required to render a document, eg settings for the cover page, table of contents, etc.
     * <br>
     * By default, a TOC will be added at the beginning of the document.
     *
     * @param model the DocumentModel.
     * @see #setDocumentModel(DocumentModel, int)
     * @see #TOC_START
     */
    public void setDocumentModel( DocumentModel model )
    {
        setDocumentModel( model, TOC_START );
    }

    /**
     * Sets the DocumentModel to be used by this sink. The DocumentModel provides all the meta-information
     * required to render a document, eg settings for the cover page, table of contents, etc.
     *
     * @param model  the DocumentModel, could be null.
     * @param tocPos should be one of these values: {@link #TOC_NONE}, {@link #TOC_START} and {@link #TOC_END}.
     * @since 1.1.2
     */
    public void setDocumentModel( DocumentModel model, int tocPos )
    {
        this.docModel = model;
        if ( !( tocPos == TOC_NONE || tocPos == TOC_START || tocPos == TOC_END ) )
        {
            if ( getLog().isDebugEnabled() )
            {
                getLog().debug( "Unrecognized value for tocPosition: " + tocPos + ", using no toc." );
            }
            tocPos = TOC_NONE;
        }
        this.tocPosition = tocPos;

        if ( this.docModel != null && this.docModel.getToc() != null && this.tocPosition != TOC_NONE )
        {
            DocumentTOCItem tocItem = new DocumentTOCItem();
            tocItem.setName( this.docModel.getToc().getName() );
            tocItem.setRef( "./toc" );
            List<DocumentTOCItem> items = new LinkedList<>();
            if ( this.tocPosition == TOC_START )
            {
                items.add( tocItem );
            }
            items.addAll( this.docModel.getToc().getItems() );
            if ( this.tocPosition == TOC_END )
            {
                items.add( tocItem );
            }

            this.docModel.getToc().setItems( items );
        }
    }

    /**
     * Translates the given name to a usable id.
     * Prepends "./" and strips any extension.
     *
     * @param name the name for the current document.
     * @return String
     */
    private String getIdName( String name )
    {
        if ( StringUtils.isEmpty( name ) )
        {
            getLog().warn( "Empty document reference, links will not be resolved correctly!" );
            return "";
        }

        String idName = name.replace( '\\', '/' );

        // prepend "./" and strip extension
        if ( !idName.startsWith( "./" ) )
        {
            idName = "./" + idName;
        }

        if ( idName.substring( 2 ).lastIndexOf( "." ) != -1 )
        {
            idName = idName.substring( 0, idName.lastIndexOf( "." ) );
        }

        while ( idName.contains( "//" ) )
        {
            idName = StringUtils.replace( idName, "//", "/" );
        }

        return idName;
    }

    // -----------------------------------------------------------------------
    //
    // -----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void figureGraphics( String name )
    {
        figureGraphics( name, null );
    }

    /**
     * {@inheritDoc}
     */
    public void figureGraphics( String src, SinkEventAttributes attributes )
    {
        String anchor = src;

        while ( anchor.startsWith( "./" ) )
        {
            anchor = anchor.substring( 2 );
        }

        if ( anchor.startsWith( "../" ) && docName != null )
        {
            anchor = resolveLinkRelativeToBase( anchor );
        }

        super.figureGraphics( anchor, attributes );
    }

    /**
     * {@inheritDoc}
     */
    public void anchor( String name )
    {
        anchor( name, null );
    }

    /**
     * {@inheritDoc}
     */
    public void anchor( String name, SinkEventAttributes attributes )
    {
        if ( name == null )
        {
            throw new NullPointerException( "Anchor name cannot be null!" );
        }

        String anchor = name;

        if ( !DoxiaUtils.isValidId( anchor ) )
        {
            anchor = DoxiaUtils.encodeId( name, true );

            String msg = "Modified invalid anchor name: '" + name + "' to '" + anchor + "'";
            logMessage( "modifiedLink", msg );
        }

        anchor = "#" + anchor;

        if ( docName != null )
        {
            anchor = docName + anchor;
        }

        writeStartTag( INLINE_TAG, "id", anchor );
    }

    /**
     * {@inheritDoc}
     */
    public void link( String name )
    {
        link( name, null );
    }

    /**
     * {@inheritDoc}
     */
    public void link( String name, SinkEventAttributes attributes )
    {
        if ( name == null )
        {
            throw new NullPointerException( "Link name cannot be null!" );
        }

        if ( DoxiaUtils.isExternalLink( name ) )
        {
            // external links
            writeStartTag( BASIC_LINK_TAG, "external-destination", HtmlTools.escapeHTML( name ) );
            writeStartTag( INLINE_TAG, "href.external" );
            return;
        }

        while ( name.contains( "//" ) )
        {
            name = StringUtils.replace( name, "//", "/" );
        }

        if ( DoxiaUtils.isInternalLink( name ) )
        {
            // internal link (ie anchor is in the same source document)
            String anchor = name.substring( 1 );

            if ( !DoxiaUtils.isValidId( anchor ) )
            {
                String tmp = anchor;
                anchor = DoxiaUtils.encodeId( anchor, true );

                String msg = "Modified invalid anchor name: '" + tmp + "' to '" + anchor + "'";
                logMessage( "modifiedLink", msg );
            }

            if ( docName != null )
            {
                anchor = docName + "#" + anchor;
            }

            writeStartTag( BASIC_LINK_TAG, "internal-destination", HtmlTools.escapeHTML( anchor ) );
            writeStartTag( INLINE_TAG, "href.internal" );
        }
        else if ( name.startsWith( "../" ) )
        {
            // local link (ie anchor is not in the same source document)

            if ( docName == null )
            {
                // can't resolve link without base, fop will issue a warning
                writeStartTag( BASIC_LINK_TAG, "internal-destination", HtmlTools.escapeHTML( name ) );
                writeStartTag( INLINE_TAG, "href.internal" );

                return;
            }

            String anchor = resolveLinkRelativeToBase( chopExtension( name ) );

            writeStartTag( BASIC_LINK_TAG, "internal-destination", HtmlTools.escapeHTML( anchor ) );
            writeStartTag( INLINE_TAG, "href.internal" );
        }
        else
        {
            // local link (ie anchor is not in the same source document)

            String anchor = name;

            if ( anchor.startsWith( "./" ) )
            {
                this.link( anchor.substring( 2 ) );
                return;
            }

            anchor = chopExtension( anchor );

            String base = docName.substring( 0, docName.lastIndexOf( "/" ) );
            anchor = base + "/" + anchor;

            writeStartTag( BASIC_LINK_TAG, "internal-destination", HtmlTools.escapeHTML( anchor ) );
            writeStartTag( INLINE_TAG, "href.internal" );
        }
    }

    // only call this if docName != null !!!
    private String resolveLinkRelativeToBase( String name )
    {
        String anchor = name;

        String base = docName.substring( 0, docName.lastIndexOf( "/" ) );

        if ( base.contains( "/" ) )
        {
            while ( anchor.startsWith( "../" ) )
            {
                base = base.substring( 0, base.lastIndexOf( "/" ) );

                anchor = anchor.substring( 3 );

                if ( base.lastIndexOf( "/" ) == -1 )
                {
                    while ( anchor.startsWith( "../" ) )
                    {
                        anchor = anchor.substring( 3 );
                    }
                    break;
                }
            }
        }

        return base + "/" + anchor;
    }

    private String chopExtension( String name )
    {
        String anchor = name;

        int dot = anchor.lastIndexOf( "." );

        if ( dot != -1 && dot != anchor.length() && anchor.charAt( dot + 1 ) != '/' )
        {
            int hash = anchor.indexOf( "#", dot );

            if ( hash != -1 )
            {
                int dot2 = anchor.indexOf( ".", hash );

                if ( dot2 != -1 )
                {
                    anchor =
                        anchor.substring( 0, dot ) + "#" + HtmlTools.encodeId( anchor.substring( hash + 1, dot2 ) );
                }
                else
                {
                    anchor = anchor.substring( 0, dot ) + "#" + HtmlTools.encodeId(
                        anchor.substring( hash + 1 ) );
                }
            }
            else
            {
                anchor = anchor.substring( 0, dot );
            }
        }

        return anchor;
    }

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    @Override
    protected void writeStartTag( Tag tag, String attributeId )
    {
        if ( !ignoreText )
        {
            super.writeStartTag( tag, attributeId );
        }
    }

    @Override
    protected void writeStartTag( Tag tag, String id, String name )
    {
        if ( !ignoreText )
        {
            super.writeStartTag( tag, id, name );
        }
    }

    @Override
    protected void writeEndTag( Tag t )
    {
        if ( !ignoreText )
        {
            super.writeEndTag( t );
        }
    }

    @Override
    protected void writeEmptyTag( Tag tag, String attributeId )
    {
        if ( !ignoreText )
        {
            super.writeEmptyTag( tag, attributeId );
        }
    }

    @Override
    protected void write( String text )
    {
        if ( !ignoreText )
        {
            super.write( text );
        }
    }

    @Override
    protected void writeln( String text )
    {
        if ( !ignoreText )
        {
            super.writeln( text );
        }
    }

    @Override
    protected void content( String text )
    {
        if ( !ignoreText )
        {
            super.content( text );
        }
    }

    /**
     * Writes EOL.
     */
    protected void newline()
    {
        if ( !ignoreText )
        {
            writeEOL();
        }
    }

    /**
     * Starts a page sequence, depending on the current chapter.
     *
     * @param headerText The text to write in the header, if null, nothing is written.
     * @param footerText The text to write in the footer, if null, nothing is written.
     */
    protected void startPageSequence( String headerText, String footerText )
    {
        if ( chapter == 1 )
        {
            startPageSequence( "0", headerText, footerText );
        }
        else
        {
            startPageSequence( "auto", headerText, footerText );
        }
    }

    /**
     * Returns the text to write in the header of each page.
     *
     * @return String
     */
    protected String getHeaderText()
    {
        return chapter + "   " + docTitle;
    }

    /**
     * Returns the text to write in the footer of each page.
     *
     * @return String
     */
    protected String getFooterText()
    {
        int actualYear;
        String add = " &#8226; " + getBundle( Locale.US ).getString( "footer.rights" );
        String companyName = "";

        if ( docModel != null && docModel.getMeta() != null && docModel.getMeta().isConfidential() )
        {
            add = add + " &#8226; " + getBundle( Locale.US ).getString( "footer.confidential" );
        }

        if ( docModel != null && docModel.getCover() != null && docModel.getCover().getCompanyName() != null )
        {
            companyName = docModel.getCover().getCompanyName();
        }

        if ( docModel != null && docModel.getMeta() != null && docModel.getMeta().getDate() != null )
        {
            Calendar date = Calendar.getInstance();
            date.setTime( docModel.getMeta().getDate() );
            actualYear = date.get( Calendar.YEAR );
        }
        else
        {
            actualYear = Calendar.getInstance().get( Calendar.YEAR );
        }

        return "&#169;" + actualYear + ", " + escaped( companyName, false ) + add;
    }

    @Override
    protected String getChapterString()
    {
        return chapter + ".";
    }

    @Override
    protected void regionBefore( String headerText )
    {
        writeStartTag( STATIC_CONTENT_TAG, "flow-name", "xsl-region-before" );
        writeln( "<fo:table table-layout=\"fixed\" width=\"100%\" >" );
        writeEmptyTag( TABLE_COLUMN_TAG, "column-width", "5.625in" );
        writeEmptyTag( TABLE_COLUMN_TAG, "column-width", "0.625in" );
        writeStartTag( TABLE_BODY_TAG, "" );
        writeStartTag( TABLE_ROW_TAG, "" );
        writeStartTag( TABLE_CELL_TAG, "" );
        writeStartTag( BLOCK_TAG, "header.style" );

        if ( headerText != null )
        {
            write( headerText );
        }

        writeEndTag( BLOCK_TAG );
        writeEndTag( TABLE_CELL_TAG );
        writeStartTag( TABLE_CELL_TAG, "" );
        writeStartTag( BLOCK_TAG, "page.number" );
        writeEmptyTag( PAGE_NUMBER_TAG, "" );
        writeEndTag( BLOCK_TAG );
        writeEndTag( TABLE_CELL_TAG );
        writeEndTag( TABLE_ROW_TAG );
        writeEndTag( TABLE_BODY_TAG );
        writeEndTag( TABLE_TAG );
        writeEndTag( STATIC_CONTENT_TAG );
    }

    @Override
    protected void regionAfter( String footerText )
    {
        writeStartTag( STATIC_CONTENT_TAG, "flow-name", "xsl-region-after" );
        writeStartTag( BLOCK_TAG, "footer.style" );

        if ( footerText != null )
        {
            write( footerText );
        }

        writeEndTag( BLOCK_TAG );
        writeEndTag( STATIC_CONTENT_TAG );
    }

    @Override
    protected void chapterHeading( String headerText, boolean chapterNumber )
    {
        if ( docName == null )
        {
            getLog().warn( "No document root specified, local links will not be resolved correctly!" );
            writeStartTag( BLOCK_TAG, "" );
        }
        else
        {
            writeStartTag( BLOCK_TAG, "id", docName );
        }

        writeStartTag( LIST_BLOCK_TAG, "" );
        writeStartTag( LIST_ITEM_TAG, "" );
        writeln( "<fo:list-item-label end-indent=\"6.375in\" start-indent=\"-1in\">" );
        writeStartTag( BLOCK_TAG, "outdented.number.style" );

        if ( chapterNumber )
        {
            writeStartTag( BLOCK_TAG, "chapter.title" );
            write( Integer.toString( chapter ) );
            writeEndTag( BLOCK_TAG );
        }

        writeEndTag( BLOCK_TAG );
        writeEndTag( LIST_ITEM_LABEL_TAG );
        writeln( "<fo:list-item-body end-indent=\"1in\" start-indent=\"0in\">" );
        writeStartTag( BLOCK_TAG, "chapter.title" );

        if ( headerText == null )
        {
            text( docTitle );
        }
        else
        {
            text( headerText );
        }

        writeEndTag( BLOCK_TAG );
        writeEndTag( LIST_ITEM_BODY_TAG );
        writeEndTag( LIST_ITEM_TAG );
        writeEndTag( LIST_BLOCK_TAG );
        writeEndTag( BLOCK_TAG );
        writeStartTag( BLOCK_TAG, "space-after.optimum", "0em" );
        writeEmptyTag( LEADER_TAG, "chapter.rule" );
        writeEndTag( BLOCK_TAG );
    }

    /**
     * Writes a table of contents. The DocumentModel has to contain a DocumentTOC for this to work.
     */
    public void toc()
    {
        if ( docModel == null || docModel.getToc() == null || docModel.getToc().getItems() == null
            || this.tocPosition == TOC_NONE )
        {
            return;
        }

        DocumentTOC toc = docModel.getToc();

        writeln( "<fo:page-sequence master-reference=\"toc\" initial-page-number=\"1\" format=\"i\">" );
        regionBefore( toc.getName() );
        regionAfter( getFooterText() );
        writeStartTag( FLOW_TAG, "flow-name", "xsl-region-body" );
        writeStartTag( BLOCK_TAG, "id", "./toc" );
        chapterHeading( toc.getName(), false );
        writeln( "<fo:table table-layout=\"fixed\" width=\"100%\" >" );
        writeEmptyTag( TABLE_COLUMN_TAG, "column-width", "0.45in" );
        writeEmptyTag( TABLE_COLUMN_TAG, "column-width", "0.4in" );
        writeEmptyTag( TABLE_COLUMN_TAG, "column-width", "0.4in" );
        writeEmptyTag( TABLE_COLUMN_TAG, "column-width", "5in" ); // TODO {$maxBodyWidth - 1.25}in
        writeStartTag( TABLE_BODY_TAG );

        writeTocItems( toc.getItems(), 1 );

        writeEndTag( TABLE_BODY_TAG );
        writeEndTag( TABLE_TAG );
        writeEndTag( BLOCK_TAG );
        writeEndTag( FLOW_TAG );
        writeEndTag( PAGE_SEQUENCE_TAG );
    }

    private void writeTocItems( List<DocumentTOCItem> tocItems, int level )
    {
        final int maxTocLevel = 4;

        if ( level < 1 || level > maxTocLevel )
        {
            return;
        }

        tocStack.push( new NumberedListItem( NUMBERING_DECIMAL ) );

        boolean printToc = ( level == 1 );

        for ( DocumentTOCItem tocItem : tocItems )
        {
            String ref = getIdName( tocItem.getRef() );

            writeStartTag( TABLE_ROW_TAG, "keep-with-next", "auto" );

            if ( level > 2 )
            {
                for ( int i = 0; i < level - 2; i++ )
                {
                    writeStartTag( TABLE_CELL_TAG );
                    writeSimpleTag( BLOCK_TAG );
                    writeEndTag( TABLE_CELL_TAG );
                }
            }

            writeStartTag( TABLE_CELL_TAG, "toc.cell" );
            writeStartTag( BLOCK_TAG, "toc.number.style" );

            NumberedListItem current = tocStack.peek();
            if ( printToc )
            {
                // MPDF-59: no entry numbering for first, since it's the "Table of Contents"
                printToc = false;
            }
            else
            {
                current.next();
                write( currentTocNumber() );
            }

            writeEndTag( BLOCK_TAG );
            writeEndTag( TABLE_CELL_TAG );

            String span = "3";

            if ( level > 2 )
            {
                span = Integer.toString( 5 - level );
            }

            writeStartTag( TABLE_CELL_TAG, "number-columns-spanned", span, "toc.cell" );
            MutableAttributeSet atts = getFoConfiguration().getAttributeSet( "toc.h" + level + ".style" );
            atts.addAttribute( "text-align-last", "justify" );
            writeStartTag( BLOCK_TAG, atts );
            writeStartTag( BASIC_LINK_TAG, "internal-destination", ref );
            text( tocItem.getName() );
            writeEndTag( BASIC_LINK_TAG );
            writeEmptyTag( LEADER_TAG, "toc.leader.style" );
            writeStartTag( INLINE_TAG, "page.number" );
            writeEmptyTag( PAGE_NUMBER_CITATION_TAG, "ref-id", ref );
            writeEndTag( INLINE_TAG );
            writeEndTag( BLOCK_TAG );
            writeEndTag( TABLE_CELL_TAG );
            writeEndTag( TABLE_ROW_TAG );

            if ( tocItem.getItems() != null )
            {
                writeTocItems( tocItem.getItems(), level + 1 );
            }
        }

        tocStack.pop();
    }

    private String currentTocNumber()
    {
        StringBuilder ch = new StringBuilder( tocStack.get( 0 ).getListItemSymbol() );

        for ( int i = 1; i < tocStack.size(); i++ )
        {
            ch.append( tocStack.get( i ).getListItemSymbol() );
        }

        return ch.toString();
    }

    /**
     * Writes a fo:bookmark-tree. The DocumentModel has to contain a DocumentTOC for this to work.
     */
    protected void pdfBookmarks()
    {
        if ( docModel == null || docModel.getToc() == null )
        {
            return;
        }

        writeStartTag( BOOKMARK_TREE_TAG );

        renderBookmarkItems( docModel.getToc().getItems() );

        writeEndTag( BOOKMARK_TREE_TAG );
    }

    private void renderBookmarkItems( List<DocumentTOCItem> items )
    {
        for ( DocumentTOCItem tocItem : items )
        {
            String ref = getIdName( tocItem.getRef() );

            writeStartTag( BOOKMARK_TAG, "internal-destination", ref );
            writeStartTag( BOOKMARK_TITLE_TAG );
            text( tocItem.getName() );
            writeEndTag( BOOKMARK_TITLE_TAG );

            if ( tocItem.getItems() != null )
            {
                renderBookmarkItems( tocItem.getItems() );
            }

            writeEndTag( BOOKMARK_TAG );
        }
    }

    /**
     * Writes a cover page. The DocumentModel has to contain a DocumentMeta for this to work.
     */
    public void coverPage()
    {
        if ( this.docModel == null )
        {
            return;
        }

        DocumentCover cover = docModel.getCover();
        DocumentMeta meta = docModel.getMeta();

        if ( cover == null && meta == null )
        {
            return; // no information for cover page: ignore
        }

        // TODO: remove hard-coded settings

        writeStartTag( PAGE_SEQUENCE_TAG, "master-reference", "cover-page" );
        writeStartTag( FLOW_TAG, "flow-name", "xsl-region-body" );
        writeStartTag( BLOCK_TAG, "text-align", "center" );
        writeln( "<fo:table table-layout=\"fixed\" width=\"100%\" >" );
        writeEmptyTag( TABLE_COLUMN_TAG, "column-width", "3.125in" );
        writeEmptyTag( TABLE_COLUMN_TAG, "column-width", "3.125in" );
        writeStartTag( TABLE_BODY_TAG );

        writeCoverHead( cover );
        writeCoverBody( cover, meta );
        writeCoverFooter( cover, meta );

        writeEndTag( TABLE_BODY_TAG );
        writeEndTag( TABLE_TAG );
        writeEndTag( BLOCK_TAG );
        writeEndTag( FLOW_TAG );
        writeEndTag( PAGE_SEQUENCE_TAG );
    }

    private void writeCoverHead( DocumentCover cover )
    {
        if ( cover == null )
        {
            return;
        }

        String compLogo = cover.getCompanyLogo();
        String projLogo = cover.getProjectLogo();

        writeStartTag( TABLE_ROW_TAG, "height", COVER_HEADER_HEIGHT );
        writeStartTag( TABLE_CELL_TAG );

        if ( StringUtils.isNotEmpty( compLogo ) )
        {
            SinkEventAttributeSet atts = new SinkEventAttributeSet();
            atts.addAttribute( "text-align", "left" );
            atts.addAttribute( "vertical-align", "top" );
            writeStartTag( BLOCK_TAG, atts );
            figureGraphics( compLogo, getGraphicsAttributes( compLogo ) );
            writeEndTag( BLOCK_TAG );
        }

        writeSimpleTag( BLOCK_TAG );
        writeEndTag( TABLE_CELL_TAG );
        writeStartTag( TABLE_CELL_TAG );

        if ( StringUtils.isNotEmpty( projLogo ) )
        {
            SinkEventAttributeSet atts = new SinkEventAttributeSet();
            atts.addAttribute( "text-align", "right" );
            atts.addAttribute( "vertical-align", "top" );
            writeStartTag( BLOCK_TAG, atts );
            figureGraphics( projLogo, getGraphicsAttributes( projLogo ) );
            writeEndTag( BLOCK_TAG );
        }

        writeSimpleTag( BLOCK_TAG );
        writeEndTag( TABLE_CELL_TAG );
        writeEndTag( TABLE_ROW_TAG );
    }

    private void writeCoverBody( DocumentCover cover, DocumentMeta meta )
    {
        if ( cover == null && meta == null )
        {
            return;
        }

        String subtitle = null;
        String title;
        String type = null;
        String version = null;
        if ( cover == null )
        {
            // aleady checked that meta != null
            getLog().debug( "The DocumentCover is not defined, using the DocumentMeta title as cover title." );
            title = meta.getTitle();
        }
        else
        {
            subtitle = cover.getCoverSubTitle();
            title = cover.getCoverTitle();
            type = cover.getCoverType();
            version = cover.getCoverVersion();
        }

        writeln( "<fo:table-row keep-with-previous=\"always\" height=\"0.014in\">" );
        writeStartTag( TABLE_CELL_TAG, "number-columns-spanned", "2" );
        writeStartTag( BLOCK_TAG, "line-height", "0.014in" );
        writeEmptyTag( LEADER_TAG, "chapter.rule" );
        writeEndTag( BLOCK_TAG );
        writeEndTag( TABLE_CELL_TAG );
        writeEndTag( TABLE_ROW_TAG );

        writeStartTag( TABLE_ROW_TAG, "height", "7.447in" );
        writeStartTag( TABLE_CELL_TAG, "number-columns-spanned", "2" );
        writeln( "<fo:table table-layout=\"fixed\" width=\"100%\" >" );
        writeEmptyTag( TABLE_COLUMN_TAG, "column-width", "2.083in" );
        writeEmptyTag( TABLE_COLUMN_TAG, "column-width", "2.083in" );
        writeEmptyTag( TABLE_COLUMN_TAG, "column-width", "2.083in" );

        writeStartTag( TABLE_BODY_TAG );

        writeStartTag( TABLE_ROW_TAG );
        writeStartTag( TABLE_CELL_TAG, "number-columns-spanned", "3" );
        writeSimpleTag( BLOCK_TAG );
        writeEmptyTag( BLOCK_TAG, "space-before", "3.2235in" );
        writeEndTag( TABLE_CELL_TAG );
        writeEndTag( TABLE_ROW_TAG );

        writeStartTag( TABLE_ROW_TAG );
        writeStartTag( TABLE_CELL_TAG );
        writeEmptyTag( BLOCK_TAG, "space-after", "0.5in" );
        writeEndTag( TABLE_CELL_TAG );

        writeStartTag( TABLE_CELL_TAG, "number-columns-spanned", "2", "cover.border.left" );
        writeStartTag( BLOCK_TAG, "cover.title" );
        text( title == null ? "" : title );
        writeEndTag( BLOCK_TAG );
        writeEndTag( TABLE_CELL_TAG );
        writeEndTag( TABLE_ROW_TAG );

        writeStartTag( TABLE_ROW_TAG );
        writeStartTag( TABLE_CELL_TAG );
        writeSimpleTag( BLOCK_TAG );
        writeEndTag( TABLE_CELL_TAG );

        writeStartTag( TABLE_CELL_TAG, "number-columns-spanned", "2", "cover.border.left.bottom" );
        writeStartTag( BLOCK_TAG, "cover.subtitle" );
        text( subtitle == null ? ( version == null ? "" : " v. " + version ) : subtitle );
        writeEndTag( BLOCK_TAG );
        writeStartTag( BLOCK_TAG, "cover.subtitle" );
        text( type == null ? "" : type );
        writeEndTag( BLOCK_TAG );
        writeEndTag( TABLE_CELL_TAG );
        writeEndTag( TABLE_ROW_TAG );

        writeEndTag( TABLE_BODY_TAG );
        writeEndTag( TABLE_TAG );

        writeEndTag( TABLE_CELL_TAG );
        writeEndTag( TABLE_ROW_TAG );

        writeStartTag( TABLE_ROW_TAG, "height", "0.014in" );
        writeStartTag( TABLE_CELL_TAG, "number-columns-spanned", "2" );
        writeln( "<fo:block space-after=\"0.2in\" line-height=\"0.014in\">" );
        writeEmptyTag( LEADER_TAG, "chapter.rule" );
        writeEndTag( BLOCK_TAG );
        writeEndTag( TABLE_CELL_TAG );
        writeEndTag( TABLE_ROW_TAG );

        writeStartTag( TABLE_ROW_TAG );
        writeStartTag( TABLE_CELL_TAG, "number-columns-spanned", "2" );
        writeSimpleTag( BLOCK_TAG );
        writeEmptyTag( BLOCK_TAG, "space-before", "0.2in" );
        writeEndTag( TABLE_CELL_TAG );
        writeEndTag( TABLE_ROW_TAG );
    }

    private void writeCoverFooter( DocumentCover cover, DocumentMeta meta )
    {
        if ( cover == null && meta == null )
        {
            return;
        }

        String date = null;
        String compName;
        if ( cover == null )
        {
            // aleady checked that meta != null
            getLog().debug( "The DocumentCover is not defined, using the DocumentMeta author as company name." );
            compName = meta.getAuthor();
        }
        else
        {
            compName = cover.getCompanyName();

            if ( cover.getCoverdate() == null )
            {
                cover.setCoverDate( new Date() );
                date = cover.getCoverdate();
                cover.setCoverDate( null );
            }
            else
            {
                date = cover.getCoverdate();
            }
        }

        writeStartTag( TABLE_ROW_TAG, "height", "0.3in" );

        writeStartTag( TABLE_CELL_TAG );
        MutableAttributeSet att = getFoConfiguration().getAttributeSet( "cover.subtitle" );
        att.addAttribute( "height", "0.3in" );
        att.addAttribute( "text-align", "left" );
        writeStartTag( BLOCK_TAG, att );
        text( compName == null ? ( cover.getAuthor() == null ? "" : cover.getAuthor() ) : compName );
        writeEndTag( BLOCK_TAG );
        writeEndTag( TABLE_CELL_TAG );

        writeStartTag( TABLE_CELL_TAG );
        att = getFoConfiguration().getAttributeSet( "cover.subtitle" );
        att.addAttribute( "height", "0.3in" );
        att.addAttribute( "text-align", "right" );
        writeStartTag( BLOCK_TAG, att );
        text( date == null ? "" : date );
        writeEndTag( BLOCK_TAG );
        writeEndTag( TABLE_CELL_TAG );

        writeEndTag( TABLE_ROW_TAG );
    }

    private ResourceBundle getBundle( Locale locale )
    {
        return ResourceBundle.getBundle( "doxia-fo", locale, this.getClass().getClassLoader() );
    }

    private SinkEventAttributeSet getGraphicsAttributes( String logo )
    {
        MutableAttributeSet atts = null;

        try
        {
            atts = DoxiaUtils.getImageAttributes( logo );
        }
        catch ( IOException e )
        {
            getLog().debug( e );
        }

        if ( atts == null )
        {
            return new SinkEventAttributeSet( SinkEventAttributes.HEIGHT, COVER_HEADER_HEIGHT );
        }

        // FOP dpi: 72
        // Max width : 3.125 inch, table cell size, see #coverPage()
        final int maxWidth = 225; // 3.125 * 72

        if ( Integer.parseInt( atts.getAttribute( SinkEventAttributes.WIDTH ).toString() ) > maxWidth )
        {
            atts.addAttribute( "content-width", "3.125in" );
        }

        return new SinkEventAttributeSet( atts );
    }
}
