/*
 * Unicode Bidirectional Algorithm implementation
 *
 * Copyright 2003 Shachar Shemesh
 * Copyright 2007 Maarten Lankhorst
 * Copyright 2010 CodeWeavers, Aric Stewart
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * Code derived from the modified reference implementation
 * that was found in revision 17 of http://unicode.org/reports/tr9/
 * "Unicode Standard Annex #9: THE BIDIRECTIONAL ALGORITHM"
 *
 * -- Copyright (C) 1999-2005, ASMUS, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of the Unicode data files and any associated documentation (the
 * "Data Files") or Unicode software and any associated documentation (the
 * "Software") to deal in the Data Files or Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, and/or sell copies of the Data Files or Software,
 * and to permit persons to whom the Data Files or Software are furnished
 * to do so, provided that (a) the above copyright notice(s) and this
 * permission notice appear with all copies of the Data Files or Software,
 * (b) both the above copyright notice(s) and this permission notice appear
 * in associated documentation, and (c) there is clear notice in each
 * modified Data File or in the Software as well as in the documentation
 * associated with the Data File(s) or Software that the data or software
 * has been modified.
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
#include "wine/list.h"

#include "dwrite_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(bidi);

extern const unsigned short bidi_bracket_table[];

#define ASSERT(x) do { if (!(x)) FIXME("assert failed: %s\n", #x); } while(0)
#define MAX_DEPTH 125

#define odd(x) ((x) & 1)

/*------------------------------------------------------------------------
    Bidirectional Character Types

    as defined by the Unicode Bidirectional Algorithm Table 3-7.

    Note:

      The list of bidirectional character types here is not grouped the
      same way as the table 3-7, since the numberic values for the types
      are chosen to keep the state and action tables compact.
------------------------------------------------------------------------*/
enum directions
{
    /* input types */
             /* ON MUST be zero, code relies on ON = NI = 0 */
    ON = 0,  /* Other Neutral */
    L,       /* Left Letter */
    R,       /* Right Letter */
    AN,      /* Arabic Number */
    EN,      /* European Number */
    AL,      /* Arabic Letter (Right-to-left) */
    NSM,     /* Non-spacing Mark */
    CS,      /* Common Separator */
    ES,      /* European Separator */
    ET,      /* European Terminator (post/prefix e.g. $ and %) */

    /* resolved types */
    BN,      /* Boundary neutral (type of RLE etc after explicit levels) */

    /* input types, */
    S,       /* Segment Separator (TAB)        // used only in L1 */
    WS,      /* White space                    // used only in L1 */
    B,       /* Paragraph Separator (aka as PS) */

    /* types for explicit controls */
    RLO,     /* these are used only in X1-X9 */
    RLE,
    LRO,
    LRE,
    PDF,

    LRI, /* Isolate formatting characters new with 6.3 */
    RLI,
    FSI,
    PDI,

    /* resolved types, also resolved directions */
    NI = ON,  /* alias, where ON, WS, S  and Isolates are treated the same */
};

static const char debug_type[][4] =
{
    "ON",      /* Other Neutral */
    "L",       /* Left Letter */
    "R",       /* Right Letter */
    "AN",      /* Arabic Number */
    "EN",      /* European Number */
    "AL",      /* Arabic Letter (Right-to-left) */
    "NSM",     /* Non-spacing Mark */
    "CS",      /* Common Separator */
    "ES",      /* European Separator */
    "ET",      /* European Terminator (post/prefix e.g. $ and %) */
    "BN",      /* Boundary neutral (type of RLE etc after explicit levels) */
    "S",       /* Segment Separator (TAB)         used only in L1 */
    "WS",      /* White space                     used only in L1 */
    "B",       /* Paragraph Separator (aka as PS) */
    "RLO",     /* these are used only in X1-X9 */
    "RLE",
    "LRO",
    "LRE",
    "PDF",
    "LRI",     /* Isolate formatting characters new with 6.3 */
    "RLI",
    "FSI",
    "PDI",
};

static inline void bidi_dump_types(const char* header, const UINT8 *types, UINT32 start, UINT32 end)
{
    int i, len = 0;
    TRACE("%s:", header);
    for (i = start; i < end && len < 200; i++) {
        TRACE(" %s", debug_type[types[i]]);
        len += strlen(debug_type[types[i]])+1;
    }
    if (i != end)
        TRACE("...");
    TRACE("\n");
}

