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

import java.util.Locale;
import java.util.Stack;

import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import org.apache.fop.accessibility.StructureTreeElement;
import org.apache.fop.accessibility.StructureTreeEventHandler;
import org.apache.fop.fo.FOEventHandler;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
import org.apache.fop.fo.extensions.InternalElementMapping;
import org.apache.fop.fo.flow.AbstractGraphics;
import org.apache.fop.fo.flow.BasicLink;
import org.apache.fop.fo.flow.Block;
import org.apache.fop.fo.flow.BlockContainer;
import org.apache.fop.fo.flow.Character;
import org.apache.fop.fo.flow.ExternalGraphic;
import org.apache.fop.fo.flow.Footnote;
import org.apache.fop.fo.flow.FootnoteBody;
import org.apache.fop.fo.flow.Inline;
import org.apache.fop.fo.flow.InstreamForeignObject;
import org.apache.fop.fo.flow.ListBlock;
import org.apache.fop.fo.flow.ListItem;
import org.apache.fop.fo.flow.ListItemBody;
import org.apache.fop.fo.flow.ListItemLabel;
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.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.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.LayoutMasterSet;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.StaticContent;
import org.apache.fop.fo.properties.CommonAccessibilityHolder;
import org.apache.fop.util.XMLUtil;

/**
 * A bridge between {@link FOEventHandler} and {@link StructureTreeEventHandler}.
 */
class StructureTreeEventTrigger extends FOEventHandler {

    private StructureTreeEventHandler structureTreeEventHandler;

    private LayoutMasterSet layoutMasterSet;

    private final Stack<Table> tables = new Stack<Table>();

    private final Stack<Boolean> inTableHeader = new Stack<Boolean>();

    public StructureTreeEventTrigger(StructureTreeEventHandler structureTreeEventHandler) {
        this.structureTreeEventHandler = structureTreeEventHandler;
    }

    @Override
    public void startDocument() throws SAXException {
    }

    @Override
    public void endDocument() throws SAXException {
    }

    @Override
    public void startPageSequence(PageSequence pageSeq) {
        if (layoutMasterSet == null) {
            layoutMasterSet = pageSeq.getRoot().getLayoutMasterSet();
        }
        Locale locale = null;
        if (pageSeq.getLanguage() != null) {
            if (pageSeq.getCountry() != null) {
                locale = new Locale(pageSeq.getLanguage(), pageSeq.getCountry());
            } else {
                locale = new Locale(pageSeq.getLanguage());
            }
        }
        String role = pageSeq.getCommonAccessibility().getRole();
        structureTreeEventHandler.startPageSequence(locale, role);
    }

    @Override
    public void endPageSequence(PageSequence pageSeq) {
        structureTreeEventHandler.endPageSequence();
    }

    @Override
    public void startPageNumber(PageNumber pagenum) {
        startElementWithID(pagenum);
    }

    @Override
    public void endPageNumber(PageNumber pagenum) {
        endElement(pagenum);
    }

    @Override
    public void startPageNumberCitation(PageNumberCitation pageCite) {
        startElementWithID(pageCite);
    }

    @Override
    public void endPageNumberCitation(PageNumberCitation pageCite) {
        endElement(pageCite);
    }

    @Override
    public void startPageNumberCitationLast(PageNumberCitationLast pageLast) {
        startElementWithID(pageLast);
    }

    @Override
    public void endPageNumberCitationLast(PageNumberCitationLast pageLast) {
        endElement(pageLast);
    }

    @Override
    public void startStatic(StaticContent staticContent) {
        AttributesImpl flowName = createFlowNameAttribute(staticContent.getFlowName());
        startElement(staticContent, flowName);
    }

    private AttributesImpl createFlowNameAttribute(String flowName) {
        String regionName = layoutMasterSet.getDefaultRegionNameFor(flowName);
        AttributesImpl attribute = new AttributesImpl();
        addNoNamespaceAttribute(attribute, Flow.FLOW_NAME, regionName);
        return attribute;
    }

