// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 2006-2008, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.charset;

/**
 * Defines the UConverterSharedData struct, the immutable, shared part of
 * UConverter.
 */
final class UConverterSharedData {
    // agljport:todo const void *dataMemory; /* from udata_openChoice() - for cleanup */
    // agljport:todo void *table; /* Unused. This used to be a UConverterTable - Pointer to conversion data - see mbcs below */

    // const UConverterStaticData *staticData; /* pointer to the static (non changing) data. */
    /**
     * pointer to the static (non changing)
     * data.
     */
    final UConverterStaticData staticData;

    // const UConverterImpl *impl; /* vtable-style struct of mostly function pointers */
    // UConverterImpl impl; /* vtable-style struct of mostly function pointers */
    /** initial values of some members of the mutable part of object */

    /**
     * Shared data structures currently come in two flavors:
     * - readonly for built-in algorithmic converters
     * - allocated for MBCS, with a pointer to an allocated UConverterTable
     *   which always has a UConverterMBCSTable
     *   
     * To eliminate one allocation, I am making the UConverterMBCSTable a member
     * of the shared data. It is the last member so that static definitions of
     * UConverterSharedData work as before. The table field above also remains
     * to avoid updating all static definitions, but is now unused.
     * 
     */
    CharsetMBCS.UConverterMBCSTable mbcs;

    UConverterSharedData(UConverterStaticData staticData_)
    {
        mbcs = new CharsetMBCS.UConverterMBCSTable();
        staticData = staticData_;
    }