/* Convert the libwine information to the direction enum */
static void bidi_classify(const WCHAR *string, UINT8 *chartype, UINT32 count)
{
    static const enum directions dir_map[16] =
    {
        L,  /* unassigned defaults to L */
        L,
        R,
        EN,
        ES,
        ET,
        AN,
        CS,
        B,
        S,
        WS,
        ON,
        AL,
        NSM,
        BN,
        PDF  /* also LRE, LRO, RLE, RLO */
    };

    UINT32 i;

    for (i = 0; i < count; ++i) {
        chartype[i] = dir_map[get_char_typeW(string[i]) >> 12];

        switch (chartype[i]) {
        case ES:
            break;
        case PDF:
            switch (string[i]) {
            case 0x202a: chartype[i] = LRE; break;
            case 0x202b: chartype[i] = RLE; break;
            case 0x202c: chartype[i] = PDF; break;
            case 0x202d: chartype[i] = LRO; break;
            case 0x202e: chartype[i] = RLO; break;
            case 0x2066: chartype[i] = LRI; break;
            case 0x2067: chartype[i] = RLI; break;
            case 0x2068: chartype[i] = FSI; break;
            case 0x2069: chartype[i] = PDI; break;
            }
            break;
        }
    }
}

WCHAR bidi_get_mirrored_char(WCHAR ch)
{
    extern const WCHAR wine_mirror_map[];
    return ch + wine_mirror_map[wine_mirror_map[ch >> 8] + (ch & 0xff)];
}

/* RESOLVE EXPLICIT */

static inline UINT8 get_greater_even_level(UINT8 level)
{
    return odd(level) ? level + 1 : level + 2;
}

static inline UINT8 get_greater_odd_level(UINT8 level)
{
    return odd(level) ? level + 2 : level + 1;
}

static inline UINT8 get_embedding_direction(UINT8 level)
{
    return odd(level) ? R : L;
}

/*------------------------------------------------------------------------
    Function: bidi_resolve_explicit

    Recursively resolves explicit embedding levels and overrides.
    Implements rules X1-X9, of the Unicode Bidirectional Algorithm.

    Input: Base embedding level and direction
           Character count

    Output: Array of embedding levels

    In/Out: Array of direction classes


    Note: The function uses two simple counters to keep track of
          matching explicit codes and PDF. Use the default argument for
          the outermost call. The nesting counter counts the recursion
          depth and not the embedding level.
------------------------------------------------------------------------*/
typedef struct tagStackItem
{
    UINT8 level;
    UINT8 override;
    BOOL isolate;
} StackItem;

#define push_stack(l,o,i)  \
  do { stack_top--; \
  stack[stack_top].level = l; \
  stack[stack_top].override = o; \
  stack[stack_top].isolate = i;} while(0)

#define pop_stack() do { stack_top++; } while(0)

#define valid_level(x) (x <= MAX_DEPTH && overflow_isolate_count == 0 && overflow_embedding_count == 0)

