/*
 * 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.text.MessageFormat;

/**
 * This class allows tracks the enabled PDF profiles (PDF/A and PDF/X) and provides methods to
 * the libarary and its users to enable the generation of PDFs conforming to the enabled PDF
 * profiles.
 * <p>
 * Some profile from PDF/X and PDF/A can be active simultaneously (example: PDF/A-1 and
 * PDF/X-3:2003).
 */
public class PDFProfile {

    /**
     * Indicates the PDF/A mode currently active. Defaults to "no restrictions", i.e.
     * PDF/A not active.
     */
    protected PDFAMode pdfAMode = PDFAMode.DISABLED;

    /**
     * Indicates the PDF/X mode currently active. Defaults to "no restrictions", i.e.
     * PDF/X not active.
     */
    protected PDFXMode pdfXMode = PDFXMode.DISABLED;

    private PDFDocument doc;

    /**
     * Main constructor
     * @param doc the PDF document
     */
    public PDFProfile(PDFDocument doc) {
        this.doc = doc;
    }

    /**
     * Validates if the requested profile combination is compatible.
     */
    protected void validateProfileCombination() {
        if (pdfAMode != PDFAMode.DISABLED) {
            if (pdfAMode == PDFAMode.PDFA_1A) {
                throw new UnsupportedOperationException("PDF/A-1a is not implemented, yet");
            }
            if (pdfAMode == PDFAMode.PDFA_1B) {
                if (pdfXMode != PDFXMode.DISABLED && pdfXMode != PDFXMode.PDFX_3_2003) {
                    throw new PDFConformanceException(
                            pdfAMode + " and " + pdfXMode + " are not compatible!");
                }
            }
        }
    }

    /** @return the PDFDocument this profile is attached to */
    public PDFDocument getDocument() {
        return this.doc;
    }

    /** @return the PDF/A mode */
    public PDFAMode getPDFAMode() {
        return this.pdfAMode;
    }

    /** @return true if any PDF/A mode is active */
    public boolean isPDFAActive() {
        return getPDFAMode() != PDFAMode.DISABLED;
    }

    /**
     * Sets the PDF/A mode
     * @param mode the PDF/A mode
     */
    public void setPDFAMode(PDFAMode mode) {
        if (mode == null) {
            mode = PDFAMode.DISABLED;
        }
        this.pdfAMode = mode;
        validateProfileCombination();
    }

    /** @return the PDF/X mode */
    public PDFXMode getPDFXMode() {
        return this.pdfXMode;
    }

    /** @return true if any PDF/X mode is active */
    public boolean isPDFXActive() {
        return getPDFXMode() != PDFXMode.DISABLED;
    }

    /**
     * Sets the PDF/X mode
     * @param mode the PDF/X mode
     */
    public void setPDFXMode(PDFXMode mode) {
        if (mode == null) {
            mode = PDFXMode.DISABLED;
        }
        this.pdfXMode = mode;
        validateProfileCombination();
    }

    /** {@inheritDoc} */
    public String toString() {
        StringBuffer sb = new StringBuffer();
        if (isPDFAActive() && isPDFXActive()) {
            sb.append("[").append(getPDFAMode()).append(",").append(getPDFXMode()).append("]");
        } else if (isPDFAActive()) {
            sb.append(getPDFAMode());
        } else if (isPDFXActive()) {
            sb.append(getPDFXMode());
        } else {
            sb.append(super.toString());
        }
        return sb.toString();
    }

    //---------=== Info and validation methods ===---------

    private String format(String pattern, Object arg) {
        return MessageFormat.format(pattern, new Object[] {arg});
    }

    /** Checks if encryption is allowed. */
    public void verifyEncryptionAllowed() {
        final String err = "{0} doesn't allow encrypted PDFs";
        if (isPDFAActive()) {
            throw new PDFConformanceException(format(err, getPDFAMode()));
        }
        if (isPDFXActive()) {
            throw new PDFConformanceException(format(err, getPDFXMode()));
        }
    }

    /** Checks if PostScript XObjects are allowed. */
    public void verifyPSXObjectsAllowed() {
        final String err = "PostScript XObjects are prohibited when {0}"
                + " is active. Convert EPS graphics to another format.";
        if (isPDFAActive()) {
            throw new PDFConformanceException(format(err, getPDFAMode()));
        }
        if (isPDFXActive()) {
            throw new PDFConformanceException(format(err, getPDFXMode()));
        }
    }

    /**
     * Checks if the use of transparency is allowed.
     * @param context Context information for the user to identify the problem spot
     */
    public void verifyTransparencyAllowed(String context) {
        final String err = "{0} does not allow the use of transparency. ({1})";
        if (isPDFAActive()) {
            throw new PDFConformanceException(MessageFormat.format(err,
                    new Object[] {getPDFAMode(), context}));
        }
        if (isPDFXActive()) {
            throw new PDFConformanceException(MessageFormat.format(err,
                    new Object[] {getPDFXMode(), context}));
        }
    }

    /** Checks if the right PDF version is set. */
    public void verifyPDFVersion() {
        final String err = "PDF version must be 1.4 for {0}";
        if (getPDFAMode().isPDFA1LevelB()
                && getDocument().getPDFVersion() != PDFDocument.PDF_VERSION_1_4) {
            throw new PDFConformanceException(format(err, getPDFAMode()));
        }
        if (getPDFXMode() == PDFXMode.PDFX_3_2003
                && getDocument().getPDFVersion() != PDFDocument.PDF_VERSION_1_4) {
            throw new PDFConformanceException(format(err, getPDFXMode()));
        }
    }

    /** @return true if the ID entry must be present in the trailer. */
    public boolean isIDEntryRequired() {
        return isPDFAActive() || isPDFXActive();
    }

    /** @return true if all fonts need to be embedded. */
    public boolean isFontEmbeddingRequired() {
        return isPDFAActive() || isPDFXActive();
    }

    /** Checks if a title may be absent. */
    public void verifyTitleAbsent() {
        if (isPDFXActive()) {
            final String err = "{0} requires the title to be set.";
            throw new PDFConformanceException(format(err, getPDFXMode()));
        }
    }

    /** @return true if the ModDate Info entry must be present. */
    public boolean isModDateRequired() {
        return getPDFXMode() == PDFXMode.PDFX_3_2003;
    }

    /** @return true if the Trapped Info entry must be present. */
    public boolean isTrappedEntryRequired() {
        return getPDFXMode() == PDFXMode.PDFX_3_2003;
    }

    /** @return true if annotations are allowed */
    public boolean isAnnotationAllowed() {
        return !isPDFXActive();
    }

    /** Checks if annotations are allowed. */
    public void verifyAnnotAllowed() {
        if (!isAnnotationAllowed()) {
            final String err = "{0} does not allow annotations inside the printable area.";
            //Note: this rule is simplified. Refer to the standard for details.
            throw new PDFConformanceException(format(err, getPDFXMode()));
        }
    }

    /** Checks if Actions are allowed. */
    public void verifyActionAllowed() {
        if (isPDFXActive()) {
            final String err = "{0} does not allow Actions.";
            throw new PDFConformanceException(format(err, getPDFXMode()));
        }
    }

}