    /**
     * UConverterImpl contains all the data and functions for a converter type.
     * Its function pointers work much like a C++ vtable. Many converter types
     * need to define only a subset of the functions; when a function pointer is
     * NULL, then a default action will be performed.
     * 
     * Every converter type must implement toUnicode, fromUnicode, and
     * getNextUChar, otherwise the converter may crash. Every converter type
     * that has variable-length codepage sequences should also implement
     * toUnicodeWithOffsets and fromUnicodeWithOffsets for correct offset
     * handling. All other functions may or may not be implemented - it depends
     * only on whether the converter type needs them.
     * 
     * When open() fails, then close() will be called, if present.
     */
/* class UConverterImpl {
    UConverterType type;
    UConverterToUnicode toUnicode;
    protected void doToUnicode(UConverterToUnicodeArgs args, int[] pErrorCode)
    {
    }
    
     final void toUnicode(UConverterToUnicodeArgs args, int[] pErrorCode)
    {
        doToUnicode(args, pErrorCode);
    }
    
    //UConverterFromUnicode fromUnicode;
    protected void doFromUnicode(UConverterFromUnicodeArgs args, int[] pErrorCode)
    {
    }
    
     final void fromUnicode(UConverterFromUnicodeArgs args, int[] pErrorCode)
    {
        doFromUnicode(args, pErrorCode);
    }
    
    protected int doGetNextUChar(UConverterToUnicodeArgs args, int[] pErrorCode)
    {
        return 0;
    }
    
    //UConverterGetNextUChar getNextUChar;
     final int getNextUChar(UConverterToUnicodeArgs args, int[] pErrorCode)
    {
        return doGetNextUChar(args, pErrorCode);
    }
    
    // interface UConverterImplLoadable extends UConverterImpl
    protected void doLoad(UConverterLoadArgs pArgs, short[] raw, int[] pErrorCode)
    {
    }
    
    protected void doUnload()
    {
    }

    // interface UConverterImplOpenable extends UConverterImpl
    protected void doOpen(UConverter cnv, String name, String locale, long options, int[] pErrorCode)
    {
    }
    
    //UConverterOpen open;
     final void open(UConverter cnv, String name, String locale, long options, int[] pErrorCode)
    {
        doOpen(cnv, name, locale, options, pErrorCode);
    }
    
    protected void doClose(UConverter cnv)
    {
    }
    
    //UConverterClose close;
     final void close(UConverter cnv)
    {
        doClose(cnv);
    }
    
    protected void doReset(UConverter cnv, int choice)
    {
    }
    
    //typedef void (*UConverterReset) (UConverter *cnv, UConverterResetChoice choice);
    //UConverterReset reset;
     final void reset(UConverter cnv, int choice)
    {
        doReset(cnv, choice);
    }

    // interface UConverterImplVariableLength extends UConverterImpl
    protected void doToUnicodeWithOffsets(UConverterToUnicodeArgs args, int[] pErrorCode)
    {
    }
    
    //UConverterToUnicode toUnicodeWithOffsets;
     final void toUnicodeWithOffsets(UConverterToUnicodeArgs args, int[] pErrorCode)
    {
        doToUnicodeWithOffsets(args, pErrorCode);
    }
    
    protected void doFromUnicodeWithOffsets(UConverterFromUnicodeArgs args, int[] pErrorCode)
    {
    }
    
    //UConverterFromUnicode fromUnicodeWithOffsets;
     final void fromUnicodeWithOffsets(UConverterFromUnicodeArgs args, int[] pErrorCode)
    {
        doFromUnicodeWithOffsets(args, pErrorCode);
    }

    // interface UConverterImplMisc extends UConverterImpl
    protected void doGetStarters(UConverter converter, boolean starters[], int[] pErrorCode)
    {
    }
    
    //UConverterGetStarters getStarters;
     final void getStarters(UConverter converter, boolean starters[], int[] pErrorCode)
    {
        doGetStarters(converter, starters, pErrorCode);
    }
    
    protected String doGetName(UConverter cnv)
    {
        return "";
    }
    
    //UConverterGetName getName;
     final String getName(UConverter cnv)
    {
        return doGetName(cnv);
    }
    
    protected void doWriteSub(UConverterFromUnicodeArgs pArgs, long offsetIndex, int[] pErrorCode)
    {
    }
    
    //UConverterWriteSub writeSub;
     final void writeSub(UConverterFromUnicodeArgs pArgs, long offsetIndex, int[] pErrorCode)
    {
        doWriteSub(pArgs, offsetIndex, pErrorCode);
    }
    
    protected UConverter doSafeClone(UConverter cnv, byte[] stackBuffer, int[] pBufferSize, int[] status)
    {
        return new UConverter();
    }

    //UConverterSafeClone safeClone;
     final UConverter  safeClone(UConverter cnv, byte[] stackBuffer, int[] pBufferSize, int[] status)
    {
        return doSafeClone(cnv, stackBuffer, pBufferSize, status);
    }
    
    protected void doGetUnicodeSet(UConverter cnv, UnicodeSet /*USetAdder* / sa, int /*UConverterUnicodeSet* / which, int[] pErrorCode)
    {
    }
    
    //UConverterGetUnicodeSet getUnicodeSet;
    // final void getUnicodeSet(UConverter cnv, UnicodeSet /*USetAdder* / sa, int /*UConverterUnicodeSet* / which, int[] pErrorCode)
    //{
    //  doGetUnicodeSet(cnv, sa, which, pErrorCode);
    //}

    //}

    static final String DATA_TYPE = "cnv";
    private static final int CNV_DATA_BUFFER_SIZE = 25000;
     static final int sizeofUConverterSharedData = 100;
    
    //static UDataMemoryIsAcceptable isCnvAcceptable;

    /**
     * Load a non-algorithmic converter.
     * If pkg==NULL, then this function must be called inside umtx_lock(&cnvCacheMutex).
     
    // UConverterSharedData * load(UConverterLoadArgs *pArgs, UErrorCode *err)
     static final UConverterSharedData load(UConverterLoadArgs pArgs, int[] err)
    {
        UConverterSharedData mySharedConverterData = null;
    
        if(err == null || ErrorCode.isFailure(err[0])) {
            return null;
        }
    
        if(pArgs.pkg != null && pArgs.pkg.length() != 0) {
             application-provided converters are not currently cached 
            return UConverterSharedData.createConverterFromFile(pArgs, err);
        }
    
        //agljport:fix mySharedConverterData = getSharedConverterData(pArgs.name);
        if (mySharedConverterData == null)
        {
            Not cached, we need to stream it in from file 
            mySharedConverterData = UConverterSharedData.createConverterFromFile(pArgs, err);
            if (ErrorCode.isFailure(err[0]) || (mySharedConverterData == null))
            {
                return null;
            }
            else
            {
                 share it with other library clients 
                //agljport:fix shareConverterData(mySharedConverterData);
            }
        }
        else
        {
             The data for this converter was already in the cache.            
             Update the reference counter on the shared data: one more client 
            mySharedConverterData.referenceCounter++;
        }
    
        return mySharedConverterData;
    }
    
    Takes an alias name gets an actual converter file name
     *goes to disk and opens it.
     *allocates the memory and returns a new UConverter object
     
    //static UConverterSharedData *createConverterFromFile(UConverterLoadArgs *pArgs, UErrorCode * err)
     static final UConverterSharedData createConverterFromFile(UConverterLoadArgs pArgs, int[] err)
    {
        UDataMemory data = null;
        UConverterSharedData sharedData = null;
    
        //agljport:todo UTRACE_ENTRY_OC(UTRACE_LOAD);
    
        if (err == null || ErrorCode.isFailure(err[0])) {
            //agljport:todo UTRACE_EXIT_STATUS(*err);
            return null;
        }
    
        //agljport:todo UTRACE_DATA2(UTRACE_OPEN_CLOSE, "load converter %s from package %s", pArgs->name, pArgs->pkg);
    
        //agljport:fix data = udata_openChoice(pArgs.pkgArray, DATA_TYPE.getBytes(), pArgs.name, isCnvAcceptable, null, err);
        if(ErrorCode.isFailure(err[0]))
        {
            //agljport:todo UTRACE_EXIT_STATUS(*err);
            return null;
        }
    
        sharedData = data_unFlattenClone(pArgs, data, err);
        if(ErrorCode.isFailure(err[0]))
        {
            //agljport:fix udata_close(data);
            //agljport:todo UTRACE_EXIT_STATUS(*err);
            return null;
        }
    
        
         * TODO Store pkg in a field in the shared data so that delta-only converters
         * can load base converters from the same package.
         * If the pkg name is longer than the field, then either do not load the converter
         * in the first place, or just set the pkg field to "".
         
    
        return sharedData;
    }
*/

