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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.area.AreaTreeHandler;
import org.apache.fop.fo.FOElementMapping;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FONode.FONodeIterator;
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.FObjMixed;
import org.apache.fop.fo.extensions.ExternalDocument;
import org.apache.fop.fo.flow.BasicLink;
import org.apache.fop.fo.flow.BidiOverride;
import org.apache.fop.fo.flow.Block;
import org.apache.fop.fo.flow.BlockContainer;
import org.apache.fop.fo.flow.ChangeBarBegin;
import org.apache.fop.fo.flow.ChangeBarEnd;
import org.apache.fop.fo.flow.Character;
import org.apache.fop.fo.flow.ExternalGraphic;
import org.apache.fop.fo.flow.Float;
import org.apache.fop.fo.flow.Footnote;
import org.apache.fop.fo.flow.Inline;
import org.apache.fop.fo.flow.InlineContainer;
import org.apache.fop.fo.flow.InlineLevel;
import org.apache.fop.fo.flow.InstreamForeignObject;
import org.apache.fop.fo.flow.Leader;
import org.apache.fop.fo.flow.ListBlock;
import org.apache.fop.fo.flow.ListItem;
import org.apache.fop.fo.flow.MultiCase;
import org.apache.fop.fo.flow.MultiSwitch;
import org.apache.fop.fo.flow.PageNumber;
import org.apache.fop.fo.flow.PageNumberCitation;
import org.apache.fop.fo.flow.PageNumberCitationLast;
import org.apache.fop.fo.flow.RetrieveMarker;
import org.apache.fop.fo.flow.RetrieveTableMarker;
import org.apache.fop.fo.flow.Wrapper;
import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TableBody;
import org.apache.fop.fo.flow.table.TableCell;
import org.apache.fop.fo.flow.table.TableColumn;
import org.apache.fop.fo.flow.table.TableFooter;
import org.apache.fop.fo.flow.table.TableHeader;
import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.SideRegion;
import org.apache.fop.fo.pagination.StaticContent;
import org.apache.fop.fo.pagination.Title;
import org.apache.fop.layoutmgr.inline.BasicLinkLayoutManager;
import org.apache.fop.layoutmgr.inline.BidiLayoutManager;
import org.apache.fop.layoutmgr.inline.CharacterLayoutManager;
import org.apache.fop.layoutmgr.inline.ContentLayoutManager;
import org.apache.fop.layoutmgr.inline.ExternalGraphicLayoutManager;
import org.apache.fop.layoutmgr.inline.FloatLayoutManager;
import org.apache.fop.layoutmgr.inline.FootnoteLayoutManager;
import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager;
import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
import org.apache.fop.layoutmgr.inline.InstreamForeignObjectLM;
import org.apache.fop.layoutmgr.inline.LeaderLayoutManager;
import org.apache.fop.layoutmgr.inline.PageNumberCitationLastLayoutManager;
import org.apache.fop.layoutmgr.inline.PageNumberCitationLayoutManager;
import org.apache.fop.layoutmgr.inline.PageNumberLayoutManager;
import org.apache.fop.layoutmgr.inline.TextLayoutManager;
import org.apache.fop.layoutmgr.inline.WrapperLayoutManager;
import org.apache.fop.layoutmgr.list.ListBlockLayoutManager;
import org.apache.fop.layoutmgr.list.ListItemLayoutManager;
import org.apache.fop.layoutmgr.table.TableLayoutManager;
import org.apache.fop.util.CharUtilities;

/**
 * The default LayoutManager maker class
 */
public class LayoutManagerMapping implements LayoutManagerMaker {

    /** logging instance */
    private static final Log LOG = LogFactory.getLog(LayoutManagerMapping.class);

    /** The map of LayoutManagerMakers */
    private final Map makers = new HashMap();

    private FOUserAgent userAgent;

    /** default constructor */
    public LayoutManagerMapping(FOUserAgent userAgent) {
        this.userAgent = userAgent;
        initialize();
    }

