/*
 * 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.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
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.fonts.AFPFont;
import org.apache.fop.afp.fonts.AFPFontInfo;
import org.apache.fop.afp.fonts.CharacterSet;
import org.apache.fop.afp.fonts.CharacterSetBuilder;
import org.apache.fop.afp.fonts.CharacterSetType;
import org.apache.fop.afp.fonts.DoubleByteFont;
import org.apache.fop.afp.fonts.OutlineFont;
import org.apache.fop.afp.fonts.RasterFont;
import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.configuration.Configuration;
import org.apache.fop.configuration.ConfigurationException;
import org.apache.fop.events.EventProducer;
import org.apache.fop.fonts.EmbedFontInfo;
import org.apache.fop.fonts.EmbeddingMode;
import org.apache.fop.fonts.EncodingMode;
import org.apache.fop.fonts.FontConfig;
import org.apache.fop.fonts.FontManager;
import org.apache.fop.fonts.FontManagerConfigurator;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.FontTriplet.Matcher;
import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.FontUris;
import org.apache.fop.fonts.FontUtil;
import org.apache.fop.fonts.LazyFont;
import org.apache.fop.fonts.Typeface;

/**
 * The config object for AFP fonts, these differ from the the more generic fonts (TTF and Type1).
 */
public final class AFPFontConfig implements FontConfig {

    private static final Log LOG = LogFactory.getLog(AFPFontConfig.class);

    private final List<AFPFontConfigData> fontsConfig;

    private AFPFontConfig() {
        fontsConfig = new ArrayList<AFPFontConfigData>();
    }

    /**
     * Returns a list of AFP font configuration data.
     * @return the AFP font config data
     */
    public List<AFPFontConfigData> getFontConfig() {
        return fontsConfig;
    }

    /**
     * The parser for AFP font data.
     */
    static final class AFPFontInfoConfigParser implements FontConfigParser {

        /** {@inheritDoc}} */
        public AFPFontConfig parse(Configuration cfg, FontManager fontManager, boolean strict,
                                   EventProducer eventProducer) throws FOPException {
            try {
                return new ParserHelper(cfg, fontManager, strict,
                        (AFPEventProducer) eventProducer).fontConfig;
            } catch (ConfigurationException ce) {
                throw new FOPException(ce);
            }
        }

        AFPFontConfig getEmptyConfig() {
            return new AFPFontConfig();
        }
    }

    private static final class AggregateMatcher implements Matcher {

        private final List<Matcher> matchers;

        private AggregateMatcher(Matcher... matchers) {
            this.matchers = new ArrayList<Matcher>();
            for (Matcher matcher : matchers) {
                if (matcher != null) {
                    this.matchers.add(matcher);
                }
            }
        }

        public boolean matches(FontTriplet triplet) {
            for (Matcher matcher : matchers) {
                if (matcher.matches(triplet)) {
                    return true;
                }
            }
            return false;
        }

    }

    private static final class ParserHelper {

        private static final Log LOG = LogFactory.getLog(ParserHelper.class);

        private final AFPFontConfig fontConfig;

        private final Matcher matcher;

        private ParserHelper(Configuration cfg, FontManager fontManager, boolean strict,
                AFPEventProducer eventProducer) throws FOPException, ConfigurationException {
            Configuration fonts = cfg.getChild("fonts");
            Matcher localMatcher = null;
            Configuration referencedFontsCfg = fonts.getChild("referenced-fonts", false);
            if (referencedFontsCfg != null) {
                localMatcher = FontManagerConfigurator.createFontsMatcher(referencedFontsCfg, strict);
            }
            matcher = new AggregateMatcher(fontManager.getReferencedFontsMatcher(), localMatcher);
            fontConfig = new AFPFontConfig();
            for (Configuration font : fonts.getChildren("font")) {
                buildFont(font, eventProducer);
            }
        }

