/*
 * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.font;

import java.awt.FontFormatException;
import java.awt.font.FontRenderContext;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Locale;
import java.nio.charset.*;
import java.nio.CharBuffer;
import java.nio.ByteBuffer;

class XMap {

    private static HashMap xMappers = new HashMap();

    /* ConvertedGlyphs has unicode code points as indexes and values
     * are platform-encoded multi-bytes chars packed into java chars.
     * These platform-encoded characters are equated to glyph ids, although
     * that's not strictly true, as X11 only supports using chars.
     * The assumption carried over from the native implementation that
     * a char is big enough to hold an X11 glyph id (ie platform char).
     */
    char[] convertedGlyphs;

    static synchronized XMap getXMapper(String encoding) {
        XMap mapper = (XMap)xMappers.get(encoding);
        if (mapper == null) {
            mapper = getXMapperInternal(encoding);
            xMappers.put(encoding, mapper);
        }
        return mapper;
    }

    static final int SINGLE_BYTE = 1;
    static final int DOUBLE_BYTE = 2;

    private static XMap getXMapperInternal(String encoding) {

        String jclass = null;
        int nBytes = SINGLE_BYTE;
        int maxU = 0xffff;
        int minU = 0;
        boolean addAscii = false;
        boolean lowPartOnly = false;
        if (encoding.equals("dingbats")) {
            jclass = "sun.awt.motif.X11Dingbats";
            minU = 0x2701;
            maxU = 0x27be;
        } else if (encoding.equals("symbol")){
            jclass = "sun.awt.Symbol";
            minU = 0x0391;
            maxU = 0x22ef;
        } else if (encoding.equals("iso8859-1")) {
            maxU = 0xff;
        } else if (encoding.equals("iso8859-2")) {
            jclass = "ISO8859_2";
        } else if (encoding.equals("jisx0208.1983-0")) {
            jclass = "sun.awt.motif.X11JIS0208";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.equals("jisx0201.1976-0")) {
            jclass = "sun.awt.motif.X11JIS0201";
            // this is mapping the latin supplement range 128->255 which
            // doesn't exist in JIS0201. This needs examination.
            // it was also overwriting a couple of the mappings of
            // 7E and A5 which in JIS201 are different chars than in
            // Latin 1. I have revised AddAscii to not overwrite chars
            // which are already converted.
            addAscii = true;
            lowPartOnly = true;
        } else if (encoding.equals("jisx0212.1990-0")) {
            jclass = "sun.awt.motif.X11JIS0212";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.equals("iso8859-4")) {
            jclass = "ISO8859_4";
        } else if (encoding.equals("iso8859-5")) {
            jclass = "ISO8859_5";
        } else if (encoding.equals("koi8-r")) {
            jclass = "KOI8_R";
        } else if (encoding.equals("ansi-1251")) {
            jclass = "windows-1251";
        } else if (encoding.equals("iso8859-6")) {
            jclass = "ISO8859_6";
        } else if (encoding.equals("iso8859-7")) {
            jclass = "ISO8859_7";
        } else if (encoding.equals("iso8859-8")) {
            jclass = "ISO8859_8";
        } else if (encoding.equals("iso8859-9")) {
            jclass = "ISO8859_9";
        } else if (encoding.equals("iso8859-13")) {
            jclass = "ISO8859_13";
        } else if (encoding.equals("iso8859-15")) {
            jclass = "ISO8859_15";
        } else if (encoding.equals("ksc5601.1987-0")) {
            jclass ="sun.awt.motif.X11KSC5601";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.equals( "ksc5601.1992-3")) {
            jclass ="sun.awt.motif.X11Johab";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.equals( "ksc5601.1987-1")) {
            jclass ="EUC_KR";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.equals( "cns11643-1")) {
            jclass = "sun.awt.motif.X11CNS11643P1";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.equals("cns11643-2")) {
            jclass = "sun.awt.motif.X11CNS11643P2";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.equals("cns11643-3")) {
            jclass = "sun.awt.motif.X11CNS11643P3";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.equals("gb2312.1980-0")) {
            jclass = "sun.awt.motif.X11GB2312";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.indexOf("big5") >= 0) {
            jclass = "Big5";
            nBytes = DOUBLE_BYTE;
            addAscii = true;
        } else if (encoding.equals("tis620.2533-0")) {
            jclass = "TIS620";
        } else if (encoding.equals("gbk-0")) {
            jclass = "sun.awt.motif.X11GBK";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.indexOf("sun.unicode-0") >= 0) {
            jclass = "sun.awt.motif.X11SunUnicode_0";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.indexOf("gb18030.2000-1") >= 0) {
            jclass = "sun.awt.motif.X11GB18030_1";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.indexOf( "gb18030.2000-0") >= 0) {
            jclass = "sun.awt.motif.X11GB18030_0";
            nBytes = DOUBLE_BYTE;
        } else if (encoding.indexOf("hkscs") >= 0) {
            jclass = "sun.awt.HKSCS";
            nBytes = DOUBLE_BYTE;
        }
        return new XMap(jclass, minU, maxU, nBytes, addAscii, lowPartOnly);
    }

    private static final char SURR_MIN = '\uD800';
    private static final char SURR_MAX = '\uDFFF';

    private XMap(String className, int minU, int maxU, int nBytes,
                 boolean addAscii, boolean lowPartOnly) {

        CharsetEncoder enc = null;
        if (className != null) {
            try {
                if (className.startsWith("sun.awt")) {
                    enc = ((Charset)Class.forName(className).newInstance()).newEncoder();
                } else {
                    enc = Charset.forName(className).newEncoder();
                }
            } catch (Exception x) {x.printStackTrace();}
        }
        if (enc == null) {
            convertedGlyphs = new char[256];
            for (int i=0; i<256; i++) {
                convertedGlyphs[i] = (char)i;
            }
            return;
        } else {
            /* chars is set to the unicode values to convert,
             * bytes is where the X11 character codes will be output.
             * Finally we pack the byte pairs into chars.
             */
            int count = maxU - minU + 1;
            byte[] bytes = new byte[count*nBytes];
            char[] chars  = new char[count];
            for (int i=0; i<count; i++) {
                chars[i] = (char)(minU+i);
            }
            int startCharIndex = 0;
            /* For multi-byte encodings, single byte chars should be skipped */
            if (nBytes > SINGLE_BYTE && minU < 256) {
                startCharIndex = 256-minU;
            }
            byte[] rbytes = new byte[nBytes];
            try {
                int cbLen = 0;
                int bbLen = 0;
                // Since we dont support surrogates in any X11 encoding, skip
                // the surrogate area, otherwise the sequence of "Oxdbff0xdc00"
                // will accidently cause the surrogate-aware nio charset to treat
                // them as a legal pair and then undesirablly skip 2 "chars"
                // for one "unmappable character"
                if (startCharIndex < SURR_MIN && startCharIndex + count >SURR_MAX) {
                    cbLen = SURR_MIN - startCharIndex;
                    bbLen = cbLen * nBytes;
                    enc.onMalformedInput(CodingErrorAction.REPLACE)
                        .onUnmappableCharacter(CodingErrorAction.REPLACE)
                        .replaceWith(rbytes)
                        .encode(CharBuffer.wrap(chars, startCharIndex, cbLen),
                                ByteBuffer.wrap(bytes, startCharIndex * nBytes, bbLen),
                                true);
                    startCharIndex = SURR_MAX + 1;
                }
                cbLen = count - startCharIndex;
                bbLen = cbLen * nBytes;
                enc.onMalformedInput(CodingErrorAction.REPLACE)
                    .onUnmappableCharacter(CodingErrorAction.REPLACE)
                    .replaceWith(rbytes)
                    .encode(CharBuffer.wrap(chars, startCharIndex, cbLen),
                            ByteBuffer.wrap(bytes, startCharIndex * nBytes, bbLen),
                            true);
            } catch (Exception e) { e.printStackTrace();}

            convertedGlyphs = new char[65536];
            for (int i=0; i<count; i++) {
                if (nBytes == 1) {
                    convertedGlyphs[i+minU] = (char)(bytes[i]&0xff);
                } else {
                    convertedGlyphs[i+minU] =
                        (char)(((bytes[i*2]&0xff) << 8) + (bytes[i*2+1]&0xff));
                }
            }
        }

        int max = (lowPartOnly) ? 128 : 256;
        if (addAscii && convertedGlyphs.length >= 256) {
            for (int i=0;i<max;i++) {
                if (convertedGlyphs[i] == 0) {
                    convertedGlyphs[i] = (char)i;
                }
            }
        }
    }
}