    /**
     * Initializes the set of maker objects associated with this LayoutManagerMapping
     */
    protected void initialize() {
        registerMaker(FOText.class, new FOTextLayoutManagerMaker());
        registerMaker(FObjMixed.class, new Maker());
        registerMaker(BidiOverride.class, new BidiOverrideLayoutManagerMaker());
        registerMaker(Inline.class, new InlineLayoutManagerMaker());
        registerMaker(Footnote.class, new FootnoteLayoutManagerMaker());
        registerMaker(InlineContainer.class,
                   new InlineContainerLayoutManagerMaker());
        registerMaker(BasicLink.class, new BasicLinkLayoutManagerMaker());
        registerMaker(Block.class, new BlockLayoutManagerMaker());
        registerMaker(Leader.class, new LeaderLayoutManagerMaker());
        registerMaker(RetrieveMarker.class, new RetrieveMarkerLayoutManagerMaker());
        registerMaker(RetrieveTableMarker.class, new RetrieveTableMarkerLayoutManagerMaker());
        registerMaker(Character.class, new CharacterLayoutManagerMaker());
        registerMaker(ExternalGraphic.class,
                   new ExternalGraphicLayoutManagerMaker());
        registerMaker(BlockContainer.class,
                   new BlockContainerLayoutManagerMaker());
        registerMaker(ListItem.class, new ListItemLayoutManagerMaker());
        registerMaker(ListBlock.class, new ListBlockLayoutManagerMaker());
        registerMaker(InstreamForeignObject.class,
                   new InstreamForeignObjectLayoutManagerMaker());
        registerMaker(PageNumber.class, new PageNumberLayoutManagerMaker());
        registerMaker(PageNumberCitation.class,
                   new PageNumberCitationLayoutManagerMaker());
        registerMaker(PageNumberCitationLast.class,
                new PageNumberCitationLastLayoutManagerMaker());
        registerMaker(Table.class, new TableLayoutManagerMaker());
        registerMaker(TableBody.class, new Maker());
        registerMaker(TableColumn.class, new Maker());
        registerMaker(TableRow.class, new Maker());
        registerMaker(TableCell.class, new Maker());
        registerMaker(TableFooter.class, new Maker());
        registerMaker(TableHeader.class, new Maker());
        registerMaker(Wrapper.class, new WrapperLayoutManagerMaker());
        registerMaker(Title.class, new InlineLayoutManagerMaker());
        registerMaker(ChangeBarBegin.class, new Maker());
        registerMaker(ChangeBarEnd.class, new Maker());
        registerMaker(MultiCase.class, new MultiCaseLayoutManagerMaker());
        registerMaker(MultiSwitch.class, new MultiSwitchLayoutManagerMaker());
        registerMaker(Float.class, new FloatLayoutManagerMaker());
    }

    /**
     * Registers a Maker class for a specific formatting object.
     * @param clazz the formatting object class
     * @param maker the maker for the layout manager
     */
    protected void registerMaker(Class clazz, Maker maker) {
        makers.put(clazz, maker);
    }