static void bidi_resolve_explicit(UINT8 baselevel, UINT8 *classes, UINT8 *levels, UINT32 count)
{
    /* X1 */
    int overflow_isolate_count = 0;
    int overflow_embedding_count = 0;
    int valid_isolate_count = 0;
    UINT32 i;

    StackItem stack[MAX_DEPTH+2];
    int stack_top = MAX_DEPTH+1;

    stack[stack_top].level = baselevel;
    stack[stack_top].override = NI;
    stack[stack_top].isolate = FALSE;

    for (i = 0; i < count; i++) {
        UINT8 least_odd, least_even;

        switch (classes[i]) {

        /* X2 */
        case RLE:
            least_odd = get_greater_odd_level(stack[stack_top].level);
            levels[i] = stack[stack_top].level;
            if (valid_level(least_odd))
                push_stack(least_odd, NI, FALSE);
            else if (overflow_isolate_count == 0)
                overflow_embedding_count++;
            break;

        /* X3 */
        case LRE:
            least_even = get_greater_even_level(stack[stack_top].level);
            levels[i] = stack[stack_top].level;
            if (valid_level(least_even))
                push_stack(least_even, NI, FALSE);
            else if (overflow_isolate_count == 0)
                overflow_embedding_count++;
            break;

        /* X4 */
        case RLO:
            least_odd = get_greater_odd_level(stack[stack_top].level);
            levels[i] = stack[stack_top].level;
            if (valid_level(least_odd))
                push_stack(least_odd, R, FALSE);
            else if (overflow_isolate_count == 0)
                overflow_embedding_count++;
            break;

        /* X5 */
        case LRO:
            least_even = get_greater_even_level(stack[stack_top].level);
            levels[i] = stack[stack_top].level;
            if (valid_level(least_even))
                push_stack(least_even, L, FALSE);
            else if (overflow_isolate_count == 0)
                overflow_embedding_count++;
            break;

        /* X5a */
        case RLI:
            least_odd = get_greater_odd_level(stack[stack_top].level);
            levels[i] = stack[stack_top].level;
            if (valid_level(least_odd))
            {
                valid_isolate_count++;
                push_stack(least_odd, NI, TRUE);
            }
            else
                overflow_isolate_count++;
            break;

        /* X5b */
        case LRI:
            least_even = get_greater_even_level(stack[stack_top].level);
            levels[i] = stack[stack_top].level;
            if (valid_level(least_even))
            {
                valid_isolate_count++;
                push_stack(least_even, NI, TRUE);
            }
            else
                overflow_isolate_count++;
            break;

        /* X5c */
        case FSI:
        {
            UINT8 new_level = 0;
            int skipping = 0;
            int j;

            levels[i] = stack[stack_top].level;
            for (j = i+1; j < count; j++)
            {
                if (classes[j] == LRI || classes[j] == RLI || classes[j] == FSI)
                {
                    skipping++;
                    continue;
                }
                else if (classes[j] == PDI)
                {
                    if (skipping)
                        skipping --;
                    else
                        break;
                    continue;
                }

                if (skipping) continue;

                if (classes[j] == L)
                {
                    new_level = 0;
                    break;
                }
                else if (classes[j] == R || classes[j] == AL)
                {
                    new_level = 1;
                    break;
                }
            }
            if (odd(new_level))
            {
                least_odd = get_greater_odd_level(stack[stack_top].level);
                if (valid_level(least_odd))
                {
                    valid_isolate_count++;
                    push_stack(least_odd, NI, TRUE);
                }
                else
                    overflow_isolate_count++;
            }
            else
            {
                least_even = get_greater_even_level(stack[stack_top].level);
                if (valid_level(least_even))
                {
                    valid_isolate_count++;
                    push_stack(least_even, NI, TRUE);
                }
                else
                    overflow_isolate_count++;
            }
            break;
        }

        /* X6 */
        case ON:
        case L:
        case R:
        case AN:
        case EN:
        case AL:
        case NSM:
        case CS:
        case ES:
        case ET:
        case S:
        case WS:
            levels[i] = stack[stack_top].level;
            if (stack[stack_top].override != NI)
                classes[i] = stack[stack_top].override;
            break;

        /* X6a */
        case PDI:
            if (overflow_isolate_count) overflow_isolate_count--;
            else if (!valid_isolate_count) {/* do nothing */}
            else
            {
                overflow_embedding_count = 0;
                while (!stack[stack_top].isolate) pop_stack();
                pop_stack();
                valid_isolate_count--;
            }
            levels[i] = stack[stack_top].level;
            break;

        /* X7 */
        case PDF:
            levels[i] = stack[stack_top].level;
            if (overflow_isolate_count) {/* do nothing */}
            else if (overflow_embedding_count) overflow_embedding_count--;
            else if (!stack[stack_top].isolate && stack_top < (MAX_DEPTH+1))
                pop_stack();
            break;

        /* X8: Nothing */
        default:
            break;
        }
    }
    /* X9: Based on 5.2 Retaining Explicit Formatting Characters */
    for (i = 0; i < count ; i++)
        if (classes[i] == RLE || classes[i] == LRE || classes[i] == RLO || classes[i] == LRO || classes[i] == PDF)
            classes[i] = BN;
}

static inline int get_prev_valid_char_index(const UINT8 *classes, int index, int back_fence)
{
    if (index == -1 || index == back_fence) return index;
    index--;
    while (index > back_fence && classes[index] == BN) index--;
    return index;
}