        private void buildFont(Configuration fontCfg, AFPEventProducer eventProducer)
                throws ConfigurationException {
            //FontManager fontManager = this.userAgent.getFontManager();
            Configuration[] triplets = fontCfg.getChildren("font-triplet");
            List<FontTriplet> tripletList = new ArrayList<FontTriplet>();
            if (triplets.length == 0) {
                eventProducer.fontConfigMissing(this, "<font-triplet...", fontCfg.getLocation());
                return;
            }
            for (Configuration triplet : triplets) {
                int weight = FontUtil.parseCSS2FontWeight(triplet.getAttribute("weight"));
                FontTriplet fontTriplet = new FontTriplet(triplet.getAttribute("name"),
                        triplet.getAttribute("style"), weight);
                tripletList.add(fontTriplet);
            }

            String tturi = fontCfg.getAttribute("embed-url", null);
            if (tturi != null) {
                fontFromType(tripletList, "truetype", null, "UTF-16BE", fontCfg, eventProducer, tturi);
                return;
            }

            //build the fonts
            Configuration[] config = fontCfg.getChildren("afp-font");
            if (config.length == 0) {
                eventProducer.fontConfigMissing(this, "<afp-font...", fontCfg.getLocation());
                return;
            }
            Configuration afpFontCfg = config[0];
            String uri = afpFontCfg.getAttribute("base-uri", null);
            try {
                String type = afpFontCfg.getAttribute("type");
                if (type == null) {
                    eventProducer.fontConfigMissing(this, "type attribute", fontCfg.getLocation());
                    return;
                }
                String codepage = afpFontCfg.getAttribute("codepage");
                if (codepage == null) {
                    eventProducer.fontConfigMissing(this, "codepage attribute",
                            fontCfg.getLocation());
                    return;
                }
                String encoding = afpFontCfg.getAttribute("encoding");
                if (encoding == null) {
                    eventProducer.fontConfigMissing(this, "encoding attribute",
                            fontCfg.getLocation());
                    return;
                }

                fontFromType(tripletList, type, codepage, encoding, afpFontCfg, eventProducer, uri);
            } catch (ConfigurationException ce) {
                eventProducer.invalidConfiguration(this, ce);
            }
        }

        private void fontFromType(List<FontTriplet> fontTriplets, String type, String codepage,
                String encoding, Configuration cfg, AFPEventProducer eventProducer, String embedURI)
                throws ConfigurationException {
            AFPFontConfigData config = null;
            if ("raster".equalsIgnoreCase(type)) {
                config = getRasterFont(fontTriplets, type, codepage, encoding, cfg, eventProducer,
                        embedURI);
            } else if ("outline".equalsIgnoreCase(type)) {
                config = getOutlineFont(fontTriplets, type, codepage, encoding, cfg, eventProducer,
                        embedURI);
            } else if ("CIDKeyed".equalsIgnoreCase(type)) {
                config = getCIDKeyedFont(fontTriplets, type, codepage, encoding, cfg,
                        eventProducer, embedURI);
            } else if ("truetype".equalsIgnoreCase(type)) {
                config = getTruetypeFont(fontTriplets, type, codepage, encoding, cfg, eventProducer, embedURI);
            } else {
                LOG.error("No or incorrect type attribute: " + type);
            }
            if (config != null) {
                fontConfig.fontsConfig.add(config);
            }
        }

        private CIDKeyedFontConfig getCIDKeyedFont(List<FontTriplet> fontTriplets, String type,
                String codepage, String encoding, Configuration cfg, AFPEventProducer eventProducer,
                String uri) throws ConfigurationException {
            String characterset = cfg.getAttribute("characterset");
            if (characterset == null) {
                eventProducer.fontConfigMissing(this, "characterset attribute",
                        cfg.getLocation());
                return null;
            }
            String name = cfg.getAttribute("name", characterset);
            CharacterSetType charsetType = cfg.getAttributeAsBoolean("ebcdic-dbcs", false)
                    ? CharacterSetType.DOUBLE_BYTE_LINE_DATA : CharacterSetType.DOUBLE_BYTE;
            return new CIDKeyedFontConfig(fontTriplets, type, codepage, encoding, characterset,
                    name, charsetType, isEmbbedable(fontTriplets), uri);
        }

