/*
 * 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.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.fop.render.gradient.Function;
import org.apache.fop.render.gradient.Function.SubFunctionRenderer;
import org.apache.fop.render.gradient.GradientMaker;
import org.apache.fop.render.gradient.GradientMaker.DoubleFormatter;

/**
 * class representing a PDF Function.
 *
 * PDF Functions represent parameterized mathematical formulas and
 * sampled representations with
 * arbitrary resolution. Functions are used in two areas: device-dependent
 * rasterization information for halftoning and transfer
 * functions, and color specification for smooth shading (a PDF 1.3 feature).
 *
 * All PDF Functions have a FunctionType (0,2,3, or 4), a Domain, and a Range.
 */
public class PDFFunction extends PDFObject {

    private final Function function;

    private final List<PDFFunction> pdfFunctions;

    /**
     * create an complete Function object of Type 2, an Exponential Interpolation function.
     *
     * Use null for an optional object parameter if you choose not to use it.
     * For optional int parameters, pass the default.
     *
     * @param domain List objects of Double objects.
     * This is the domain of the function.
     * See page 264 of the PDF 1.3 Spec.
     * @param range List of Doubles that is the Range of the function.
     * See page 264 of the PDF 1.3 Spec.
     * @param cZero This is a vector of Double objects which defines the function result
     * when x=0.
     *
     * This attribute is optional.
     * It's described on page 268 of the PDF 1.3 spec.
     * @param cOne This is a vector of Double objects which defines the function result
     * when x=1.
     *
     * This attribute is optional.
     * It's described on page 268 of the PDF 1.3 spec.
     * @param interpolationExponentN This is the inerpolation exponent.
     *
     * This attribute is required.
     * PDF Spec page 268
     */
    public PDFFunction(List<Double> domain, List<Double> range, float[] cZero, float[] cOne,
            double interpolationExponentN) {
        this(new Function(domain, range, cZero, cOne, interpolationExponentN));

    }

    @SuppressWarnings("unchecked")
    public PDFFunction(Function function) {
        this(function, Collections.EMPTY_LIST);
    }

    public PDFFunction(Function function, List<PDFFunction> pdfFunctions) {
        this.function = function;
        this.pdfFunctions = pdfFunctions;
    }

    public Function getFunction() {
        return function;
    }

    /**
     * represent as PDF. Whatever the FunctionType is, the correct
     * representation spits out. The sets of required and optional
     * attributes are different for each type, but if a required
     * attribute's object was constructed as null, then no error
     * is raised. Instead, the malformed PDF that was requested
     * by the construction is dutifully output.
     * This policy should be reviewed.
     *
     * @return the PDF string.
     */
    public byte[] toPDF() {
        return toByteString();
    }


    public byte[] toByteString() {
        List<String> functionsStrings = new ArrayList<String>(function.getFunctions().size());
        for (PDFFunction f : pdfFunctions) {
            functionsStrings.add(f.referencePDF());
        }
        SubFunctionRenderer subFunctionRenderer = new SubFunctionRenderer() {

            public void outputFunction(StringBuilder out, int functionIndex) {
                out.append(pdfFunctions.get(functionIndex).referencePDF());
            }
        };
        StringBuilder out = new StringBuilder();
        GradientMaker.DoubleFormatter doubleFormatter = new DoubleFormatter() {

            public String formatDouble(double d) {
                return PDFNumber.doubleOut(d);
            }
        };
        function.output(out, doubleFormatter, subFunctionRenderer);
        return encode(out.toString());
    }

    /** {@inheritDoc} */
    protected boolean contentEquals(PDFObject obj) {
        if (obj == null) {
            return false;
        }
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof PDFFunction)) {
            return false;
        }
        Function func = ((PDFFunction) obj).function;
        if (function.getFunctionType() != func.getFunctionType()) {
            return false;
        }
        if (function.getBitsPerSample() != func.getBitsPerSample()) {
            return false;
        }
        if (function.getOrder() != func.getOrder()) {
            return false;
        }
        if (function.getInterpolationExponentN() != func.getInterpolationExponentN()) {
            return false;
        }
        if (function.getDomain() != null) {
            if (!function.getDomain().equals(func.getDomain())) {
                return false;
            }
        } else if (func.getDomain() != null) {
            return false;
        }
        if (function.getRange() != null) {
            if (!function.getRange().equals(func.getRange())) {
                return false;
            }
        } else if (func.getRange() != null) {
            return false;
        }
        if (function.getEncode() != null) {
            if (!function.getEncode().equals(func.getEncode())) {
                return false;
            }
        } else if (func.getEncode() != null) {
            return false;
        }
        if (!Arrays.equals(function.getCZero(), func.getCZero())) {
            return false;
        }
        if (!Arrays.equals(function.getCOne(), func.getCOne())) {
            return false;
        }
        if (!pdfFunctions.equals(((PDFFunction) obj).pdfFunctions)) {
            return false;
        }
        if (function.getBounds() != null) {
            if (!function.getBounds().equals(func.getBounds())) {
                return false;
            }
        } else if (func.getBounds() != null) {
            return false;
        }
        return true;
    }

}