static inline int get_next_valid_char_index(const UINT8 *classes, int index, int front_fence)
{
    if (index == front_fence) return index;
    index++;
    while (index < front_fence && classes[index] == BN) index++;
    return index;
}

typedef struct tagRun
{
    int start;
    int end;
    UINT8 e;
} Run;

typedef struct tagRunChar
{
    WCHAR  ch;
    UINT8 *class;
} RunChar;

typedef struct tagIsolatedRun
{
    struct list entry;
    int length;
    UINT8 sos;
    UINT8 eos;
    UINT8 e;

    RunChar item[1];
} IsolatedRun;

static inline int get_next_valid_char_from_run(IsolatedRun *run, int index)
{
    if (index >= (run->length-1)) return -1;
    index++;
    while (index < run->length && *run->item[index].class == BN) index++;
    if (index == run->length) return -1;
    return index;
}

static inline int get_prev_valid_char_from_run(IsolatedRun *run, int index)
{
    if (index <= 0) return -1;
    index--;
    while (index > -1 && *run->item[index].class == BN) index--;
    return index;
}

static inline void iso_dump_types(const char* header, IsolatedRun *run)
{
    int i, len = 0;
    TRACE("%s:",header);
    TRACE("[ ");
    for (i = 0; i < run->length && len < 200; i++) {
        TRACE(" %s", debug_type[*run->item[i].class]);
        len += strlen(debug_type[*run->item[i].class])+1;
    }
    if (i != run->length)
        TRACE("...");
    TRACE(" ]\n");
}

/*------------------------------------------------------------------------
    Function: bidi_resolve_weak

    Resolves the directionality of numeric and other weak character types

    Implements rules X10 and W1-W6 of the Unicode Bidirectional Algorithm.

    Input: Array of embedding levels
           Character count

    In/Out: Array of directional classes

    Note: On input only these directional classes are expected
          AL, HL, R, L,  ON, BN, NSM, AN, EN, ES, ET, CS,
------------------------------------------------------------------------*/
static void bidi_resolve_weak(IsolatedRun *iso_run)
{
    int i;

    /* W1 */
    for (i=0; i < iso_run->length; i++) {
        if (*iso_run->item[i].class == NSM) {
            int j = get_prev_valid_char_from_run(iso_run, i);
            if (j == -1)
                *iso_run->item[i].class = iso_run->sos;
            else if (*iso_run->item[j].class >= LRI)
                *iso_run->item[i].class = ON;
            else
                *iso_run->item[i].class = *iso_run->item[j].class;
        }
    }

    /* W2 */
    for (i = 0; i < iso_run->length; i++) {
        if (*iso_run->item[i].class == EN) {
            int j = get_prev_valid_char_from_run(iso_run, i);
            while (j > -1) {
                if (*iso_run->item[j].class == R || *iso_run->item[j].class == L || *iso_run->item[j].class == AL) {
                    if (*iso_run->item[j].class == AL)
                        *iso_run->item[i].class = AN;
                    break;
                }
                j = get_prev_valid_char_from_run(iso_run, j);
            }
        }
    }

    /* W3 */
    for (i = 0; i < iso_run->length; i++) {
        if (*iso_run->item[i].class == AL)
            *iso_run->item[i].class = R;
    }

    /* W4 */
    for (i = 0; i < iso_run->length; i++) {
        if (*iso_run->item[i].class == ES) {
            int b = get_prev_valid_char_from_run(iso_run, i);
            int f = get_next_valid_char_from_run(iso_run, i);

            if (b > -1 && f > -1 && *iso_run->item[b].class == EN && *iso_run->item[f].class == EN)
                *iso_run->item[i].class = EN;
        }
        else if (*iso_run->item[i].class == CS) {
            int b = get_prev_valid_char_from_run(iso_run, i);
            int f = get_next_valid_char_from_run(iso_run, i);

            if (b > -1 && f > -1 && *iso_run->item[b].class == EN && *iso_run->item[f].class == EN)
                *iso_run->item[i].class = EN;
            else if (b > -1 && f > -1 && *iso_run->item[b].class == AN && *iso_run->item[f].class == AN)
                *iso_run->item[i].class = AN;
        }
    }

    /* W5 */
    for (i = 0; i < iso_run->length; i++) {
        if (*iso_run->item[i].class == ET) {
            int j;
            for (j = i-1 ; j > -1; j--) {
                if (*iso_run->item[j].class == BN) continue;
                if (*iso_run->item[j].class == ET) continue;
                else if (*iso_run->item[j].class == EN) *iso_run->item[i].class = EN;
                else break;
            }
            if (*iso_run->item[i].class == ET) {
                for (j = i+1; j < iso_run->length; j++) {
                    if (*iso_run->item[j].class == BN) continue;
                    if (*iso_run->item[j].class == ET) continue;
                    else if (*iso_run->item[j].class == EN) *iso_run->item[i].class = EN;
                    else break;
                }
            }
        }
    }

    /* W6 */
    for (i = 0; i < iso_run->length; i++) {
        if (*iso_run->item[i].class == ET || *iso_run->item[i].class == ES || *iso_run->item[i].class == CS || *iso_run->item[i].class == ON)
        {
            int b = i-1;
            int f = i+1;
            if (b > -1 && *iso_run->item[b].class == BN)
                *iso_run->item[b].class = ON;
            if (f < iso_run->length && *iso_run->item[f].class == BN)
                *iso_run->item[f].class = ON;

            *iso_run->item[i].class = ON;
        }
    }

    /* W7 */
    for (i = 0; i < iso_run->length; i++) {
        if (*iso_run->item[i].class == EN) {
            int j;
            for (j = get_prev_valid_char_from_run(iso_run, i); j > -1; j = get_prev_valid_char_from_run(iso_run, j))
                if (*iso_run->item[j].class == R || *iso_run->item[j].class == L) {
                    if (*iso_run->item[j].class == L)
                        *iso_run->item[i].class = L;
                    break;
                }
            if (iso_run->sos == L && j == -1)
                *iso_run->item[i].class = L;
        }
    }
}

