/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.text.cts;

import android.test.AndroidTestCase;
import android.text.Editable;
import android.text.GetChars;
import android.text.GraphicsOperations;
import android.text.Layout.Alignment;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.SpannedString;
import android.text.StaticLayout;
import android.text.TextDirectionHeuristics;
import android.text.TextPaint;
import android.text.TextUtils;

import java.text.Normalizer;
import java.util.ArrayList;
import java.util.List;

public class StaticLayoutTest extends AndroidTestCase {
    private static final float SPACE_MULTI = 1.0f;
    private static final float SPACE_ADD = 0.0f;
    private static final int DEFAULT_OUTER_WIDTH = 150;

    private static final int LAST_LINE = 5;
    private static final int LINE_COUNT = 6;
    private static final int LARGER_THAN_LINE_COUNT  = 50;

    /* the first line must have one tab. the others not. totally 6 lines
     */
    private static final CharSequence LAYOUT_TEXT = "CharSe\tq\nChar"
            + "Sequence\nCharSequence\nHelllo\n, world\nLongLongLong";

    private static final CharSequence LAYOUT_TEXT_SINGLE_LINE = "CharSequence";

    private static final int VERTICAL_BELOW_TEXT = 1000;

    private static final Alignment DEFAULT_ALIGN = Alignment.ALIGN_CENTER;

    private static final int ELLIPSIZE_WIDTH = 8;