        private OutlineFontConfig getOutlineFont(List<FontTriplet> fontTriplets, String type,
                String codepage, String encoding, Configuration cfg,
                AFPEventProducer eventProducer, String uri) throws ConfigurationException {
            String characterset = cfg.getAttribute("characterset");
            if (characterset == null) {
                eventProducer.fontConfigMissing(this, "characterset attribute",
                        cfg.getLocation());
                return null;
            }
            String name = cfg.getAttribute("name", characterset);
            String base14 = cfg.getAttribute("base14-font", null);
            return new OutlineFontConfig(fontTriplets, type, codepage, encoding, characterset,
                    name, base14, isEmbbedable(fontTriplets), uri);
        }

        private TrueTypeFontConfig getTruetypeFont(List<FontTriplet> fontTriplets, String type, String codepage,
                                                   String encoding, Configuration cfg, AFPEventProducer eventProducer,
                                                   String uri) throws ConfigurationException {
            String name = cfg.getAttribute("name", null);
            if (name == null) {
                eventProducer.fontConfigMissing(this, "font name attribute", cfg.getLocation());
                return null;
            }
            String subfont = cfg.getAttribute("sub-font", null);
            boolean positionByChar = cfg.getAttributeAsBoolean("position-by-char", true);
            return new TrueTypeFontConfig(fontTriplets, type, codepage, encoding, "",
                    name, subfont, isEmbbedable(fontTriplets), uri, positionByChar);
        }

        private RasterFontConfig getRasterFont(List<FontTriplet> triplets, String type,
                String codepage, String encoding, Configuration cfg,
                AFPEventProducer eventProducer, String uri)
                throws ConfigurationException {
            String name = cfg.getAttribute("name", "Unknown");
            // Create a new font object
            Configuration[] rasters = cfg.getChildren("afp-raster-font");
            if (rasters.length == 0) {
                eventProducer.fontConfigMissing(this, "<afp-raster-font...",
                        cfg.getLocation());
                return null;
            }
            List<RasterCharactersetData> charsetData = new ArrayList<RasterCharactersetData>();
            for (Configuration rasterCfg : rasters) {
                String characterset = rasterCfg.getAttribute("characterset");
                if (characterset == null) {
                    eventProducer.fontConfigMissing(this, "characterset attribute",
                            cfg.getLocation());
                    return null;
                }
                float size = rasterCfg.getAttributeAsFloat("size");
                int sizeMpt = (int) (size * 1000);
                String base14 = rasterCfg.getAttribute("base14-font", null);
                charsetData.add(new RasterCharactersetData(characterset, sizeMpt, base14));
            }
            return new RasterFontConfig(triplets, type, codepage, encoding, null, name, uri, charsetData,
                    isEmbbedable(triplets));
        }

        private boolean isEmbbedable(List<FontTriplet> triplets) {
            for (FontTriplet triplet : triplets) {
                if (matcher.matches(triplet)) {
                    return false;
                }
            }
            return true;
        }

    }

    abstract static class AFPFontConfigData {
        protected final List<FontTriplet> triplets;
        private final String codePage;
        private final String encoding;
        private final String name;
        private final boolean embeddable;
        protected final String uri;

        AFPFontConfigData(List<FontTriplet> triplets, String type, String codePage,
                String encoding, String name, boolean embeddable, String uri) {
            this.triplets = Collections.unmodifiableList(triplets);
            this.codePage = codePage;
            this.encoding = encoding;
            this.name = name;
            this.embeddable = embeddable;
            this.uri = uri;
        }

