/*
 *******************************************************************************
 *
 *   Copyright (C) 2004-2015, 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.IOException;
import java.nio.ByteBuffer;
import java.util.Iterator;

import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UProperty;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.ICUUncheckedIOException;

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

    // port of ubidi_openProps()
    private UBiDiProps() throws IOException{
        ByteBuffer bytes=ICUBinary.getData(DATA_FILE_NAME);
        readData(bytes);
    }

    private void readData(ByteBuffer bytes) throws IOException {
        // read the header
        ICUBinary.readHeader(bytes, FMT, new IsAcceptable());

        // read indexes[]
        int i, count;
        count=bytes.getInt();
        if(count<IX_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]=bytes.getInt();
        }

        // read the trie
        trie=Trie2_16.createFromSerialized(bytes);
        int expectedTrieLength=indexes[IX_TRIE_SIZE];
        int trieLength=trie.getSerializedLength();
        if(trieLength>expectedTrieLength) {
            throw new IOException(DATA_FILE_NAME+": not enough bytes for the trie");
        }
        // skip padding after trie bytes
        ICUBinary.skipBytes(bytes, expectedTrieLength-trieLength);

        // read mirrors[]
        count=indexes[IX_MIRROR_LENGTH];
        if(count>0) {
            mirrors=ICUBinary.getInts(bytes, count, 0);
        }

        // read jgArray[]
        count=indexes[IX_JG_LIMIT]-indexes[IX_JG_START];
        jgArray=new byte[count];
        bytes.get(jgArray);

        // read jgArray2[]
        count=indexes[IX_JG_LIMIT2]-indexes[IX_JG_START2];
        jgArray2=new byte[count];
        bytes.get(jgArray2);
    }

    // implement ICUBinary.Authenticate
    private final static class IsAcceptable implements ICUBinary.Authenticate {
        public boolean isDataVersionAcceptable(byte version[]) {
            return version[0]==2;
        }
    }

    // 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 */
        Iterator<Trie2.Range> trieIterator=trie.iterator();
        Trie2.Range range;
        while(trieIterator.hasNext() && !(range=trieIterator.next()).leadSurrogate) {
            set.add(range.startCodePoint);
        }

        /* 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];
        byte[] jga=jgArray;
        for(;;) {
            length=limit-start;
            prev=0;
            for(i=0; i<length; ++i) {
                jg=jga[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);
            }
            if(limit==indexes[IX_JG_LIMIT]) {
                /* switch to the second Joining_Group range */
                start=indexes[IX_JG_START2];
                limit=indexes[IX_JG_LIMIT2];
                jga=jgArray2;
            } else {
                break;
            }
        }

        /* 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;
        case UProperty.BIDI_PAIRED_BRACKET_TYPE:
            return (max&BPT_MASK)>>BPT_SHIFT;
        default:
            return -1; /* undefined */
        }
    }

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

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

    private final int getMirror(int c, int props) {
        int delta=getMirrorDeltaFromProps(props);
        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 int getMirror(int c) {
        int props=trie.get(c);
        return getMirror(c, props);
    }

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

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

    public final int getJoiningType(int c) {
        return (trie.get(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;
        }
        start=indexes[IX_JG_START2];
        limit=indexes[IX_JG_LIMIT2];
        if(start<=c && c<limit) {
            return (int)jgArray2[c-start]&0xff;
        }
        return UCharacter.JoiningGroup.NO_JOINING_GROUP;
    }

    public final int getPairedBracketType(int c) {
        return (trie.get(c)&BPT_MASK)>>BPT_SHIFT;
    }

    public final int getPairedBracket(int c) {
        int props=trie.get(c);
        if((props&BPT_MASK)==0) {
            return c;
        } else {
            return getMirror(c, props);
        }
    }

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

    private Trie2_16 trie;

    // 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 int FMT=0x42694469;

    /* 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_JG_START2=6;  /* new in format version 2.2, ICU 54 */
    private static final int IX_JG_LIMIT2=7;

    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 BPT_SHIFT=8;          /* Bidi_Paired_Bracket_Type(bpt): 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 BPT_MASK=      0x00000300;

    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 getMirrorDeltaFromProps(int props) {
        return (short)props>>MIRROR_DELTA_SHIFT;
    }

    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;
    }


    /*
     * public singleton instance
     */
    public static final UBiDiProps INSTANCE;

    // This static initializer block must be placed after
    // other static member initialization
    static {
        try {
            INSTANCE = new UBiDiProps();
        } catch (IOException e) {
            throw new ICUUncheckedIOException(e);
        }
    }
}
