/*
 * 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: PDFReferenceTestCase.java 1551536 2013-12-17 13:15:06Z vhennebert $ */

package org.apache.fop.pdf;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import org.junit.Test;

import static org.junit.Assert.assertTrue;

/**
 * Test case for {@link PDFResources}.
 */
public class PDFResourcesTestCase {

    private AtomicInteger patternCount = new AtomicInteger(0);
    private AtomicInteger objectNummerCount = new AtomicInteger(0);

    /**
     * Test PDF resources output with color space, pattern and shading.
     * @throws IOException
     */
    @Test
    public void testOutput() throws IOException {
        PDFDocument pdfDoc = new PDFDocument(null);
        PDFResources res = new PDFResources(pdfDoc);
        res.addColorSpace(this.createColorSpace());
        PDFResourceContext context = new PDFResourceContext(res);

        context.addPattern(this.createPDFPattern(res, pdfDoc));
        context.addShading(this.createPDFShading(res, pdfDoc));

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        res.output(baos);

        String expectedShading = "/Shading << /Sh2 4 0 R >>";
        String expectedPattern = "/Pattern << /Pa1 2 0 R >>\n";
        String expectedColorspace = "/ColorSpace << /cs1 [/Separation /cs1 /DeviceRGB 1 0 R] >>\n";

        String outputString = baos.toString();

        assertTrue(outputString.contains(expectedShading));
        assertTrue(outputString.contains(expectedPattern));
        assertTrue(outputString.contains(expectedColorspace));
    }

    /**
     * Test PDF resources output with color space, pattern and shading,
     * if the PDF resource object has a parent resource object.
     * @throws IOException
     */
    @Test
    public void testOutputWithParent() throws IOException {
        PDFDocument pdfDoc = new PDFDocument(null);
        PDFResources res = new PDFResources(pdfDoc);
        PDFResources resParent = new PDFResources(pdfDoc);
        res.setParentResources(resParent);
        resParent.addColorSpace(this.createColorSpace());
        PDFResourceContext context = new PDFResourceContext(resParent);

        context.addPattern(this.createPDFPattern(resParent, pdfDoc));
        context.addShading(this.createPDFShading(resParent, pdfDoc));

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        res.output(baos);

        String expectedShading = "/Shading << /Sh2 4 0 R >>";
        String expectedPattern = "/Pattern << /Pa1 2 0 R >>\n";
        String expectedColorspace = "/ColorSpace << /cs1 [/Separation /cs1 /DeviceRGB 1 0 R] >>\n";

        String outputString = baos.toString();

        assertTrue(outputString.contains(expectedShading));
        assertTrue(outputString.contains(expectedPattern));
        assertTrue(outputString.contains(expectedColorspace));
    }

    /**
     * Test PDF resources output with color space, pattern and shading,
     * if the PDF resource object has a parent resource object, that also has
     * color spaces, patterns and shadings.
     * @throws IOException
     */
    @Test
    public void testOutputWithParent2() throws IOException {
        PDFDocument pdfDoc = new PDFDocument(null);
        PDFResources res = new PDFResources(pdfDoc);
        PDFDictionary shadingDict = new PDFDictionary();
        shadingDict.put("Sh1-1718006973", new PDFReference("9 0"));
        res.put("Shading", shadingDict);
        PDFDictionary patternDict = new PDFDictionary();
        patternDict.put("Pa1-1718006973", new PDFReference("10 0"));
        res.put("Pattern", patternDict);
        PDFDictionary colorSpaceDict = new PDFDictionary();
        colorSpaceDict.put("DefaultRGB", new PDFReference("11 0"));
        res.put("ColorSpace", colorSpaceDict);
        PDFResources resParent = new PDFResources(pdfDoc);
        res.setParentResources(resParent);
        resParent.addColorSpace(this.createColorSpace());
        PDFResourceContext context = new PDFResourceContext(resParent);

        context.addPattern(this.createPDFPattern(resParent, pdfDoc));
        context.addShading(this.createPDFShading(resParent, pdfDoc));

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        res.output(baos);

        String outputString = baos.toString();

        String expectedShading = "/Shading << /Sh1-1718006973 9 0 R /Sh2 4 0 R >>";
        String expectedPattern = "/Shading << /Sh1-1718006973 9 0 R /Sh2 4 0 R >>";
        String expectedColorspace = "/ColorSpace << /DefaultRGB 11 0 R"
                + " /cs1 [/Separation /cs1 /DeviceRGB 1 0 R] >>";

        assertTrue(outputString.contains(expectedShading));
        assertTrue(outputString.contains(expectedPattern));
        assertTrue(outputString.contains(expectedColorspace));
    }

    private PDFShading createPDFShading(PDFResources res, PDFDocument pdfDoc) {
        List<Double> coords = new ArrayList<Double>(4);
        coords.add(1d);
        coords.add(1d);
        coords.add(1d);
        coords.add(1d);
        PDFFunction pdfFunction = createPDFFunction();
        PDFDeviceColorSpace deviceColorspace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
        PDFShading shading = new PDFShading(2, deviceColorspace, coords, pdfFunction);
        shading.setObjectNumber(objectNummerCount.incrementAndGet());
        shading.setDocument(pdfDoc);
        shading.setName("Sh" + patternCount.incrementAndGet());
        return shading;
    }

    private PDFColorSpace createColorSpace() {
        PDFFunction tintFunction = createPDFFunction();
        return new PDFSeparationColorSpace("cs1", tintFunction);
    }

    private PDFFunction createPDFFunction() {
        final Double zero = 0d;
        final Double one = 1d;
        List<Double> domain = Arrays.asList(new Double[] {zero, one});
        List<Double> range = Arrays.asList(new Double[] {zero, one, zero, one, zero, one});
        float[] cZero = new float[] {1f, 1f, 1f};
        float[] cOne = {0f, 0f, 0f};
        PDFFunction tintFunction = new PDFFunction(domain, range, cZero, cOne, 1.0d);
        tintFunction.setObjectNumber(objectNummerCount.incrementAndGet());
        return tintFunction;
    }

    private PDFPattern createPDFPattern(PDFResources res, PDFDocument pdfDoc) {
        List<Double> bbox = new ArrayList<Double>();
        bbox.add(1d);
        bbox.add(1d);
        bbox.add(1d);
        bbox.add(1d);
        List<Double> theMatrix = new ArrayList<Double>();
        for (int i = 0; i < 6; i++) {
            theMatrix.add(1d);
        }

        PDFPattern pattern = new PDFPattern(res, 1, 1, 1, bbox, 1, 1, theMatrix, null,
                new StringBuffer());
        pattern.setObjectNumber(objectNummerCount.incrementAndGet());
        pattern.setDocument(pdfDoc);
        pattern.setName("Pa" + patternCount.incrementAndGet());
        return pattern;
    }
}