        static AFPFontInfo getFontInfo(AFPFont font, AFPFontConfigData config) {
            return font != null ? new AFPFontInfo(font, config.triplets) : null;
        }

        abstract AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver,
                AFPEventProducer eventProducer) throws IOException;

        AFPResourceAccessor getAccessor(InternalResourceResolver resourceResolver) {
            return new AFPResourceAccessor(resourceResolver, uri);
        }
    }

    static final class CIDKeyedFontConfig extends AFPFontConfigData {

        private final CharacterSetType charsetType;

        private final String characterset;

        private CIDKeyedFontConfig(List<FontTriplet> triplets, String type, String codePage, String encoding,
                String characterset, String name, CharacterSetType charsetType, boolean embeddable, String uri) {
            super(triplets, type, codePage, encoding, name, embeddable, uri);
            this.characterset = characterset;
            this.charsetType = charsetType;
        }

        @Override
        AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver, AFPEventProducer eventProducer)
                throws IOException {
            AFPResourceAccessor accessor = getAccessor(resourceResolver);
            CharacterSet characterSet = CharacterSetBuilder.getDoubleByteInstance().buildDBCS(
                    characterset, super.codePage, super.encoding, charsetType, accessor, eventProducer);
            return getFontInfo(new DoubleByteFont(super.codePage, super.embeddable, characterSet,
                    eventProducer), this);
        }
    }

    static final class TrueTypeFontConfig extends AFPFontConfigData {
        private String characterset;
        private String subfont;
        private String fontUri;
        private boolean positionByChar;

        private TrueTypeFontConfig(List<FontTriplet> triplets, String type, String codePage,
                                   String encoding, String characterset, String name, String subfont,
                                   boolean embeddable, String uri, boolean positionByChar) {
            super(triplets, type, codePage, encoding, name, embeddable, null);
            this.characterset = characterset;
            this.subfont = subfont;
            this.fontUri = uri;
            this.positionByChar = positionByChar;
        }

        @Override
        AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver, AFPEventProducer eventProducer)
                throws IOException {
            try {
                FontUris fontUris = new FontUris(new URI(fontUri), null);
                EmbedFontInfo embedFontInfo = new EmbedFontInfo(fontUris, false, true, null, subfont, EncodingMode.AUTO,
                        EmbeddingMode.FULL, false, false, true);
                Typeface tf = new LazyFont(embedFontInfo, resourceResolver, false).getRealFont();
                AFPResourceAccessor accessor = getAccessor(resourceResolver);
                CharacterSet characterSet = CharacterSetBuilder.getDoubleByteInstance().build(characterset,
                        super.codePage, super.encoding, tf, accessor, eventProducer);
                OutlineFont font = new AFPTrueTypeFont(super.name, super.embeddable, characterSet,
                            eventProducer, subfont, new URI(fontUri), positionByChar);
                return getFontInfo(font, this);
            } catch (URISyntaxException e) {
                throw new IOException(e);
            }
        }
    }

    public static class AFPTrueTypeFont extends OutlineFont {
        private String ttc;
        private URI uri;
        private boolean positionByChar;
        public AFPTrueTypeFont(String name, boolean embeddable, CharacterSet charSet, AFPEventProducer eventProducer,
                               String ttc, URI uri, boolean positionByChar) {
            super(name, embeddable, charSet, eventProducer);
            this.ttc = ttc;
            this.uri = uri;
            this.positionByChar = positionByChar;
        }

        public FontType getFontType() {
            return FontType.TRUETYPE;
        }

        public String getTTC() {
            return ttc;
        }

        public URI getUri() {
            return uri;
        }

        public boolean isPositionByChar() {
            return positionByChar;
        }
    }

    static final class OutlineFontConfig extends AFPFontConfigData {
        private final String base14;
        private final String characterset;

        private OutlineFontConfig(List<FontTriplet> triplets, String type, String codePage,
                String encoding, String characterset, String name, String base14, boolean embeddable, String uri) {
            super(triplets, type, codePage, encoding, name, embeddable, uri);
            this.characterset = characterset;
            this.base14 = base14;
        }

        @Override
        AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver, AFPEventProducer eventProducer)
                throws IOException {
            CharacterSet characterSet = null;
            if (base14 != null) {
                try {
                    Typeface tf = getTypeFace(base14);
                    characterSet = CharacterSetBuilder.getSingleByteInstance()
                                                      .build(characterset, super.codePage,
                                                              super.encoding, tf, eventProducer);
                } catch (ClassNotFoundException cnfe) {
                    String msg = "The base 14 font class for " + characterset
                            + " could not be found";
                    LOG.error(msg);
                }
            } else {
                AFPResourceAccessor accessor = getAccessor(resourceResolver);
                characterSet = CharacterSetBuilder.getSingleByteInstance().buildSBCS(
                        characterset, super.codePage, super.encoding, accessor, eventProducer);
            }
            return getFontInfo(new OutlineFont(super.name, super.embeddable, characterSet,
                    eventProducer), this);
        }
    }

    private static Typeface getTypeFace(String base14Name) throws ClassNotFoundException {
        try {
            Class<? extends Typeface> clazz = Class.forName("org.apache.fop.fonts.base14."
                    + base14Name).asSubclass(Typeface.class);
            return clazz.getDeclaredConstructor().newInstance();
        } catch (IllegalAccessException iae) {
            LOG.error(iae.getMessage());
        } catch (ClassNotFoundException cnfe) {
            LOG.error(cnfe.getMessage());
        } catch (InstantiationException ie) {
            LOG.error(ie.getMessage());
        } catch (NoSuchMethodException e) {
            LOG.error(e.getMessage());
        } catch (InvocationTargetException e) {
            LOG.error(e.getMessage());
        }
        throw new ClassNotFoundException("Couldn't load file for AFP font with base14 name: "
                + base14Name);
    }

    static final class RasterFontConfig extends AFPFontConfigData {
        private final List<RasterCharactersetData> charsets;

        private RasterFontConfig(List<FontTriplet> triplets, String type, String codePage,
                String encoding, String characterset, String name, String uri,
                List<RasterCharactersetData> csetData, boolean embeddable) {
            super(triplets, type, codePage, encoding, name, embeddable, uri);
            this.charsets = Collections.unmodifiableList(csetData);
        }

        @Override
        AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver, AFPEventProducer eventProducer)
                throws IOException {
            RasterFont rasterFont = new RasterFont(super.name, super.embeddable);
            for (RasterCharactersetData charset : charsets) {
                if (charset.base14 != null) {
                    try {
                        Typeface tf = getTypeFace(charset.base14);
                        rasterFont.addCharacterSet(charset.size,
                                CharacterSetBuilder.getSingleByteInstance().build(
                                        charset.characterset, super.codePage, super.encoding,
                                        tf, eventProducer));

                    } catch (ClassNotFoundException cnfe) {
                        String msg = "The base 14 font class for " + charset.characterset
                                + " could not be found";
                        LOG.error(msg);
                    } catch (IOException ie) {
                        String msg = "The base 14 font class " + charset.characterset
                                + " could not be instantiated";
                        LOG.error(msg);
                    }
                } else {
                    AFPResourceAccessor accessor = getAccessor(resourceResolver);
                    rasterFont.addCharacterSet(charset.size,
                            CharacterSetBuilder.getSingleByteInstance().buildSBCS(charset.characterset,
                                    super.codePage, super.encoding, accessor, eventProducer));
                }
            }
            return getFontInfo(rasterFont, this);
        }
    }

    static final class RasterCharactersetData {
        private final String characterset;
        private final int size;
        private final String base14;

        private RasterCharactersetData(String characterset, int size, String base14) {
            this.characterset = characterset;
            this.size = size;
            this.base14 = base14;
        }
    }
}