typedef struct tagBracketPair
{
    int start;
    int end;
} BracketPair;

static int bracketpair_compr(const void *a, const void* b)
{
    return ((BracketPair*)a)->start - ((BracketPair*)b)->start;
}

static BracketPair *bidi_compute_bracket_pairs(IsolatedRun *iso_run)
{
    WCHAR *open_stack;
    int *stack_index;
    int stack_top = iso_run->length;
    BracketPair *out = NULL;
    int pair_count = 0;
    int i;

    open_stack = heap_alloc(sizeof(WCHAR) * iso_run->length);
    stack_index = heap_alloc(sizeof(int) * iso_run->length);

    for (i = 0; i < iso_run->length; i++) {
        unsigned short ubv = get_table_entry(bidi_bracket_table, iso_run->item[i].ch);
        if (ubv) {
            if (!out) {
                out = heap_alloc(sizeof(BracketPair));
                out[0].start = -1;
            }

            if ((ubv >> 8) == 0) {
                stack_top--;
                open_stack[stack_top] = iso_run->item[i].ch + (signed char)(ubv & 0xff);
                /* deal with canonical equivalent U+2329/232A and U+3008/3009 */
                if (open_stack[stack_top] == 0x232A)
                    open_stack[stack_top] = 0x3009;
                stack_index[stack_top] = i;
            }
            else if ((ubv >> 8) == 1) {
                int j;

                if (stack_top == iso_run->length) continue;
                for (j = stack_top; j < iso_run->length; j++) {
                    WCHAR c = iso_run->item[i].ch;
                    if (c == 0x232A) c = 0x3009;
                    if (c == open_stack[j]) {
                        out[pair_count].start = stack_index[j];
                        out[pair_count].end = i;
                        pair_count++;
                        out = heap_realloc(out, sizeof(BracketPair) * (pair_count+1));
                        out[pair_count].start = -1;
                        stack_top = j+1;
                        break;
                    }
                }
            }
        }
    }
    if (pair_count == 0) {
        heap_free(out);
        out = NULL;
    }
    else if (pair_count > 1)
        qsort(out, pair_count, sizeof(BracketPair), bracketpair_compr);

    heap_free(open_stack);
    heap_free(stack_index);
    return out;
}

static inline UINT8 get_rule_N0_class(UINT8 class)
{
    return (class == AN || class == EN) ? R : class;
}

