// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 *   Copyright (C) 2002-2010, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
*/

package com.ibm.icu.impl;
/**
 * @version     1.1
 * @author     Markus W. Scherer
 * Ram: Add documentation, remove unwanted methods, improve coverage.
 */

/**
 * Simple class for handling serialized USet/UnicodeSet structures
 * without object creation. See ICU4C icu/source/common/uset.c.
 *
 * @internal
 */
public final class USerializedSet {
    /**
     * Fill in the given serialized set object.
     * @param src pointer to start of array
     * @param srcStart pointer to start of serialized data (length value)
     * @return true if the given array is valid, otherwise false
     */
    public final boolean getSet(char src[], int srcStart) {
        // leave most argument checking up to Java exceptions
        array=null;
        arrayOffset=bmpLength=length=0;

        length=src[srcStart++];
        
        if ((length&0x8000) != 0) {
            /* there are supplementary values */
            length&=0x7fff;
            if(src.length<(srcStart+1+length)) {
                length=0;
                throw new IndexOutOfBoundsException();
            }
            bmpLength=src[srcStart++];
        } else {
            /* only BMP values */
            if(src.length<(srcStart+length)) {
                length=0;
                throw new IndexOutOfBoundsException();
            }
            bmpLength=length;
        }
        array = new char[length];
        System.arraycopy(src,srcStart,array,0,length);
        //arrayOffset=srcStart;
        return true;
    }
    
    /**
     * Set the USerializedSet to contain the given character (and nothing
     * else).
     */
    public final void setToOne(int c) {
        if( 0x10ffff<c) {
            return;
        }

        if(c<0xffff) {
            bmpLength=length=2;
            array[0]=(char)c;
            array[1]=(char)(c+1);
        } else if(c==0xffff) {
            bmpLength=1;
            length=3;
            array[0]=0xffff;
            array[1]=1;
            array[2]=0;
        } else if(c<0x10ffff) {
            bmpLength=0;
            length=4;
            array[0]=(char)(c>>16);
            array[1]=(char)c;
            ++c;
            array[2]=(char)(c>>16);
            array[3]=(char)c;
        } else /* c==0x10ffff */ {
            bmpLength=0;
            length=2;
            array[0]=0x10;
            array[1]=0xffff;
        }
    }
        
    /**
     * Returns a range of characters contained in the given serialized
     * set.
     * @param rangeIndex a non-negative integer in the range <code>0..
     * getSerializedRangeCount()-1</code>
     * @param range variable to receive the data in the range
     * @return true if rangeIndex is valid, otherwise false
     */
    public final boolean getRange(int rangeIndex, int[] range) {
        if( rangeIndex<0) {
            return false;
        }
        if(array==null){
            array = new char[8];
        }
        if(range==null || range.length <2){
            throw new IllegalArgumentException();
        }
        rangeIndex*=2; /* address start/limit pairs */
        if(rangeIndex<bmpLength) {
            range[0]=array[rangeIndex++];
            if(rangeIndex<bmpLength) {
                range[1]=array[rangeIndex]-1;
            } else if(rangeIndex<length) {
                range[1]=((((int)array[rangeIndex])<<16)|array[rangeIndex+1])-1;
            } else {
                range[1]=0x10ffff;
            }
            return true;
        } else {
            rangeIndex-=bmpLength;
            rangeIndex*=2; /* address pairs of pairs of units */
            int suppLength=length-bmpLength;
            if(rangeIndex<suppLength) {
                int offset=arrayOffset+bmpLength;
                range[0]=(((int)array[offset+rangeIndex])<<16)|array[offset+rangeIndex+1];
                rangeIndex+=2;
                if(rangeIndex<suppLength) {
                    range[1]=((((int)array[offset+rangeIndex])<<16)|array[offset+rangeIndex+1])-1;
                } else {
                    range[1]=0x10ffff;
                }
                return true;
            } else {
                return false;
            }
        }
    }
    
    /**
     * Returns true if the given USerializedSet contains the given
     * character.
     * @param c the character to test for
     * @return true if set contains c
     */
    public final boolean contains(int c) {
        
        if(c>0x10ffff) {
            return false;
        }
            
        if(c<=0xffff) {
            int i;
            /* find c in the BMP part */
            for(i=0; i<bmpLength && (char)c>=array[i]; ++i) {}
            return ((i&1) != 0);
        } else {
            int i;
            /* find c in the supplementary part */
            char high=(char)(c>>16), low=(char)c;
            for(i=bmpLength;
                i<length && (high>array[i] || (high==array[i] && low>=array[i+1]));
                i+=2) {}
        
            /* count pairs of 16-bit units even per BMP and check if the number of pairs is odd */
            return (((i+bmpLength)&2)!=0);
        }
    }

    /**
     * Returns the number of disjoint ranges of characters contained in
     * the given serialized set.  Ignores any strings contained in the
     * set.
     * @return a non-negative integer counting the character ranges
     * contained in set
     */
    public final int countRanges() {
        return (bmpLength+(length-bmpLength)/2+1)/2;
    }
    
    private char array[] = new char[8];
    private int arrayOffset, bmpLength, length;
}