    /*
     * returns a converter type from a string
     */
    /*   static final UConverterSharedData getAlgorithmicTypeFromName(String realName)
    {
        long mid, start, limit;
        long lastMid;
        int result;
        StringBuffer strippedName = new StringBuffer(UConverterConstants.MAX_CONVERTER_NAME_LENGTH);
    
        // Lower case and remove ignoreable characters.
        UConverterAlias.stripForCompare(strippedName, realName);
    
        // do a binary search for the alias
        start = 0;
        limit = cnvNameType.length;
        mid = limit;
        lastMid = -1;
    
        for (;;) {
            mid = (long)((start + limit) / 2);
            if (lastMid == mid) {   // Have we moved?
                break;  // We haven't moved, and it wasn't found.
            }
            lastMid = mid;
            result = strippedName.substring(0).compareTo(cnvNameType[(int)mid].name);
    
            if (result < 0) {
                limit = mid;
            } else if (result > 0) {
                start = mid;
            } else {
                return converterData[cnvNameType[(int)mid].type];
            }
        }
    
        return null;
    }*/
    
    /*
     * Enum for specifying basic types of converters
     */
    static final class UConverterType {
        static final int UNSUPPORTED_CONVERTER = -1;
        static final int SBCS = 0;
        static final int DBCS = 1;
        static final int MBCS = 2;
        static final int LATIN_1 = 3;
        static final int UTF8 = 4;
        static final int UTF16_BigEndian = 5;
        static final int UTF16_LittleEndian = 6;
        static final int UTF32_BigEndian = 7;
        static final int UTF32_LittleEndian = 8;
        static final int EBCDIC_STATEFUL = 9;
        static final int ISO_2022 = 10;
        static final int LMBCS_1 = 11;
        static final int LMBCS_2 = LMBCS_1 + 1; // 12
        static final int LMBCS_3 = LMBCS_2 + 1; // 13
        static final int LMBCS_4 = LMBCS_3 + 1; // 14
        static final int LMBCS_5 = LMBCS_4 + 1; // 15
        static final int LMBCS_6 = LMBCS_5 + 1; // 16
        static final int LMBCS_8 = LMBCS_6 + 1; // 17
        static final int LMBCS_11 = LMBCS_8 + 1; // 18
        static final int LMBCS_16 = LMBCS_11 + 1; // 19
        static final int LMBCS_17 = LMBCS_16 + 1; // 20
        static final int LMBCS_18 = LMBCS_17 + 1; // 21
        static final int LMBCS_19 = LMBCS_18 + 1; // 22
        static final int LMBCS_LAST = LMBCS_19; // 22
        static final int HZ = LMBCS_LAST + 1; // 23
        static final int SCSU = HZ + 1; // 24
        static final int ISCII = SCSU + 1; // 25
        static final int US_ASCII = ISCII + 1; // 26
        static final int UTF7 = US_ASCII + 1; // 27
        static final int BOCU1 = UTF7 + 1; // 28
        static final int UTF16 = BOCU1 + 1; // 29
        static final int UTF32 = UTF16 + 1; // 30
        static final int CESU8 = UTF32 + 1; // 31
        static final int IMAP_MAILBOX = CESU8 + 1; // 32

        // Number of converter types for which we have conversion routines.
        static final int NUMBER_OF_SUPPORTED_CONVERTER_TYPES = IMAP_MAILBOX + 1;
    }

    /**
     * Enum for specifying which platform a converter ID refers to. The use of
     * platform/CCSID is not recommended. See openCCSID().
     */
    static final class UConverterPlatform {
        static final int UNKNOWN = -1;
        static final int IBM = 0;
    }

    // static UConverterSharedData[] converterData;
    /*  static class cnvNameTypeClass {
      String name;
        int type;
        cnvNameTypeClass(String name_, int type_) { name = name_; type = type_; }
    } 
    
    static cnvNameTypeClass cnvNameType[];*/


    static final String DATA_TYPE = "cnv";
    //static final int CNV_DATA_BUFFER_SIZE = 25000;
    //static final int SIZE_OF_UCONVERTER_SHARED_DATA = 228;

}