/*------------------------------------------------------------------------
    Function: bidi_resolve_neutrals

    Resolves the directionality of neutral character types.

    Implements rules N1 and N2 of the Unicode Bidi Algorithm.

    Input: Array of embedding levels
           Character count
           Baselevel

    In/Out: Array of directional classes

    Note: On input only these directional classes are expected
          R,  L,  NI, AN, EN and BN

          W8 resolves a number of ENs to L
------------------------------------------------------------------------*/
static void bidi_resolve_neutrals(IsolatedRun *run)
{
    BracketPair *pairs;
    int i;

    /* Translate isolates into NI */
    for (i = 0; i < run->length; i++) {
        if (*run->item[i].class >= LRI)
            *run->item[i].class = NI;

        switch (*run->item[i].class) {
            case B:
            case S:
            case WS: *run->item[i].class = NI;
        }

        ASSERT(*run->item[i].class < 5 || *run->item[i].class == BN); /* "Only NI, L, R,  AN, EN and BN are allowed" */
    }

    /* N0: Skipping bracketed pairs for now */
    pairs = bidi_compute_bracket_pairs(run);
    if (pairs) {
        BracketPair *p = pairs;
        int i = 0;
        while (p->start >= 0) {
            UINT8 e = get_embedding_direction(run->e);
            UINT8 o = get_embedding_direction(run->e + 1);
            BOOL flag_o = FALSE;
            int j;

            TRACE("Bracket Pair [%i - %i]\n", p->start, p->end);

            /* N0.b */
            for (j = p->start+1; j < p->end; j++) {
                if (get_rule_N0_class(*run->item[j].class) == e) {
                    *run->item[p->start].class = e;
                    *run->item[p->end].class = e;
                    break;
                }
                else if (get_rule_N0_class(*run->item[j].class) == o)
                    flag_o = TRUE;
            }
            /* N0.c */
            if (j == p->end && flag_o) {
                for (j = p->start; j >= 0; j--) {
                    if (get_rule_N0_class(*run->item[j].class) == o) {
                        *run->item[p->start].class = o;
                        *run->item[p->end].class = o;
                        break;
                    }
                    else if (get_rule_N0_class(*run->item[j].class) == e) {
                        *run->item[p->start].class = e;
                        *run->item[p->end].class = e;
                        break;
                    }
                }
                if (j < 0) {
                    *run->item[p->start].class = run->sos;
                    *run->item[p->end].class = run->sos;
                }
            }

            i++;
            p = &pairs[i];
        }
        heap_free(pairs);
    }

    /* N1 */
    for (i = 0; i < run->length; i++) {
        UINT8 l, r;

        if (*run->item[i].class == NI) {
            int b = get_prev_valid_char_from_run(run, i);
            int j;

            if (b == -1) {
                l = run->sos;
                b = 0;
            }
            else {
                if (*run->item[b].class == R || *run->item[b].class == AN || *run->item[b].class == EN)
                    l = R;
                else if (*run->item[b].class == L)
                    l = L;
                else /* No string type */
                    continue;
            }
            j = get_next_valid_char_from_run(run, i);
            while (j > -1 && *run->item[j].class == NI) j = get_next_valid_char_from_run(run, j);
            if (j == -1) {
                r = run->eos;
                j = run->length;
            }
            else if (*run->item[j].class == R || *run->item[j].class == AN || *run->item[j].class == EN)
                r = R;
            else if (*run->item[j].class == L)
                r = L;
            else /* No string type */
                continue;

            if (r == l) {
                for (b = i; b < j && b < run->length; b++)
                    *run->item[b].class = r;
            }
        }
    }

    /* N2 */
    for (i = 0; i < run->length; i++) {
        if (*run->item[i].class == NI) {
            int b = i-1;
            int f = i+1;

            *run->item[i].class = get_embedding_direction(run->e);
            if (b > -1 && *run->item[b].class == BN)
                *run->item[b].class = get_embedding_direction(run->e);
            if (f < run->length && *run->item[f].class == BN)
                *run->item[f].class = get_embedding_direction(run->e);
        }
    }
}

