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

#include "unicode/utypes.h"
#include "unicode/uset.h"
#include "unicode/udata.h" /* UDataInfo */
#include "ucmndata.h" /* DataHeader */
#include "udatamem.h"
#include "uassert.h"
#include "cmemory.h"
#include "utrie2.h"
#include "ubidi_props.h"
#include "ucln_cmn.h"

struct UBiDiProps {
    UDataMemory *mem;
    const int32_t *indexes;
    const uint32_t *mirrors;
    const uint8_t *jgArray;
    const uint8_t *jgArray2;

    UTrie2 trie;
    uint8_t formatVersion[4];
};

/* ubidi_props_data.h is machine-generated by genbidi --csource */
#define INCLUDED_FROM_UBIDI_PROPS_C
#include "ubidi_props_data.h"

/* UBiDiProps singleton ----------------------------------------------------- */

U_CFUNC const UBiDiProps *
ubidi_getSingleton() {
    return &ubidi_props_singleton;
}

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

static UBool U_CALLCONV
_enumPropertyStartsRange(const void *context, UChar32 start, UChar32 end, uint32_t value) {
    /* add the start code point to the USet */
    const USetAdder *sa=(const USetAdder *)context;
    sa->add(sa->set, start);
    return TRUE;
}

U_CFUNC void
ubidi_addPropertyStarts(const UBiDiProps *bdp, const USetAdder *sa, UErrorCode *pErrorCode) {
    int32_t i, length;
    UChar32 c, start, limit;

    const uint8_t *jgArray;
    uint8_t prev, jg;

    if(U_FAILURE(*pErrorCode)) {
        return;
    }

    /* add the start code point of each same-value range of the trie */
    utrie2_enum(&bdp->trie, NULL, _enumPropertyStartsRange, sa);

    /* add the code points from the bidi mirroring table */
    length=bdp->indexes[UBIDI_IX_MIRROR_LENGTH];
    for(i=0; i<length; ++i) {
        c=UBIDI_GET_MIRROR_CODE_POINT(bdp->mirrors[i]);
        sa->addRange(sa->set, c, c+1);
    }

    /* add the code points from the Joining_Group array where the value changes */
    start=bdp->indexes[UBIDI_IX_JG_START];
    limit=bdp->indexes[UBIDI_IX_JG_LIMIT];
    jgArray=bdp->jgArray;
    for(;;) {
        prev=0;
        while(start<limit) {
            jg=*jgArray++;
            if(jg!=prev) {
                sa->add(sa->set, start);
                prev=jg;
            }
            ++start;
        }
        if(prev!=0) {
            /* add the limit code point if the last value was not 0 (it is now start==limit) */
            sa->add(sa->set, limit);
        }
        if(limit==bdp->indexes[UBIDI_IX_JG_LIMIT]) {
            /* switch to the second Joining_Group range */
            start=bdp->indexes[UBIDI_IX_JG_START2];
            limit=bdp->indexes[UBIDI_IX_JG_LIMIT2];
            jgArray=bdp->jgArray2;
        } else {
            break;
        }
    }

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

    /* (none right now) */
}

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

U_CFUNC int32_t
ubidi_getMaxValue(const UBiDiProps *bdp, UProperty which) {
    int32_t max;

    if(bdp==NULL) {
        return -1;
    }

    max=bdp->indexes[UBIDI_MAX_VALUES_INDEX];
    switch(which) {
    case UCHAR_BIDI_CLASS:
        return (max&UBIDI_CLASS_MASK);
    case UCHAR_JOINING_GROUP:
        return (max&UBIDI_MAX_JG_MASK)>>UBIDI_MAX_JG_SHIFT;
    case UCHAR_JOINING_TYPE:
        return (max&UBIDI_JT_MASK)>>UBIDI_JT_SHIFT;
    case UCHAR_BIDI_PAIRED_BRACKET_TYPE:
        return (max&UBIDI_BPT_MASK)>>UBIDI_BPT_SHIFT;
    default:
        return -1; /* undefined */
    }
}