    @Override
    public void endStatic(StaticContent staticContent) {
        endElement(staticContent);
    }

    @Override
    public void startFlow(Flow fl) {
        AttributesImpl flowName = createFlowNameAttribute(fl.getFlowName());
        startElement(fl, flowName);
    }

    @Override
    public void endFlow(Flow fl) {
        endElement(fl);
    }

    @Override
    public void startBlock(Block bl) {
        startElement(bl);
    }

    @Override
    public void endBlock(Block bl) {
        endElement(bl);
    }

    @Override
    public void startBlockContainer(BlockContainer blc) {
        startElement(blc);
    }

    @Override
    public void endBlockContainer(BlockContainer blc) {
        endElement(blc);
    }

    @Override
    public void startInline(Inline inl) {
        startElement(inl);
    }

    @Override
    public void endInline(Inline inl) {
        endElement(inl);
    }

    @Override
    public void startTable(Table tbl) {
        tables.push(tbl);
        startElement(tbl);
    }

    @Override
    public void endTable(Table tbl) {
        endElement(tbl);
        tables.pop();
    }

    @Override
    public void startHeader(TableHeader header) {
        inTableHeader.push(Boolean.TRUE);
        startElement(header);
    }

    @Override
    public void endHeader(TableHeader header) {
        endElement(header);
        inTableHeader.pop();
    }

    @Override
    public void startFooter(TableFooter footer) {
        // TODO Shouldn't it be true?
        inTableHeader.push(Boolean.FALSE);
        startElement(footer);
    }

    @Override
    public void endFooter(TableFooter footer) {
        endElement(footer);
        inTableHeader.pop();
    }

    @Override
    public void startBody(TableBody body) {
        inTableHeader.push(Boolean.FALSE);
        startElement(body);
    }

    @Override
    public void endBody(TableBody body) {
        endElement(body);
        inTableHeader.pop();
    }

    @Override
    public void startRow(TableRow tr) {
        startElement(tr);
    }

    @Override
    public void endRow(TableRow tr) {
        endElement(tr);
    }

    @Override
    public void startCell(TableCell tc) {
        AttributesImpl attributes = new AttributesImpl();
        addSpanAttribute(attributes, "number-columns-spanned", tc.getNumberColumnsSpanned());
        addSpanAttribute(attributes, "number-rows-spanned", tc.getNumberRowsSpanned());
        boolean rowHeader = inTableHeader.peek();
        boolean columnHeader = tables.peek().getColumn(tc.getColumnNumber() - 1).isHeader();
        if (rowHeader || columnHeader) {
            final String th = "TH";
            String role = tc.getCommonAccessibility().getRole();
            /* Do not override a custom role */
            if (role == null) {
                role = th;
                addNoNamespaceAttribute(attributes, "role", th);
            }
            if (role.equals(th)) {
                if (columnHeader) {
                    String scope = rowHeader ? "Both" : "Row";
                    addAttribute(attributes, InternalElementMapping.URI, InternalElementMapping.SCOPE,
                            InternalElementMapping.STANDARD_PREFIX, scope);
                }
            }
        }
        startElement(tc, attributes);
    }

    private void addSpanAttribute(AttributesImpl attributes, String attributeName, int span) {
        if (span > 1) {
            addNoNamespaceAttribute(attributes, attributeName, Integer.toString(span));
        }
    }

    @Override
    public void endCell(TableCell tc) {
        endElement(tc);
    }

    @Override
    public void startList(ListBlock lb) {
        startElement(lb);
    }

    @Override
    public void endList(ListBlock lb) {
        endElement(lb);
    }

    @Override
    public void startListItem(ListItem li) {
        startElement(li);
    }

    @Override
    public void endListItem(ListItem li) {
        endElement(li);
    }