/*------------------------------------------------------------------------
    Function: bidi_resolve_implicit

    Recursively resolves implicit embedding levels.
    Implements rules I1 and I2 of the Unicode Bidirectional Algorithm.

    Input: Array of direction classes
           Character count
           Base level

    In/Out: Array of embedding levels

    Note: levels may exceed 15 on output.
          Accepted subset of direction classes
          R, L, AN, EN
------------------------------------------------------------------------*/
static void bidi_resolve_implicit(const UINT8 *classes, UINT8 *levels, int sos, int eos)
{
    int i;

    /* I1/2 */
    for (i = sos; i <= eos; i++) {
        if (classes[i] == BN)
            continue;

        ASSERT(classes[i] > 0); /* "No Neutrals allowed to survive here." */
        ASSERT(classes[i] < 5); /* "Out of range." */

        if (odd(levels[i]) && (classes[i] == L || classes[i] == EN || classes[i] == AN))
            levels[i]++;
        else if (!odd(levels[i]) && classes[i] == R)
            levels[i]++;
        else if (!odd(levels[i]) && (classes[i] == EN || classes[i] == AN))
            levels[i] += 2;
    }
}

static inline BOOL is_rule_L1_reset_class(UINT8 class)
{
    switch (class) {
    case WS:
    case FSI:
    case LRI:
    case RLI:
    case PDI:
    case LRE:
    case RLE:
    case LRO:
    case RLO:
    case PDF:
    case BN:
        return TRUE;
    default:
        return FALSE;
    }
}

static void bidi_resolve_resolved(UINT8 baselevel, const UINT8 *classes, UINT8 *levels, int sos, int eos)
{
    int i;

    /* L1 */
    for (i = sos; i <= eos; i++) {
        if (classes[i] == B || classes[i] == S) {
            int j = i - 1;
            while (i > sos && j >= sos && is_rule_L1_reset_class(classes[j]))
                levels[j--] = baselevel;
            levels[i] = baselevel;
        }
        if (i == eos && is_rule_L1_reset_class(classes[i])) {
            int j = i;
            while (j >= sos && is_rule_L1_reset_class(classes[j]))
                levels[j--] = baselevel;
        }
    }
}