    /** {@inheritDoc} */
    public void makeLayoutManagers(FONode node, List lms) {
        Maker maker = (Maker) makers.get(node.getClass());
        if (maker == null) {
            if (FOElementMapping.URI.equals(node.getNamespaceURI())) {
                LOG.error("No LayoutManager maker for class " + node.getClass());
            } else {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Skipping the creation of a layout manager for " + node.getClass());
                }
            }
        } else {
            maker.make(node, lms, userAgent);
        }
    }

    /** {@inheritDoc} */
    public LayoutManager makeLayoutManager(FONode node) {
        List lms = new ArrayList();
        makeLayoutManagers(node, lms);
        if (lms.size() == 0) {
            throw new IllegalStateException("LayoutManager for class "
                                   + node.getClass()
                                   + " is missing.");
        } else if (lms.size() > 1) {
            throw new IllegalStateException("Duplicate LayoutManagers for class "
                                   + node.getClass()
                                   + " found, only one may be declared.");
        }
        return (LayoutManager) lms.get(0);
    }

    /** {@inheritDoc} */
    public PageSequenceLayoutManager makePageSequenceLayoutManager(
        AreaTreeHandler ath, PageSequence ps) {
        return new PageSequenceLayoutManager(ath, ps);
    }

    /** {@inheritDoc} */
    public ExternalDocumentLayoutManager makeExternalDocumentLayoutManager(
        AreaTreeHandler ath, ExternalDocument ed) {
        return new ExternalDocumentLayoutManager(ath, ed);
    }

    /** {@inheritDoc} */
    public FlowLayoutManager makeFlowLayoutManager(
            PageSequenceLayoutManager pslm, Flow flow) {
        return new FlowLayoutManager(pslm, flow);
    }

    /** {@inheritDoc} */
    public ContentLayoutManager makeContentLayoutManager(PageSequenceLayoutManager pslm,
                                                         Title title) {
        return new ContentLayoutManager(pslm, title);
    }

    /** {@inheritDoc} */
    public StaticContentLayoutManager makeStaticContentLayoutManager(
            PageSequenceLayoutManager pslm, StaticContent sc, SideRegion reg) {
        return new StaticContentLayoutManager(pslm, sc, reg);
    }

    /** {@inheritDoc} */
    public StaticContentLayoutManager makeStaticContentLayoutManager(
        PageSequenceLayoutManager pslm, StaticContent sc, org.apache.fop.area.Block block) {
        return new StaticContentLayoutManager(pslm, sc, block);
    }

    /** a layout manager maker base class */
    public static class Maker {
        /**
         * Create a layout manager.
         * @param node the associated FO node
         * @param lms a list of layout managers to which new manager is to be added
         */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            // no layout manager
        }
    }

    /** a layout manager maker */
    public static class FOTextLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            FOText foText = (FOText) node;
            if (foText.length() > 0) {
                lms.add(new TextLayoutManager(foText, userAgent));
            }
        }
    }

    /** a layout manager maker */
    public static class BidiOverrideLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            if (node instanceof BidiOverride) {
                lms.add(new BidiLayoutManager((BidiOverride) node));
            }
        }
    }

    /** a layout manager maker */
    public static class InlineLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            lms.add(new InlineLayoutManager((InlineLevel) node));
        }
    }

    /** a layout manager maker */
    public static class FootnoteLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            lms.add(new FootnoteLayoutManager((Footnote) node));
        }
    }

    /** a layout manager maker */
    public static class InlineContainerLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            lms.add(new InlineContainerLayoutManager((InlineContainer) node));
        }
    }

    /** a layout manager maker */
    public static class BasicLinkLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            lms.add(new BasicLinkLayoutManager((BasicLink) node));
        }
    }

    /** a layout manager maker */
    public static class BlockLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
         public void make(FONode node, List lms, FOUserAgent userAgent) {
             lms.add(new BlockLayoutManager((Block) node));
         }
    }

    /** a layout manager maker */
    public static class LeaderLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            lms.add(new LeaderLayoutManager((Leader) node));
        }
    }

    /** a layout manager maker */
    public static class CharacterLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            Character foCharacter = (Character) node;
            if (foCharacter.getCharacter() != CharUtilities.CODE_EOT) {
                lms.add(new CharacterLayoutManager(foCharacter));
            }
        }
    }

    /** a layout manager maker */
    public static class ExternalGraphicLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            ExternalGraphic eg = (ExternalGraphic) node;
            if (!eg.getSrc().equals("")) {
                lms.add(new ExternalGraphicLayoutManager(eg));
            }
        }
    }

    /** a layout manager maker */
    public static class BlockContainerLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            lms.add(new BlockContainerLayoutManager((BlockContainer) node));
         }
    }

    /** a layout manager maker */
    public static class ListItemLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
         public void make(FONode node, List lms, FOUserAgent userAgent) {
             lms.add(new ListItemLayoutManager((ListItem) node));
         }
    }

    /** a layout manager maker */
    public static class ListBlockLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            lms.add(new ListBlockLayoutManager((ListBlock) node));
        }
    }

    /** a layout manager maker */
    public static class InstreamForeignObjectLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            lms.add(new InstreamForeignObjectLM((InstreamForeignObject) node));
        }
    }

    /** a layout manager maker */
    public static class PageNumberLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
         public void make(FONode node, List lms, FOUserAgent userAgent) {
             lms.add(new PageNumberLayoutManager((PageNumber) node));
         }
    }

    /** a layout manager maker */
    public static class PageNumberCitationLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
         public void make(FONode node, List lms, FOUserAgent userAgent) {
            lms.add(new PageNumberCitationLayoutManager((PageNumberCitation) node));
         }
    }

    /** a layout manager maker */
    public static class PageNumberCitationLastLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
           lms.add(new PageNumberCitationLastLayoutManager((PageNumberCitationLast) node));
        }
    }

    /** a layout manager maker */
    public static class TableLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            Table table = (Table) node;
            TableLayoutManager tlm = new TableLayoutManager(table);
            lms.add(tlm);
        }
    }

    /** a layout manager maker */
    public class RetrieveMarkerLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            Iterator baseIter;
            baseIter = node.getChildNodes();
            if (baseIter == null) {
                return;
            }
            while (baseIter.hasNext()) {
                FONode child = (FONode) baseIter.next();
                makeLayoutManagers(child, lms);
            }
        }
    }

    public class RetrieveTableMarkerLayoutManagerMaker extends Maker {
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            FONodeIterator baseIter = node.getChildNodes();
            if (baseIter == null) {
                // this happens when the retrieve-table-marker cannot be resolved yet
                RetrieveTableMarker rtm = (RetrieveTableMarker) node;
                RetrieveTableMarkerLayoutManager rtmlm = new RetrieveTableMarkerLayoutManager(rtm);
                lms.add(rtmlm);
                return;
            }
            while (baseIter.hasNext()) {
                // this happens when the retrieve-table-marker has been resolved
                FONode child = baseIter.next();
                makeLayoutManagers(child, lms);
            }
        }
    }

    /** a layout manager maker */
    public class WrapperLayoutManagerMaker extends Maker {
        /** {@inheritDoc} */
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            //We insert the wrapper LM before it's children so an ID
            //on the node can be registered on a page.
            lms.add(new WrapperLayoutManager((Wrapper)node));
            Iterator baseIter;
            baseIter = node.getChildNodes();
            if (baseIter == null) {
                return;
            }
            while (baseIter.hasNext()) {
                FONode child = (FONode) baseIter.next();
                makeLayoutManagers(child, lms);
            }
        }
    }

    public class MultiSwitchLayoutManagerMaker extends Maker {

        @Override
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            lms.add(new MultiSwitchLayoutManager((MultiSwitch) node));
        }
    }

    public class MultiCaseLayoutManagerMaker extends Maker {

        @Override
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            lms.add(new MultiCaseLayoutManager((MultiCase) node));
        }
    }

    public static class FloatLayoutManagerMaker extends Maker {
        public void make(FONode node, List lms, FOUserAgent userAgent) {
            lms.add(new FloatLayoutManager((Float) node));
        }
    }

}
