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

package org.apache.fop.render.pdf;

import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import org.junit.Test;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;

import org.apache.fop.pdf.PDFArray;
import org.apache.fop.pdf.PDFDictionary;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFName;
import org.apache.fop.pdf.PDFNumber;
import org.apache.fop.pdf.PDFObject;
import org.apache.fop.pdf.PDFPage;
import org.apache.fop.pdf.PDFResources;
import org.apache.fop.pdf.PDFStructElem;
import org.apache.fop.render.pdf.pdfbox.PDFBoxAdapter;
import org.apache.fop.render.pdf.pdfbox.TaggedPDFConductor;

import junit.framework.Assert;

public class TaggedPDFConductorTestCase {
    private static final String LINK = "test/resources/linkTagged.pdf";
    private static final String HELLO = "test/resources/helloWorld.pdf";
    private static final String TABLE = "test/resources/emptyRowTable.pdf";
    private static final String OTF = "test/resources/otf.pdf";
    private PDFPage pdfPage;
    private PDFDocument pdfDoc;

    @Test
    public void testHandleLogicalStructure() throws IOException {
        PDFStructElem elem = new PDFStructElem();
        runConductor(LINK, elem);
        checkStructure(elem, 0);

        elem = new PDFStructElem();
        runConductor(HELLO, elem);
        PDFNumber mcid = (PDFNumber)elem.getKids().get(0);
        int test = mcid.getNumber().intValue();
        Assert.assertEquals(test, 0);

        elem = new PDFStructElem();
        runConductor(TABLE, elem);
        Assert.assertEquals(print(elem), "/Div/Part/Sect/Table/TBody/TR/TD/P/TD/P/TR/TD/TD");

        elem = new PDFStructElem();
        elem.put("Alt", "alt-text");
        runConductor(OTF, elem);
        Assert.assertEquals(print(elem), "/Div/Part/Art/P/Span");
        Assert.assertNull(elem.get("Alt"));
    }

    private String print(PDFStructElem x) throws IOException {
        StringBuilder sb = new StringBuilder(x.get("S").toString());
        for (PDFObject k : x.getKids()) {
            if (k instanceof PDFStructElem) {
                sb.append(print((PDFStructElem) k));
            }
        }
        return sb.toString();
    }

    private void runConductor(String pdf, PDFStructElem elem) throws IOException {
        setUp();
        PDDocument doc = PDDocument.load(pdf);
        PDPage srcPage = doc.getPage(0);
        elem.setObjectNumber(2);
        PDFBoxAdapter adapter = new PDFBoxAdapter(
                pdfPage, new HashMap(),  new HashMap<Integer, PDFArray>());
        PDFLogicalStructureHandler handler = setUpPDFLogicalStructureHandler();
        new TaggedPDFConductor(elem, handler, srcPage, adapter).handleLogicalStructure(doc);
    }

    private void setUp() {
        Rectangle2D r = new Rectangle2D.Double();
        pdfPage = new PDFPage(new PDFResources(pdfDoc), 0, r, r, r, r);
        pdfDoc = new PDFDocument(" ");
        pdfDoc.makeStructTreeRoot(null);
        pdfPage.setObjectNumber(1);
        pdfPage.setDocument(pdfDoc);
    }

    private PDFLogicalStructureHandler setUpPDFLogicalStructureHandler() {
        PDFLogicalStructureHandler handler = new PDFLogicalStructureHandler(pdfDoc);
        handler.getParentTree().setDocument(pdfDoc);
        handler.startPage(pdfPage);
        return handler;
    }

    private void checkStructure(PDFStructElem elem, int index) {
        String [] types = {"Part", "Sect", "P"};
        List<PDFObject> list = elem.getKids();
        if (index != 3) {
            PDFStructElem kid = (PDFStructElem)list.get(0);
            String test = ((PDFName)kid.get("S")).getName();
            String expected = types[index];
            Assert.assertEquals(test, expected);
            index++;
            checkStructure(kid, index);
        } else {
            PDFDictionary firstKid = (PDFDictionary) list.get(0);
            int test = ((PDFNumber)firstKid.get("MCID")).getNumber().intValue();
            int expected = 0;
            Assert.assertEquals(test, expected);
            PDFDictionary firstKidSibling = (PDFDictionary) list.get(2);
            test = ((PDFNumber)firstKidSibling.get("MCID")).getNumber().intValue();
            expected = 2;
            Assert.assertEquals(test, expected);
            PDFStructElem second = (PDFStructElem)list.get(1);
            List secondKids = second.getKids();
            PDFStructElem secKid = (PDFStructElem) secondKids.get(0);
            List secondKidKids = secKid.getKids();
            PDFDictionary leafElem = (PDFDictionary)secondKidKids.get(0);
            test = ((PDFNumber)leafElem.get("MCID")).getNumber().intValue();
            expected = 1;
            Assert.assertEquals(test, expected);
        }
    }
}