static HRESULT bidi_compute_isolating_runs_set(UINT8 baselevel, UINT8 *classes, UINT8 *levels, const WCHAR *string, UINT32 count, struct list *set)
{
    int run_start, run_end, i;
    int run_count = 0;
    HRESULT hr = S_OK;
    Run *runs;

    runs = heap_alloc(count * sizeof(Run));
    if (!runs)
        return E_OUTOFMEMORY;

    list_init(set);

    /* Build Runs */
    run_start = 0;
    while (run_start < count) {
        run_end = get_next_valid_char_index(classes, run_start, count);
        while (run_end < count && levels[run_end] == levels[run_start])
            run_end = get_next_valid_char_index(classes, run_end, count);
        run_end--;
        runs[run_count].start = run_start;
        runs[run_count].end = run_end;
        runs[run_count].e = levels[run_start];
        run_start = get_next_valid_char_index(classes, run_end, count);
        run_count++;
    }

    /* Build Isolating Runs */
    i = 0;
    while (i < run_count) {
        int k = i;
        if (runs[k].start >= 0) {
            IsolatedRun *current_isolated;
            int type_fence, real_end;
            int j;

            current_isolated = heap_alloc(sizeof(IsolatedRun) + sizeof(RunChar)*count);
            if (!current_isolated) {
                hr = E_OUTOFMEMORY;
                break;
            }

            run_start = runs[k].start;
            current_isolated->e = runs[k].e;
            current_isolated->length = (runs[k].end - runs[k].start)+1;

            for (j = 0; j < current_isolated->length; j++) {
                current_isolated->item[j].class = &classes[runs[k].start+j];
                current_isolated->item[j].ch = string[runs[k].start+j];
            }

            run_end = runs[k].end;

            TRACE("{ [%i -- %i]",run_start, run_end);

            if (classes[run_end] == BN)
                run_end = get_prev_valid_char_index(classes, run_end, runs[k].start);

            while (run_end < count && (classes[run_end] == RLI || classes[run_end] == LRI || classes[run_end] == FSI)) {
                j = k+1;
search:
                while (j < run_count && classes[runs[j].start] != PDI) j++;
                if (j < run_count && runs[i].e != runs[j].e) {
                    j++;
                    goto search;
                }

                if (j != run_count) {
                    int l = current_isolated->length;
                    int m;

                    current_isolated->length += (runs[j].end - runs[j].start)+1;
                    for (m = 0; l < current_isolated->length; l++, m++) {
                        current_isolated->item[l].class = &classes[runs[j].start+m];
                        current_isolated->item[l].ch = string[runs[j].start+m];
                    }

                    TRACE("[%i -- %i]", runs[j].start, runs[j].end);

                    run_end = runs[j].end;
                    if (classes[run_end] == BN)
                        run_end = get_prev_valid_char_index(classes, run_end, runs[i].start);
                    runs[j].start = -1;
                    k = j;
                }
                else {
                    run_end = count;
                    break;
                }
            }

            type_fence = get_prev_valid_char_index(classes, run_start, -1);

            if (type_fence == -1)
                current_isolated->sos = (baselevel > levels[run_start]) ? baselevel : levels[run_start];
            else
                current_isolated->sos = (levels[type_fence] > levels[run_start]) ? levels[type_fence] : levels[run_start];

            current_isolated->sos = get_embedding_direction(current_isolated->sos);

            if (run_end == count)
                current_isolated->eos = current_isolated->sos;
            else {
                /* eos could be an BN */
                if (classes[run_end] == BN) {
                    real_end = get_prev_valid_char_index(classes, run_end, run_start-1);
                    if (real_end < run_start)
                        real_end = run_start;
                }
                else
                    real_end = run_end;

                type_fence = get_next_valid_char_index(classes, run_end, count);
                if (type_fence == count)
                    current_isolated->eos = (baselevel > levels[real_end]) ? baselevel : levels[real_end];
                else
                    current_isolated->eos = (levels[type_fence] > levels[real_end]) ? levels[type_fence] : levels[real_end];

                current_isolated->eos = get_embedding_direction(current_isolated->eos);
            }

            list_add_tail(set, &current_isolated->entry);
            TRACE(" } level %i {%s <--> %s}\n", current_isolated->e, debug_type[current_isolated->sos], debug_type[current_isolated->eos]);
        }
        i++;
    }

    heap_free(runs);
    return hr;
}

HRESULT bidi_computelevels(const WCHAR *string, UINT32 count, UINT8 baselevel, UINT8 *explicit, UINT8 *levels)
{
    IsolatedRun *iso_run, *next;
    struct list IsolatingRuns;
    UINT8 *chartype;
    HRESULT hr;

    TRACE("%s, %u\n", debugstr_wn(string, count), count);

    chartype = heap_alloc(count*sizeof(*chartype));
    if (!chartype)
        return E_OUTOFMEMORY;

    bidi_classify(string, chartype, count);
    if (TRACE_ON(bidi)) bidi_dump_types("start ", chartype, 0, count);

    bidi_resolve_explicit(baselevel, chartype, levels, count);
    memcpy(explicit, levels, count*sizeof(*explicit));

    if (TRACE_ON(bidi)) bidi_dump_types("after explicit", chartype, 0, count);

    /* X10/BD13: Compute Isolating runs */
    hr = bidi_compute_isolating_runs_set(baselevel, chartype, levels, string, count, &IsolatingRuns);
    if (FAILED(hr))
        goto done;

    LIST_FOR_EACH_ENTRY_SAFE(iso_run, next, &IsolatingRuns, IsolatedRun, entry)
    {
        if (TRACE_ON(bidi)) iso_dump_types("run", iso_run);

        bidi_resolve_weak(iso_run);
        if (TRACE_ON(bidi)) iso_dump_types("after weak", iso_run);

        bidi_resolve_neutrals(iso_run);
        if (TRACE_ON(bidi)) iso_dump_types("after neutrals", iso_run);

        list_remove(&iso_run->entry);
        heap_free(iso_run);
    }

    if (TRACE_ON(bidi)) bidi_dump_types("before implicit", chartype, 0, count);
    bidi_resolve_implicit(chartype, levels, 0, count-1);

    bidi_classify(string, chartype, count);
    bidi_resolve_resolved(baselevel, chartype, levels, 0, count-1);

done:
    heap_free(chartype);
    return hr;
}
