/*
*******************************************************************************
*
*   Copyright (C) 2004-2005, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*   file name:  UBiDiProps.java
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2005jan16
*   created by: Markus W. Scherer
*
*   Low-level Unicode bidi/shaping properties access.
*   Java port of ubidi_props.h/.c.
*/

package com.ibm.icu.impl;

import java.io.InputStream;
import java.io.DataInputStream;
import java.io.BufferedInputStream;
import java.io.IOException;

import com.ibm.icu.util.VersionInfo;
import com.ibm.icu.util.RangeValueIterator;

import com.ibm.icu.text.UnicodeSet;

import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UProperty;

public final class UBiDiProps {
    // constructors etc. --------------------------------------------------- ***

    // port of ubidi_openProps()
    public UBiDiProps() throws IOException {
        InputStream is=ICUData.getRequiredStream(ICUResourceBundle.ICU_BUNDLE+"/"+DATA_FILE_NAME);
        BufferedInputStream b=new BufferedInputStream(is, 4096 /* data buffer size */);
        readData(b);
        b.close();
        is.close();
    }

    private void readData(InputStream is) throws IOException {
        DataInputStream inputStream=new DataInputStream(is);

        // read the header
        unicodeVersion=ICUBinary.readHeader(inputStream, FMT, new IsAcceptable());

        // read indexes[]
        int i, count;
        count=inputStream.readInt();
        if(count<IX_INDEX_TOP) {
            throw new IOException("indexes[0] too small in "+DATA_FILE_NAME);
        }
        indexes=new int[count];

        indexes[0]=count;
        for(i=1; i<count; ++i) {
            indexes[i]=inputStream.readInt();
        }

        // read the trie
        trie=new CharTrie(inputStream, null);

        // read mirrors[]
        count=indexes[IX_MIRROR_LENGTH];
        if(count>0) {
            mirrors=new int[count];
            for(i=0; i<count; ++i) {
                mirrors[i]=inputStream.readInt();
            }
        }

        // read jgArray[]
        count=indexes[IX_JG_LIMIT]-indexes[IX_JG_START];
        jgArray=new byte[count];
        for(i=0; i<count; ++i) {
            jgArray[i]=inputStream.readByte();
        }
    }

    // implement ICUBinary.Authenticate
    private final class IsAcceptable implements ICUBinary.Authenticate {
        public boolean isDataVersionAcceptable(byte version[]) {
            formatVersion=version;
            return version[0]==1 &&
                   version[2]==Trie.INDEX_STAGE_1_SHIFT_ && version[3]==Trie.INDEX_STAGE_2_SHIFT_;
        }
    }

    // UBiDiProps singleton
    private static UBiDiProps gBdp=null;

    // port of ubidi_getSingleton()
    public static final synchronized UBiDiProps getSingleton() throws IOException {
        if(gBdp==null) {
            gBdp=new UBiDiProps();
        }
        return gBdp;
    }

    // UBiDiProps dummy singleton
    private static UBiDiProps gBdpDummy=null;

    private UBiDiProps(boolean makeDummy) { // ignore makeDummy, only creates a unique signature
        formatVersion=new byte[] { 1, 0, Trie.INDEX_STAGE_1_SHIFT_, Trie.INDEX_STAGE_2_SHIFT_ };
        unicodeVersion=new byte[] { 2, 0, 0, 0 };
        indexes=new int[IX_TOP];
        indexes[0]=IX_TOP;
        trie=new CharTrie(0, 0, null); // dummy trie, always returns 0
    }

    /**
     * Get a singleton dummy object, one that works with no real data.
     * This can be used when the real data is not available.
     * Using the dummy can reduce checks for available data after an initial failure.
     * Port of ucase_getDummy().
     */
    public static final synchronized UBiDiProps getDummy() {
        if(gBdpDummy==null) {
            gBdpDummy=new UBiDiProps(true);
        }
        return gBdpDummy;
    }

    // set of property starts for UnicodeSet ------------------------------- ***

    public final void addPropertyStarts(UnicodeSet set) {
        int i, length;
        int c, start, limit;

        byte prev, jg;

        /* add the start code point of each same-value range of the trie */
        TrieIterator iter=new TrieIterator(trie);
        RangeValueIterator.Element element=new RangeValueIterator.Element();

        while(iter.next(element)){
            set.add(element.start);
        }

        /* add the code points from the bidi mirroring table */
        length=indexes[IX_MIRROR_LENGTH];
        for(i=0; i<length; ++i) {
            c=getMirrorCodePoint(mirrors[i]);
            set.add(c, c+1);
        }

        /* add the code points from the Joining_Group array where the value changes */
        start=indexes[IX_JG_START];
        limit=indexes[IX_JG_LIMIT];
        length=limit-start;
        prev=0;
        for(i=0; i<length; ++i) {
            jg=jgArray[i];
            if(jg!=prev) {
                set.add(start);
                prev=jg;
            }
            ++start;
        }
        if(prev!=0) {
            /* add the limit code point if the last value was not 0 (it is now start==limit) */
            set.add(limit);
        }

        /* add code points with hardcoded properties, plus the ones following them */

        /* (none right now) */
    }

    // property access functions ------------------------------------------- ***