U_CAPI UCharDirection
ubidi_getClass(const UBiDiProps *bdp, UChar32 c) {
    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
    return (UCharDirection)UBIDI_GET_CLASS(props);
}

U_CFUNC UBool
ubidi_isMirrored(const UBiDiProps *bdp, UChar32 c) {
    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
    return (UBool)UBIDI_GET_FLAG(props, UBIDI_IS_MIRRORED_SHIFT);
}

static UChar32
getMirror(const UBiDiProps *bdp, UChar32 c, uint16_t props) {
    int32_t delta=UBIDI_GET_MIRROR_DELTA(props);
    if(delta!=UBIDI_ESC_MIRROR_DELTA) {
        return c+delta;
    } else {
        /* look for mirror code point in the mirrors[] table */
        const uint32_t *mirrors;
        uint32_t m;
        int32_t i, length;
        UChar32 c2;

        mirrors=bdp->mirrors;
        length=bdp->indexes[UBIDI_IX_MIRROR_LENGTH];

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

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

U_CFUNC UChar32
ubidi_getMirror(const UBiDiProps *bdp, UChar32 c) {
    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
    return getMirror(bdp, c, props);
}

U_CFUNC UBool
ubidi_isBidiControl(const UBiDiProps *bdp, UChar32 c) {
    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
    return (UBool)UBIDI_GET_FLAG(props, UBIDI_BIDI_CONTROL_SHIFT);
}

U_CFUNC UBool
ubidi_isJoinControl(const UBiDiProps *bdp, UChar32 c) {
    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
    return (UBool)UBIDI_GET_FLAG(props, UBIDI_JOIN_CONTROL_SHIFT);
}

U_CFUNC UJoiningType
ubidi_getJoiningType(const UBiDiProps *bdp, UChar32 c) {
    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
    return (UJoiningType)((props&UBIDI_JT_MASK)>>UBIDI_JT_SHIFT);
}

U_CFUNC UJoiningGroup
ubidi_getJoiningGroup(const UBiDiProps *bdp, UChar32 c) {
    UChar32 start, limit;

    start=bdp->indexes[UBIDI_IX_JG_START];
    limit=bdp->indexes[UBIDI_IX_JG_LIMIT];
    if(start<=c && c<limit) {
        return (UJoiningGroup)bdp->jgArray[c-start];
    }
    start=bdp->indexes[UBIDI_IX_JG_START2];
    limit=bdp->indexes[UBIDI_IX_JG_LIMIT2];
    if(start<=c && c<limit) {
        return (UJoiningGroup)bdp->jgArray2[c-start];
    }
    return U_JG_NO_JOINING_GROUP;
}

U_CFUNC UBidiPairedBracketType
ubidi_getPairedBracketType(const UBiDiProps *bdp, UChar32 c) {
    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
    return (UBidiPairedBracketType)((props&UBIDI_BPT_MASK)>>UBIDI_BPT_SHIFT);
}

U_CFUNC UChar32
ubidi_getPairedBracket(const UBiDiProps *bdp, UChar32 c) {
    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
    if((props&UBIDI_BPT_MASK)==0) {
        return c;
    } else {
        return getMirror(bdp, c, props);
    }
}

/* public API (see uchar.h) ------------------------------------------------- */

U_CFUNC UCharDirection
u_charDirection(UChar32 c) {   
    return ubidi_getClass(&ubidi_props_singleton, c);
}

U_CFUNC UBool
u_isMirrored(UChar32 c) {
    return ubidi_isMirrored(&ubidi_props_singleton, c);
}

U_CFUNC UChar32
u_charMirror(UChar32 c) {
    return ubidi_getMirror(&ubidi_props_singleton, c);
}

U_STABLE UChar32 U_EXPORT2
u_getBidiPairedBracket(UChar32 c) {
    return ubidi_getPairedBracket(&ubidi_props_singleton, c);
}