    private StaticLayout mDefaultLayout;
    private TextPaint mDefaultPaint;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        if (mDefaultPaint == null) {
            mDefaultPaint = new TextPaint();
        }
        if (mDefaultLayout == null) {
            mDefaultLayout = createDefaultStaticLayout();
        }
    }

    private StaticLayout createDefaultStaticLayout() {
        return new StaticLayout(LAYOUT_TEXT, mDefaultPaint,
                DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
    }

    private StaticLayout createEllipsizeStaticLayout() {
        return new StaticLayout(LAYOUT_TEXT, 0, LAYOUT_TEXT.length(), mDefaultPaint,
                DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true,
                TextUtils.TruncateAt.MIDDLE, ELLIPSIZE_WIDTH);
    }

    private StaticLayout createEllipsizeStaticLayout(CharSequence text,
            TextUtils.TruncateAt ellipsize, int maxLines) {
        return new StaticLayout(text, 0, text.length(),
                mDefaultPaint, DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN,
                TextDirectionHeuristics.FIRSTSTRONG_LTR,
                SPACE_MULTI, SPACE_ADD, true /* include pad */,
                ellipsize,
                ELLIPSIZE_WIDTH,
                maxLines);
    }



    /**
     * Constructor test
     */
    public void testConstructor() {
        new StaticLayout(LAYOUT_TEXT, mDefaultPaint, DEFAULT_OUTER_WIDTH,
                DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

        new StaticLayout(LAYOUT_TEXT, 0, LAYOUT_TEXT.length(), mDefaultPaint,
                DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

        new StaticLayout(LAYOUT_TEXT, 0, LAYOUT_TEXT.length(), mDefaultPaint,
                DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, false, null, 0);

        try {
            new StaticLayout(null, null, -1, null, 0, 0, true);
            fail("should throw NullPointerException here");
        } catch (NullPointerException e) {
        }
    }

    /*
     * Get the line number corresponding to the specified vertical position.
     *  If you ask for a position above 0, you get 0. above 0 means pixel above the fire line
     *  if you ask for a position in the range of the height, return the pixel in line
     *  if you ask for a position below the bottom of the text, you get the last line.
     *  Test 4 values containing -1, 0, normal number and > count
     */
    public void testGetLineForVertical() {
        assertEquals(0, mDefaultLayout.getLineForVertical(-1));
        assertEquals(0, mDefaultLayout.getLineForVertical(0));
        assertTrue(mDefaultLayout.getLineForVertical(50) > 0);
        assertEquals(LAST_LINE, mDefaultLayout.getLineForVertical(VERTICAL_BELOW_TEXT));
    }

    /**
     * Return the number of lines of text in this layout.
     */
    public void testGetLineCount() {
        assertEquals(LINE_COUNT, mDefaultLayout.getLineCount());
    }

    /*
     * Return the vertical position of the top of the specified line.
     * If the specified line is one beyond the last line, returns the bottom of the last line.
     * A line of text contains top and bottom in height. this method just get the top of a line
     * Test 4 values containing -1, 0, normal number and > count
     */
    public void testGetLineTop() {
        assertTrue(mDefaultLayout.getLineTop(0) >= 0);
        assertTrue(mDefaultLayout.getLineTop(1) > mDefaultLayout.getLineTop(0));

        try {
            mDefaultLayout.getLineTop(-1);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }

        try {
            mDefaultLayout.getLineTop(LARGER_THAN_LINE_COUNT );
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
    }

    /**
     * Return the descent of the specified line.
     * This method just like getLineTop, descent means the bottom pixel of the line
     * Test 4 values containing -1, 0, normal number and > count
     */
    public void testGetLineDescent() {
        assertTrue(mDefaultLayout.getLineDescent(0) > 0);
        assertTrue(mDefaultLayout.getLineDescent(1) > 0);

        try {
            mDefaultLayout.getLineDescent(-1);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }

        try {
            mDefaultLayout.getLineDescent(LARGER_THAN_LINE_COUNT );
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
    }

    /**
     * Returns the primary directionality of the paragraph containing the specified line.
     * By default, each line should be same
     */
    public void testGetParagraphDirection() {
        assertEquals(mDefaultLayout.getParagraphDirection(0),
                mDefaultLayout.getParagraphDirection(1));
        try {
            mDefaultLayout.getParagraphDirection(-1);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }

        try {
            mDefaultLayout.getParagraphDirection(LARGER_THAN_LINE_COUNT);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
    }

    /**
     * Return the text offset of the beginning of the specified line.
     * If the specified line is one beyond the last line, returns the end of the last line.
     * Test 4 values containing -1, 0, normal number and > count
     * Each line's offset must >= 0
     */
    public void testGetLineStart() {
        assertTrue(mDefaultLayout.getLineStart(0) >= 0);
        assertTrue(mDefaultLayout.getLineStart(1) >= 0);

        try {
            mDefaultLayout.getLineStart(-1);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }

        try {
            mDefaultLayout.getLineStart(LARGER_THAN_LINE_COUNT);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
    }

    /*
     * Returns whether the specified line contains one or more tabs.
     */
    public void testGetContainsTab() {
        assertTrue(mDefaultLayout.getLineContainsTab(0));
        assertFalse(mDefaultLayout.getLineContainsTab(1));

        try {
            mDefaultLayout.getLineContainsTab(-1);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }

        try {
            mDefaultLayout.getLineContainsTab(LARGER_THAN_LINE_COUNT );
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
    }

    /**
     * Returns an array of directionalities for the specified line.
     * The array alternates counts of characters in left-to-right
     * and right-to-left segments of the line.
     * We can not check the return value, for Directions's field is package private
     * So only check it not null
     */
    public void testGetLineDirections() {
        assertNotNull(mDefaultLayout.getLineDirections(0));
        assertNotNull(mDefaultLayout.getLineDirections(1));

        try {
            mDefaultLayout.getLineDirections(-1);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }

        try {
            mDefaultLayout.getLineDirections(LARGER_THAN_LINE_COUNT);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
    }

    /**
     * Returns the (negative) number of extra pixels of ascent padding
     * in the top line of the Layout.
     */
    public void testGetTopPadding() {
        assertTrue(mDefaultLayout.getTopPadding() < 0);
    }

    /**
     * Returns the number of extra pixels of descent padding in the bottom line of the Layout.
     */
    public void testGetBottomPadding() {
        assertTrue(mDefaultLayout.getBottomPadding() > 0);
    }

    /*
     * Returns the number of characters to be ellipsized away, or 0 if no ellipsis is to take place.
     * So each line must >= 0
     */
    public void testGetEllipsisCount() {
        // Multilines (6 lines) and TruncateAt.START so no ellipsis at all
        mDefaultLayout = createEllipsizeStaticLayout(LAYOUT_TEXT,
                TextUtils.TruncateAt.MIDDLE,
                Integer.MAX_VALUE /* maxLines */);

        assertTrue(mDefaultLayout.getEllipsisCount(0) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(1) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(2) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(3) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(4) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(5) == 0);

        try {
            mDefaultLayout.getEllipsisCount(-1);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }

        try {
            mDefaultLayout.getEllipsisCount(LARGER_THAN_LINE_COUNT);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }

        // Multilines (6 lines) and TruncateAt.MIDDLE so no ellipsis at all
        mDefaultLayout = createEllipsizeStaticLayout(LAYOUT_TEXT,
                TextUtils.TruncateAt.MIDDLE,
                Integer.MAX_VALUE /* maxLines */);

        assertTrue(mDefaultLayout.getEllipsisCount(0) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(1) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(2) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(3) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(4) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(5) == 0);

        // Multilines (6 lines) and TruncateAt.END so ellipsis only on the last line
        mDefaultLayout = createEllipsizeStaticLayout(LAYOUT_TEXT,
                TextUtils.TruncateAt.END,
                Integer.MAX_VALUE /* maxLines */);

        assertTrue(mDefaultLayout.getEllipsisCount(0) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(1) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(2) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(3) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(4) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(5) > 0);

        // Multilines (6 lines) and TruncateAt.MARQUEE so ellipsis only on the last line
        mDefaultLayout = createEllipsizeStaticLayout(LAYOUT_TEXT,
                TextUtils.TruncateAt.END,
                Integer.MAX_VALUE /* maxLines */);

        assertTrue(mDefaultLayout.getEllipsisCount(0) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(1) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(2) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(3) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(4) == 0);
        assertTrue(mDefaultLayout.getEllipsisCount(5) > 0);

        // Single line case and TruncateAt.END so that we have some ellipsis
        mDefaultLayout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
                TextUtils.TruncateAt.END,
                1);
        assertTrue(mDefaultLayout.getEllipsisCount(0) > 0);

        // Single line case and TruncateAt.MIDDLE so that we have some ellipsis
        mDefaultLayout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
                TextUtils.TruncateAt.MIDDLE,
                1);
        assertTrue(mDefaultLayout.getEllipsisCount(0) > 0);

        // Single line case and TruncateAt.END so that we have some ellipsis
        mDefaultLayout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
                TextUtils.TruncateAt.END,
                1);
        assertTrue(mDefaultLayout.getEllipsisCount(0) > 0);

        // Single line case and TruncateAt.MARQUEE so that we have NO ellipsis
        mDefaultLayout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
                TextUtils.TruncateAt.MARQUEE,
                1);
        assertTrue(mDefaultLayout.getEllipsisCount(0) == 0);
    }

    /*
     * Return the offset of the first character to be ellipsized away
     * relative to the start of the line.
     * (So 0 if the beginning of the line is ellipsized, not getLineStart().)
     */
    public void testGetEllipsisStart() {
        mDefaultLayout = createEllipsizeStaticLayout();
        assertTrue(mDefaultLayout.getEllipsisStart(0) >= 0);
        assertTrue(mDefaultLayout.getEllipsisStart(1) >= 0);

        try {
            mDefaultLayout.getEllipsisStart(-1);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }

        try {
            mDefaultLayout.getEllipsisStart(LARGER_THAN_LINE_COUNT);
            fail("should throw ArrayIndexOutOfBoundsException");
        } catch (ArrayIndexOutOfBoundsException e) {
        }
    }

    /*
     * Return the width to which this Layout is ellipsizing
     * or getWidth() if it is not doing anything special.
     * The constructor's Argument TextUtils.TruncateAt defines which EllipsizedWidth to use
     * ellipsizedWidth if argument is not null
     * outerWidth if argument is null
     */
    public void testGetEllipsizedWidth() {
        int ellipsizedWidth = 60;
        int outerWidth = 100;
        StaticLayout layout = new StaticLayout(LAYOUT_TEXT, 0, LAYOUT_TEXT.length(),
                mDefaultPaint, outerWidth, DEFAULT_ALIGN, SPACE_MULTI,
                SPACE_ADD, false, TextUtils.TruncateAt.END, ellipsizedWidth);
        assertEquals(ellipsizedWidth, layout.getEllipsizedWidth());

        layout = new StaticLayout(LAYOUT_TEXT, 0, LAYOUT_TEXT.length(),
                mDefaultPaint, outerWidth, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD,
                false, null, ellipsizedWidth);
        assertEquals(outerWidth, layout.getEllipsizedWidth());
    }

    /**
     * scenario description:
     * 1. set the text.
     * 2. change the text
     * 3. Check the text won't change to the StaticLayout
    */
    public void testImmutableStaticLayout() {
        Editable editable =  Editable.Factory.getInstance().newEditable("123\t\n555");
        StaticLayout layout = new StaticLayout(editable, mDefaultPaint,
                DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

        assertEquals(2, layout.getLineCount());
        assertTrue(mDefaultLayout.getLineContainsTab(0));

        // change the text
        editable.delete(0, editable.length() - 1);

        assertEquals(2, layout.getLineCount());
        assertTrue(layout.getLineContainsTab(0));

    }

    // String wrapper for testing not well known implementation of CharSequence.
    private class FakeCharSequence implements CharSequence {
        private String mStr;

        public FakeCharSequence(String str) {
            mStr = str;
        }

        @Override
        public char charAt(int index) {
            return mStr.charAt(index);
        }

        @Override
        public int length() {
            return mStr.length();
        }

        @Override
        public CharSequence subSequence(int start, int end) {
            return mStr.subSequence(start, end);
        }

        @Override
        public String toString() {
            return mStr;
        }
    };

    private List<CharSequence> buildTestCharSequences(String testString, Normalizer.Form[] forms) {
        List<CharSequence> result = new ArrayList<CharSequence>();

        List<String> normalizedStrings = new ArrayList<String>();
        for (Normalizer.Form form: forms) {
            normalizedStrings.add(Normalizer.normalize(testString, form));
        }

        for (String str: normalizedStrings) {
            result.add(str);
            result.add(new SpannedString(str));
            result.add(new SpannableString(str));
            result.add(new SpannableStringBuilder(str));  // as a GraphicsOperations implementation.
            result.add(new FakeCharSequence(str));  // as a not well known implementation.
        }
        return result;
    }

    private String buildTestMessage(CharSequence seq) {
        String normalized;
        if (Normalizer.isNormalized(seq, Normalizer.Form.NFC)) {
            normalized = "NFC";
        } else if (Normalizer.isNormalized(seq, Normalizer.Form.NFD)) {
            normalized = "NFD";
        } else if (Normalizer.isNormalized(seq, Normalizer.Form.NFKC)) {
            normalized = "NFKC";
        } else if (Normalizer.isNormalized(seq, Normalizer.Form.NFKD)) {
            normalized = "NFKD";
        } else {
            throw new IllegalStateException("Normalized form is not NFC/NFD/NFKC/NFKD");
        }

        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < seq.length(); ++i) {
            builder.append(String.format("0x%04X ", Integer.valueOf(seq.charAt(i))));
        }

        return "testString: \"" + seq.toString() + "\"[" + builder.toString() + "]" +
                ", class: " + seq.getClass().getName() +
                ", Normalization: " + normalized;
    }

    public void testGetOffset_ASCII() {
        String testStrings[] = { "abcde", "ab\ncd", "ab\tcd", "ab\n\nc", "ab\n\tc" };

        for (String testString: testStrings) {
            for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
                StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
                        DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

                String testLabel = buildTestMessage(seq);

                assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
                assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
                assertEquals(testLabel, 1, layout.getOffsetToLeftOf(2));
                assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
                assertEquals(testLabel, 3, layout.getOffsetToLeftOf(4));
                assertEquals(testLabel, 4, layout.getOffsetToLeftOf(5));

                assertEquals(testLabel, 1, layout.getOffsetToRightOf(0));
                assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
                assertEquals(testLabel, 3, layout.getOffsetToRightOf(2));
                assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
                assertEquals(testLabel, 5, layout.getOffsetToRightOf(4));
                assertEquals(testLabel, 5, layout.getOffsetToRightOf(5));
            }
        }

        String testString = "ab\r\nde";
        for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

            String testLabel = buildTestMessage(seq);

            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(2));
            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(4));
            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(5));
            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(6));

            assertEquals(testLabel, 1, layout.getOffsetToRightOf(0));
            assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
            assertEquals(testLabel, 4, layout.getOffsetToRightOf(2));
            assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
            assertEquals(testLabel, 5, layout.getOffsetToRightOf(4));
            assertEquals(testLabel, 6, layout.getOffsetToRightOf(5));
            assertEquals(testLabel, 6, layout.getOffsetToRightOf(6));
        }
    }

    public void testGetOffset_UNICODE() {
        String testStrings[] = new String[] {
              // Cyrillic alphabets.
              "\u0410\u0411\u0412\u0413\u0414",
              // Japanese Hiragana Characters.
              "\u3042\u3044\u3046\u3048\u304A",
        };

        for (String testString: testStrings) {
            for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
                StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
                        DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

                String testLabel = buildTestMessage(seq);

                assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
                assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
                assertEquals(testLabel, 1, layout.getOffsetToLeftOf(2));
                assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
                assertEquals(testLabel, 3, layout.getOffsetToLeftOf(4));
                assertEquals(testLabel, 4, layout.getOffsetToLeftOf(5));

                assertEquals(testLabel, 1, layout.getOffsetToRightOf(0));
                assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
                assertEquals(testLabel, 3, layout.getOffsetToRightOf(2));
                assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
                assertEquals(testLabel, 5, layout.getOffsetToRightOf(4));
                assertEquals(testLabel, 5, layout.getOffsetToRightOf(5));
            }
        }
    }

    public void testGetOffset_UNICODE_Normalization() {
        // "A" with acute, circumflex, tilde, diaeresis, ring above.
        String testString = "\u00C1\u00C2\u00C3\u00C4\u00C5";
        Normalizer.Form[] oneUnicodeForms = { Normalizer.Form.NFC, Normalizer.Form.NFKC };
        for (CharSequence seq: buildTestCharSequences(testString, oneUnicodeForms)) {
            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

            String testLabel = buildTestMessage(seq);

            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(2));
            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(4));
            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(5));

            assertEquals(testLabel, 1, layout.getOffsetToRightOf(0));
            assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
            assertEquals(testLabel, 3, layout.getOffsetToRightOf(2));
            assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
            assertEquals(testLabel, 5, layout.getOffsetToRightOf(4));
            assertEquals(testLabel, 5, layout.getOffsetToRightOf(5));
        }

        Normalizer.Form[] twoUnicodeForms = { Normalizer.Form.NFD, Normalizer.Form.NFKD };
        for (CharSequence seq: buildTestCharSequences(testString, twoUnicodeForms)) {
            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

            String testLabel = buildTestMessage(seq);

            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(2));
            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(4));
            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(5));
            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(6));
            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(7));
            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(8));
            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(9));
            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(10));

            assertEquals(testLabel, 2, layout.getOffsetToRightOf(0));
            assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
            assertEquals(testLabel, 4, layout.getOffsetToRightOf(2));
            assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
            assertEquals(testLabel, 6, layout.getOffsetToRightOf(4));
            assertEquals(testLabel, 6, layout.getOffsetToRightOf(5));
            assertEquals(testLabel, 8, layout.getOffsetToRightOf(6));
            assertEquals(testLabel, 8, layout.getOffsetToRightOf(7));
            assertEquals(testLabel, 10, layout.getOffsetToRightOf(8));
            assertEquals(testLabel, 10, layout.getOffsetToRightOf(9));
            assertEquals(testLabel, 10, layout.getOffsetToRightOf(10));
        }
    }

    public void testGetOffset_UNICODE_SurrogatePairs() {
        // Emoticons for surrogate pairs tests.
        String testString =
                "\uD83D\uDE00\uD83D\uDE01\uD83D\uDE02\uD83D\uDE03\uD83D\uDE04";
        for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

            String testLabel = buildTestMessage(seq);

            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(2));
            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(4));
            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(5));
            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(6));
            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(7));
            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(8));
            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(9));
            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(10));

            assertEquals(testLabel, 2, layout.getOffsetToRightOf(0));
            assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
            assertEquals(testLabel, 4, layout.getOffsetToRightOf(2));
            assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
            assertEquals(testLabel, 6, layout.getOffsetToRightOf(4));
            assertEquals(testLabel, 6, layout.getOffsetToRightOf(5));
            assertEquals(testLabel, 8, layout.getOffsetToRightOf(6));
            assertEquals(testLabel, 8, layout.getOffsetToRightOf(7));
            assertEquals(testLabel, 10, layout.getOffsetToRightOf(8));
            assertEquals(testLabel, 10, layout.getOffsetToRightOf(9));
            assertEquals(testLabel, 10, layout.getOffsetToRightOf(10));
        }
    }

    public void testGetOffset_UNICODE_Thai() {
        // Thai Characters. The expected cursorable boundary is
        // | \u0E02 | \u0E2D | \u0E1A | \u0E04\u0E38 | \u0E13 |
        String testString = "\u0E02\u0E2D\u0E1A\u0E04\u0E38\u0E13";
        for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

            String testLabel = buildTestMessage(seq);

            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(2));
            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(4));
            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(5));
            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(6));

            assertEquals(testLabel, 1, layout.getOffsetToRightOf(0));
            assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
            assertEquals(testLabel, 3, layout.getOffsetToRightOf(2));
            assertEquals(testLabel, 5, layout.getOffsetToRightOf(3));
            assertEquals(testLabel, 5, layout.getOffsetToRightOf(4));
            assertEquals(testLabel, 6, layout.getOffsetToRightOf(5));
            assertEquals(testLabel, 6, layout.getOffsetToRightOf(6));
        }
    }

    public void testGetOffset_UNICODE_Hebrew() {
        String testString = "\u05DE\u05E1\u05E2\u05D3\u05D4"; // Hebrew Characters
        for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN,
                    TextDirectionHeuristics.RTL, SPACE_MULTI, SPACE_ADD, true);

            String testLabel = buildTestMessage(seq);

            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(0));
            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(1));
            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(2));
            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(3));
            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(4));
            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(5));

            assertEquals(testLabel, 0, layout.getOffsetToRightOf(0));
            assertEquals(testLabel, 0, layout.getOffsetToRightOf(1));
            assertEquals(testLabel, 1, layout.getOffsetToRightOf(2));
            assertEquals(testLabel, 2, layout.getOffsetToRightOf(3));
            assertEquals(testLabel, 3, layout.getOffsetToRightOf(4));
            assertEquals(testLabel, 4, layout.getOffsetToRightOf(5));
        }
    }

    public void testGetOffset_UNICODE_Arabic() {
        // Arabic Characters. The expected cursorable boundary is
        // | \u0623 \u064F | \u0633 \u0652 | \u0631 \u064E | \u0629 \u064C |";
        String testString = "\u0623\u064F\u0633\u0652\u0631\u064E\u0629\u064C";

        Normalizer.Form[] oneUnicodeForms = { Normalizer.Form.NFC, Normalizer.Form.NFKC };
        for (CharSequence seq: buildTestCharSequences(testString, oneUnicodeForms)) {
            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

            String testLabel = buildTestMessage(seq);

            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(0));
            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(1));
            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(2));
            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(3));
            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(4));
            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(5));
            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(6));
            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(7));
            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(8));

            assertEquals(testLabel, 0, layout.getOffsetToRightOf(0));
            assertEquals(testLabel, 0, layout.getOffsetToRightOf(1));
            assertEquals(testLabel, 0, layout.getOffsetToRightOf(2));
            assertEquals(testLabel, 2, layout.getOffsetToRightOf(3));
            assertEquals(testLabel, 2, layout.getOffsetToRightOf(4));
            assertEquals(testLabel, 4, layout.getOffsetToRightOf(5));
            assertEquals(testLabel, 4, layout.getOffsetToRightOf(6));
            assertEquals(testLabel, 6, layout.getOffsetToRightOf(7));
            assertEquals(testLabel, 6, layout.getOffsetToRightOf(8));
        }
    }

    public void testGetOffset_UNICODE_Bidi() {
        // String having RTL characters and LTR characters

        // LTR Context
        // The first and last two characters are LTR characters.
        String testString = "\u0061\u0062\u05DE\u05E1\u05E2\u0063\u0064";
        // Logical order: [L1] [L2] [R1] [R2] [R3] [L3] [L4]
        //               0    1    2    3    4    5    6    7
        // Display order: [L1] [L2] [R3] [R2] [R1] [L3] [L4]
        //               0    1    2    4    3    5    6    7
        // [L?] means ?th LTR character and [R?] means ?th RTL character.
        for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

            String testLabel = buildTestMessage(seq);

            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(2));
            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(3));
            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(4));
            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(5));
            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(6));
            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(7));

            assertEquals(testLabel, 1, layout.getOffsetToRightOf(0));
            assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
            assertEquals(testLabel, 4, layout.getOffsetToRightOf(2));
            assertEquals(testLabel, 5, layout.getOffsetToRightOf(3));
            assertEquals(testLabel, 3, layout.getOffsetToRightOf(4));
            assertEquals(testLabel, 6, layout.getOffsetToRightOf(5));
            assertEquals(testLabel, 7, layout.getOffsetToRightOf(6));
            assertEquals(testLabel, 7, layout.getOffsetToRightOf(7));
        }

        // RTL Context
        // The first and last two characters are RTL characters.
        String testString2 = "\u05DE\u05E1\u0063\u0064\u0065\u05DE\u05E1";
        // Logical order: [R1] [R2] [L1] [L2] [L3] [R3] [R4]
        //               0    1    2    3    4    5    6    7
        // Display order: [R4] [R3] [L1] [L2] [L3] [R2] [R1]
        //               7    6    5    3    4    2    1    0
        // [L?] means ?th LTR character and [R?] means ?th RTL character.
        for (CharSequence seq: buildTestCharSequences(testString2, Normalizer.Form.values())) {
            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);

            String testLabel = buildTestMessage(seq);

            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(0));
            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(1));
            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(2));
            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(3));
            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(4));
            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(5));
            assertEquals(testLabel, 7, layout.getOffsetToLeftOf(6));
            assertEquals(testLabel, 7, layout.getOffsetToLeftOf(7));

            assertEquals(testLabel, 0, layout.getOffsetToRightOf(0));
            assertEquals(testLabel, 0, layout.getOffsetToRightOf(1));
            assertEquals(testLabel, 1, layout.getOffsetToRightOf(2));
            assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
            assertEquals(testLabel, 2, layout.getOffsetToRightOf(4));
            assertEquals(testLabel, 3, layout.getOffsetToRightOf(5));
            assertEquals(testLabel, 5, layout.getOffsetToRightOf(6));
            assertEquals(testLabel, 6, layout.getOffsetToRightOf(7));
        }
    }
}
