/*
 * 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: PDFDocumentGraphics2DTestCase.java 1894166 2021-10-12 14:33:18Z ssteiner $ */

package org.apache.fop.pdf;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;

import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.apache.commons.io.output.ByteArrayOutputStream;

import org.apache.xmlgraphics.java2d.GraphicContext;
import org.apache.xmlgraphics.util.UnitConv;

import org.apache.fop.svg.PDFDocumentGraphics2D;

/**
 * Tests for {@link PDFDocumentGraphics2D}.
 */
public class PDFDocumentGraphics2DTestCase {

    /**
     * Does a smoke test on PDFDocumentGraphics2D making sure that nobody accidentally broke
     * anything serious. It does not check the correctness of the produced PDF.
     * @throws Exception if an error occurs
     */
    @Test
    public void smokeTest() throws Exception {
        ByteArrayOutputStream baout = new ByteArrayOutputStream();
        PDFDocumentGraphics2D g2d = new PDFDocumentGraphics2D(false);
        g2d.setGraphicContext(new GraphicContext());

        //Set up the document size
        Dimension pageSize = new Dimension(
                (int)Math.ceil(UnitConv.mm2pt(210)),
                (int)Math.ceil(UnitConv.mm2pt(297))); //page size A4 (in pt)
        g2d.setupDocument(baout, pageSize.width, pageSize.height);

        //A few rectangles rotated and with different color
        Graphics2D copy = (Graphics2D)g2d.create();
        int c = 12;
        for (int i = 0; i < c; i++) {
            float f = ((i + 1) / (float)c);
            Color col = new Color(0.0f, 1 - f, 0.0f);
            copy.setColor(col);
            copy.fillRect(70, 90, 50, 50);
            copy.rotate(-2 * Math.PI / c, 70, 90);
        }
        copy.dispose();

        //Some text
        g2d.rotate(-0.25);
        g2d.setColor(Color.RED);
        g2d.setFont(new Font("sans-serif", Font.PLAIN, 36));
        g2d.drawString("Hello world!", 140, 140);
        g2d.setColor(Color.RED.darker());
        g2d.setFont(new Font("serif", Font.PLAIN, 36));
        g2d.drawString("Hello world!", 140, 180);

        g2d.nextPage(); //Move to next page

        g2d.setFont(new Font("sans-serif", Font.PLAIN, 36));
        g2d.drawString("Welcome to page 2!", 140, 140);

        //Cleanup
        g2d.finish();

        String pdfString = baout.toString("ISO-8859-1");
        assertEquals("%%EOF not found",
                pdfString.substring(pdfString.length() - 6), "%%EOF\n");
    }

    @Test
    public void checkContentNotRepeatedAcrossPage() throws Exception {
        ByteArrayOutputStream baout = new ByteArrayOutputStream();
        PDFDocumentGraphics2D gPDF = new PDFDocumentGraphics2D(false);
        Dimension pageSize = new Dimension(
                (int) Math.ceil(UnitConv.mm2pt(210)),
                (int) Math.ceil(UnitConv.mm2pt(297))); //page size A4 (in pt)
        gPDF.setupDocument(baout, pageSize.width, pageSize.height);
        gPDF.setupDefaultFontInfo();
        gPDF.setGraphicContext(new GraphicContext());
        for (int i = 0; i < 4; i++) {
            gPDF.drawString("PageOUTPUT " + i, getInch(1), getInch(1 + i * 0.2));
            assertTrue(gPDF.getString().contains("PageOUTPUT " + i));
            if (i > 1) {
                int previousValue = i - 1;
                assertFalse(gPDF.getString().contains("PageOUTPUT " + previousValue));
            }
            gPDF.nextPage();
        }
        gPDF.finish();
    }

    private int getInch(double p) {
        final int point = 72;
        final int dpiScale = 4;
        return (int) (p * point * dpiScale);
    }
}