    @Override
    public void startListLabel(ListItemLabel listItemLabel) {
        startElement(listItemLabel);
    }

    @Override
    public void endListLabel(ListItemLabel listItemLabel) {
        endElement(listItemLabel);
    }

    @Override
    public void startListBody(ListItemBody listItemBody) {
        startElement(listItemBody);
    }

    @Override
    public void endListBody(ListItemBody listItemBody) {
        endElement(listItemBody);
    }

    @Override
    public void startLink(BasicLink basicLink) {
        startElementWithID(basicLink);
    }

    @Override
    public void endLink(BasicLink basicLink) {
        endElement(basicLink);
    }

    @Override
    public void image(ExternalGraphic eg) {
        startElementWithIDAndAltText(eg);
        endElement(eg);
    }

    @Override
    public void startInstreamForeignObject(InstreamForeignObject ifo) {
        startElementWithIDAndAltText(ifo);
    }

    @Override
    public void endInstreamForeignObject(InstreamForeignObject ifo) {
        endElement(ifo);
    }

    @Override
    public void startFootnote(Footnote footnote) {
        startElement(footnote);
    }

    @Override
    public void endFootnote(Footnote footnote) {
        endElement(footnote);
    }

    @Override
    public void startFootnoteBody(FootnoteBody body) {
        startElement(body);
    }

    @Override
    public void endFootnoteBody(FootnoteBody body) {
        endElement(body);
    }

    @Override
    public void startWrapper(Wrapper wrapper) {
        startElement(wrapper);
    }

    @Override
    public void endWrapper(Wrapper wrapper) {
        endElement(wrapper);
    }

    @Override
    public void character(Character c) {
        startElementWithID(c);
        endElement(c);
    }

    @Override
    public void characters(FOText foText) {
        startElementWithID(foText);
        endElement(foText);
    }


    private void startElement(FONode node) {
        startElement(node, new AttributesImpl());
    }

    private void startElementWithID(FONode node) {
        AttributesImpl attributes = new AttributesImpl();
        String localName = node.getLocalName();
        if (node instanceof CommonAccessibilityHolder) {
            addRole((CommonAccessibilityHolder) node, attributes);
        }
        node.setStructureTreeElement(
                structureTreeEventHandler.startReferencedNode(localName, attributes));
    }

    private void startElementWithIDAndAltText(AbstractGraphics node) {
        AttributesImpl attributes = new AttributesImpl();
        String localName = node.getLocalName();
        addRole(node, attributes);
        addAttribute(attributes, ExtensionElementMapping.URI, "alt-text",
                ExtensionElementMapping.STANDARD_PREFIX, node.getAltText());
        node.setStructureTreeElement(
                structureTreeEventHandler.startImageNode(localName, attributes));
    }

    private StructureTreeElement startElement(FONode node, AttributesImpl attributes) {
        String localName = node.getLocalName();
        if (node instanceof CommonAccessibilityHolder) {
            addRole((CommonAccessibilityHolder) node, attributes);
        }
        return structureTreeEventHandler.startNode(localName, attributes);
    }

    private void addNoNamespaceAttribute(AttributesImpl attributes, String name, String value) {
        attributes.addAttribute("", name, name, XMLUtil.CDATA, value);
    }

    private void addAttribute(AttributesImpl attributes,
            String namespace, String localName, String prefix, String value) {
        assert namespace.length() > 0 && prefix.length() > 0;
        String qualifiedName = prefix + ":" + localName;
        attributes.addAttribute(namespace, localName, qualifiedName, XMLUtil.CDATA, value);
    }

    private void addRole(CommonAccessibilityHolder node, AttributesImpl attributes) {
        String role = node.getCommonAccessibility().getRole();
        if (role != null) {
            addNoNamespaceAttribute(attributes, "role", role);
        }
    }

    private void endElement(FONode node) {
        String localName = node.getLocalName();
        structureTreeEventHandler.endNode(localName);
    }

}
