/*
 * 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.render.afp;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.afp.AFPEventProducer;
import org.apache.fop.afp.AFPResourceLevelDefaults;
import org.apache.fop.afp.fonts.AFPFontCollection;
import org.apache.fop.afp.fonts.AFPFontInfo;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.FontCollection;
import org.apache.fop.render.PrintRendererConfigurator;
import org.apache.fop.render.RendererConfig.RendererConfigParser;
import org.apache.fop.render.afp.AFPFontConfig.AFPFontConfigData;
import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.util.LogUtil;

/**
 * AFP Renderer configurator
 */
public class AFPRendererConfigurator extends PrintRendererConfigurator {
    private static Log log = LogFactory.getLog(AFPRendererConfigurator.class);

    private final AFPEventProducer eventProducer;

    /**
     * Default constructor
     *
     * @param userAgent user agent
     */
    public AFPRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser) {
        super(userAgent, rendererConfigParser);
        eventProducer = AFPEventProducer.Provider.get(userAgent.getEventBroadcaster());
    }


    @Override
    public void configure(IFDocumentHandler documentHandler) throws FOPException {
        AFPRendererConfig config = (AFPRendererConfig) getRendererConfig(documentHandler);
        if (config != null) {
            AFPDocumentHandler afpDocumentHandler = (AFPDocumentHandler) documentHandler;
            configure(afpDocumentHandler, config);
        }
    }

    private void configure(AFPDocumentHandler documentHandler, AFPRendererConfig config) {
        Boolean colorImages = config.isColorImages();
        if (colorImages != null) {
            documentHandler.setColorImages(colorImages);
            if (colorImages) {
                documentHandler.setCMYKImagesSupported(config.isCmykImagesSupported());
            } else {
                documentHandler.setBitsPerPixel(config.getBitsPerPixel());
            }
        }
        if (config.getDitheringQuality() != null) {
            documentHandler.setDitheringQuality(config.getDitheringQuality());
        }
        if (config.isNativeImagesSupported() != null) {
            documentHandler.setNativeImagesSupported(config.isNativeImagesSupported());
        }
        if (config.getShadingMode() != null) {
            documentHandler.setShadingMode(config.getShadingMode());
        }
        if (config.getResolution() != null) {
            documentHandler.setResolution(config.getResolution());
        }
        if (config.isWrapPseg() != null) {
            documentHandler.setWrapPSeg(config.isWrapPseg());
        }
        if (config.isGocaWrapPseg() != null) {
            documentHandler.setWrapGocaPSeg(config.isGocaWrapPseg());
        }
        if (config.isFs45() != null) {
            documentHandler.setFS45(config.isFs45());
        }
        if (config.isMaskEnabled() != null) {
            documentHandler.setMaskEnabled(config.isMaskEnabled());
        }
        if (config.allowJpegEmbedding() != null) {
            documentHandler.canEmbedJpeg(config.allowJpegEmbedding());
        }
        if (config.getBitmapEncodingQuality() != null) {
            documentHandler.setBitmapEncodingQuality(config.getBitmapEncodingQuality());
        }
        if (config.getLineWidthCorrection() != null) {
            documentHandler.setLineWidthCorrection(config.getLineWidthCorrection());
        }
        if (config.isGocaEnabled() != null) {
            documentHandler.setGOCAEnabled(config.isGocaEnabled());
        }
        if (config.isStrokeGocaText() != null) {
            documentHandler.setStrokeGOCAText(config.isStrokeGocaText());
        }
        if (config.getDefaultResourceGroupUri() != null) {
            documentHandler.setDefaultResourceGroupUri(config.getDefaultResourceGroupUri());
        }
        AFPResourceLevelDefaults resourceLevelDefaults = config.getResourceLevelDefaults();
        if (resourceLevelDefaults != null) {
            documentHandler.setResourceLevelDefaults(resourceLevelDefaults);
        }
    }

    @Override
    protected List<FontCollection> getDefaultFontCollection() {
        return new ArrayList<FontCollection>();
    }

    @Override
    protected FontCollection getCustomFontCollection(InternalResourceResolver uriResolverWrapper,
            String mimeType) throws FOPException {
        AFPRendererConfig config = (AFPRendererConfig) getRendererConfig(mimeType);
        if (config != null) {
            try {
                return new AFPFontCollection(userAgent.getEventBroadcaster(), createFontsList(
                        config.getFontInfoConfig(), mimeType));
            } catch (IOException e) {
                eventProducer.invalidConfiguration(this, e);
                LogUtil.handleException(log, e, userAgent.validateUserConfigStrictly());
            } catch (IllegalArgumentException iae) {
                eventProducer.invalidConfiguration(this, iae);
                LogUtil.handleException(log, iae, userAgent.validateUserConfigStrictly());
            }
        }
        return new AFPFontCollection(userAgent.getEventBroadcaster(), null);
    }

    private List<AFPFontInfo> createFontsList(AFPFontConfig fontConfig, String mimeType)
            throws FOPException, IOException {
        List<AFPFontInfo> afpFonts = new ArrayList<AFPFontInfo>();
        for (AFPFontConfigData config : fontConfig.getFontConfig()) {
            afpFonts.add(config.getFontInfo(userAgent.getFontManager().getResourceResolver(),
                    eventProducer));
        }
        return afpFonts;
    }
}
