/*
 * %Z%%W% %I%
 * ===========================================================================
 * Licensed Materials - Property of IBM
 * "Restricted Materials of IBM"
 *
 * IBM SDK, Java(tm) 2 Technology Edition, v1.4
 * (C) Copyright IBM Corp. 1999, 2002. All Rights Reserved
 * ===========================================================================
 */
/*
 * FontProperties: Return font properties information
 *
 * Function:
 *     There are no external Java interfaces to get at information which is in
 *     font.properties, so this code duplicates the logic which reads font.properties
 *     and returns the same information.
 *
 */
import java.awt.*;
import java.util.*;
import java.io.*;
import java.lang.*;
import sun.io.CharacterEncoding;

public class FontProperties extends Object {

    private Properties fprops;
    private String     fname;
    private String     language;
    private String     region;
    private String     osVersion;
    private String     encoding;

    public FontProperties() {
        initializeProps();
    }

    /*
     * getProperties: Returns the font properties as a Properties object.
     *                All of the valid Properties methods can then be done.
     */
    public Properties getProperties() {
        return fprops;
    }

    /*
     * getProperty:  Get a font property
     */
    public String getProperty(String key) {
        return fprops.getProperty(key);
    }

    /*
     * getProperty:  Get a font property with default
     */
    public String getProperty(String key, String deflt) {
        return fprops.getProperty(key, deflt);
    }

    /*
     * getFilename:  Get the font.properties file name
     */
    public String getFilename() {
        return fname;
    }

    /*
     * getDescriptor:  Get the descriptor for one index in a font
     */
    public String getDescriptor(String font, int idx) {
        return getProperty(font+"."+idx);
    }

    /*
     * getDescriptorName:  Get the name portion of a descriptor for one
     *                     index in a font.
     */
    public String getDescriptorName(String font, int idx) {
        return parseName(getProperty(font+"."+idx));
    }

    /*
     * getCompositeCount: Get the count of subfonts for this font
     */
    public int getCompositeCount(String font) {
        for (int i=0; i<99; i++) {
            if (getProperty(font+"."+i, "").equals(""))
                 return i;
        }
        return 0;
    }

    /*
     * getCharset: Get the charset of one subfont
     */
    public String getCharset(String font, int idx) {
         return getProperty("fontcharset."+font+"."+idx, "");
    }

    /*
     * Return system properties used to find font.properties
     */
    public String getEncoding()     { return encoding; }
    public String getLanguage()     { return language; }
    public String getRegion()       { return region; }

    /*
     * Return the OS Version.  Note that this may be different from the
     * OS version used by the
     */
    public String getOSVersion()    { return osVersion; }

    /*
     * Start of private implementation of FontProperties
     */

    /*
     * Parse the name portion of a descriptor
     */
    private String parseName(String name) {
        int separator = name.indexOf(",");
        if (separator == -1) {
            separator = name.length();
        }
        return name.substring(0, separator);
    }

