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