    public final int getMaxValue(int which) {
        int max;

        max=indexes[IX_MAX_VALUES];
        switch(which) {
        case UProperty.BIDI_CLASS:
            return (max&CLASS_MASK);
        case UProperty.JOINING_GROUP:
            return (max&MAX_JG_MASK)>>MAX_JG_SHIFT;
        case UProperty.JOINING_TYPE:
            return (max&JT_MASK)>>JT_SHIFT;
        default:
            return -1; /* undefined */
        }
    }

    public final int getClass(int c) {
        return getClassFromProps(trie.getCodePointValue(c));
    }

    public final boolean isMirrored(int c) {
        return getFlagFromProps(trie.getCodePointValue(c), IS_MIRRORED_SHIFT);
    }

    public final int getMirror(int c) {
        int props;
        int delta;

        props=trie.getCodePointValue(c);
        delta=((short)props)>>MIRROR_DELTA_SHIFT;
        if(delta!=ESC_MIRROR_DELTA) {
            return c+delta;
        } else {
            /* look for mirror code point in the mirrors[] table */
            int m;
            int i, length;
            int c2;

            length=indexes[IX_MIRROR_LENGTH];

            /* linear search */
            for(i=0; i<length; ++i) {
                m=mirrors[i];
                c2=getMirrorCodePoint(m);
                if(c==c2) {
                    /* found c, return its mirror code point using the index in m */
                    return getMirrorCodePoint(mirrors[getMirrorIndex(m)]);
                } else if(c<c2) {
                    break;
                }
            }

            /* c not found, return it itself */
            return c;
        }
    }

    public final boolean isBidiControl(int c) {
        return getFlagFromProps(trie.getCodePointValue(c), BIDI_CONTROL_SHIFT);
    }

    public final boolean isJoinControl(int c) {
        return getFlagFromProps(trie.getCodePointValue(c), JOIN_CONTROL_SHIFT);
    }

    public final int getJoiningType(int c) {
        return (trie.getCodePointValue(c)&JT_MASK)>>JT_SHIFT;
    }

    public final int getJoiningGroup(int c) {
        int start, limit;

        start=indexes[IX_JG_START];
        limit=indexes[IX_JG_LIMIT];
        if(start<=c && c<limit) {
            return (int)jgArray[c-start]&0xff;
        } else {
            return UCharacter.JoiningGroup.NO_JOINING_GROUP;
        }
    }

    // data members -------------------------------------------------------- ***
    private int indexes[];
    private int mirrors[];
    private byte jgArray[];

    private CharTrie trie;
    private byte formatVersion[];
    private byte unicodeVersion[];  

    // data format constants ----------------------------------------------- ***
    private static final String DATA_NAME="ubidi";
    private static final String DATA_TYPE="icu";
    private static final String DATA_FILE_NAME=DATA_NAME+"."+DATA_TYPE;

    /* format "BiDi" */
    private static final byte FMT[]={ 0x42, 0x69, 0x44, 0x69 };

    /* indexes into indexes[] */
    private static final int IX_INDEX_TOP=0;
    private static final int IX_LENGTH=1;
    private static final int IX_TRIE_SIZE=2;
    private static final int IX_MIRROR_LENGTH=3;

    private static final int IX_JG_START=4;
    private static final int IX_JG_LIMIT=5;

    private static final int IX_MAX_VALUES=15;
    private static final int IX_TOP=16;

    // definitions for 16-bit bidi/shaping properties word ----------------- ***

                          /* CLASS_SHIFT=0, */     /* bidi class: 5 bits (4..0) */
    private static final int JT_SHIFT=5;           /* joining type: 3 bits (7..5) */

    /* private static final int _SHIFT=8, reserved: 2 bits (9..8) */

    private static final int JOIN_CONTROL_SHIFT=10;
    private static final int BIDI_CONTROL_SHIFT=11;

    private static final int IS_MIRRORED_SHIFT=12;         /* 'is mirrored' */
    private static final int MIRROR_DELTA_SHIFT=13;        /* bidi mirroring delta: 3 bits (15..13) */

    private static final int MAX_JG_SHIFT=16;              /* max JG value in indexes[MAX_VALUES_INDEX] bits 23..16 */

    private static final int CLASS_MASK=    0x0000001f;
    private static final int JT_MASK=       0x000000e0;

    private static final int MAX_JG_MASK=   0x00ff0000;

    private static final int getClassFromProps(int props) {
        return props&CLASS_MASK;
    }
    private static final boolean getFlagFromProps(int props, int shift) {
        return ((props>>shift)&1)!=0;
    }

    private static final int ESC_MIRROR_DELTA=-4;
    private static final int MIN_MIRROR_DELTA=-3;
    private static final int MAX_MIRROR_DELTA=3;

    // definitions for 32-bit mirror table entry --------------------------- ***

    /* the source Unicode code point takes 21 bits (20..0) */
    private static final int MIRROR_INDEX_SHIFT=21;
    private static final int MAX_MIRROR_INDEX=0x7ff;

    private static final int getMirrorCodePoint(int m) {
        return m&0x1fffff;
    }
    private static final int getMirrorIndex(int m) {
        return m>>>MIRROR_INDEX_SHIFT;
    }
}