    /*
     * Initialize the font properties
     */
    private void initializeProps() {
        String jhome = System.getProperty("java.home");
        language = System.getProperty("user.language", "en").toLowerCase();
        String javaVersion = System.getProperty("java.version");
        if (javaVersion.compareTo("1.4") < 0)
            region = System.getProperty("user.region");
        else
            region = System.getProperty("user.country");
        osVersion = System.getProperty("os.version");
        String osName = System.getProperty("os.name");

        /* Implement the subclass of the version */
        if (osName.equals("Windows NT")) {
            osVersion = "NT" + osVersion;
        }
        if (osName.equals("OS/2")) {
            if (osVersion.startsWith("20.") && osVersion.length() > 4) {
                osVersion = "OS2"+osVersion.substring(3,4)+'.'+
                            osVersion.substring(4,5);
            }
        }

        String rawEncoding = System.getProperty("file.encoding");
        encoding = CharacterEncoding.aliasName(rawEncoding);
        if (encoding == null)
            encoding = rawEncoding;

        String fontDirFilename = jhome + File.separator + "lib" + File.separator
                                       + "fprop.dir";
        File fontDir = new File(fontDirFilename);
        Properties fpropDir = null;
        if (fontDir.exists()) {
            fpropDir = new Properties();
            try {
                InputStream in = new BufferedInputStream(
                                       new FileInputStream(fontDir.getPath()));
                fpropDir.load(in);
                in.close();
            }
            catch (IOException e) {}
        }

        try {
            File f = null;
            f = tryOpeningFontProp(f, fpropDir, jhome, language, region, encoding, osVersion);
            f = tryOpeningFontProp(f, fpropDir, jhome, language, region, encoding, null);
            f = tryOpeningFontProp(f, fpropDir, jhome, language, region, null, osVersion);
            f = tryOpeningFontProp(f, fpropDir, jhome, language, null, encoding, osVersion);
            f = tryOpeningFontProp(f, fpropDir, jhome, language, region, null, null);
            if ("zh".equals(language) &&
                ("TW".equals(region) || "MO".equals(region)))
                f = tryOpeningFontProp(f, fpropDir, jhome, "zh", "TW", null, null);
            f = tryOpeningFontProp(f, fpropDir, jhome, null, region, null, null);
            f = tryOpeningFontProp(f, fpropDir, jhome, language, null, encoding, null);
            f = tryOpeningFontProp(f, fpropDir, jhome, language, null, null, osVersion);
            f = tryOpeningFontProp(f, fpropDir, jhome, null, null, encoding, osVersion);
            f = tryOpeningFontProp(f, fpropDir, jhome, language, null, null, null);
            f = tryOpeningFontProp(f, fpropDir, jhome, null, null, encoding, null);
            f = tryOpeningFontProp(f, fpropDir, jhome, null, null, null, osVersion);
            f = tryOpeningFontProp(f, fpropDir, jhome, null, null, null, null);

            // set default props to prevent crashing
            // with corrupted or missing font.properties
            Properties defaultProps = new Properties();
            defaultProps.put("serif.0", "unknown");
            defaultProps.put("sansserif.0", "unknown");
            defaultProps.put("monospaced.0", "unknown");
            defaultProps.put("dialog.0", "unknown");
            defaultProps.put("dialoginput.0", "unknown");

            defaultProps.put("default.0", "sansserif");
            defaultProps.put("timesroman.0", "serif");
            defaultProps.put("helvetica.0", "sansserif");
            defaultProps.put("courier.0", "monospaced");
            defaultProps.put("zapfdingbats.0", "unknown");

            fprops = new Properties(defaultProps);
            if (f != null) {
                InputStream in =
                    new BufferedInputStream(new FileInputStream(f.getPath()));
                fprops.load(in);
                in.close();
            }
        } catch (Exception e){
        }
    }

    private File tryOpeningFontProp(File f, Properties fpropDir, String homedir, String language,
                                    String region, String encoding, String osVersion) {
        String  filename;
        String  pathname;
        File    propsFile = null;

        if (f != null) {  // f is already validated
            propsFile = f;
        } else {
            filename = "font.properties";
            pathname = homedir + File.separator + "lib" + File.separator ;
            filename = getPropsFilename(filename,language,region,encoding,osVersion);

            if (fpropDir != null) {
                filename = fpropDir.getProperty(filename);
            }

            if (filename != null) {  //  Returns the fullpath filename.
                f = new File(pathname + filename);
                if (f.canRead()) {
                    propsFile = f;
                    fname = pathname + filename;
                }
            }
        }
        return propsFile;
    }

    private String getPropsFilename (String filename, String language, String region,
                                     String encoding, String osVersion) {
        if (language != null) {
            filename += "." + language;                                                                                            // font.properties.xx
            if (region != null) {
                filename += "_" + region;                                                                                      // font.properties.xx_yy
                if (encoding != null) {
                    filename += "_" + encoding;                                                                            // font.properties.xx_yy_zzz
                    if (osVersion != null) filename += "." + osVersion;            // font.properties.xx_yy_zzz.vvvv
                }
                else if (osVersion != null) filename += "." + osVersion;       // font.properties.xx_yy.vvvv
            } else {
                if (encoding != null) {
                    filename += "_" + encoding;                            // font.properties.xx_zzz
                    if (osVersion != null) filename += "." + osVersion;       // font.properties.xx_zzz.vvvv
                }
                else if (osVersion != null) filename += "." + osVersion;       // font.properties.xx.vvvv
            }
        } else {
            if (encoding != null) {
                filename += "." + encoding;                                                                                    // font.properties.zzz
                if (osVersion != null) filename += "." + osVersion;                    // font.properties.zzz.vvvv
            }
            else if (osVersion != null) filename += "." + osVersion;     // font.properties.vvvv
        }
        return filename;
    }
}
