/*******************************************************************************
 * Copyright (c) 2015, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Red Hat Inc. - Bug 462631
 *******************************************************************************/
package org.eclipse.swt.tests.junit;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.TextLayout;
import org.eclipse.swt.graphics.TextStyle;
import org.eclipse.swt.widgets.Display;
import org.junit.Before;
import org.junit.Test;


public class Test_org_eclipse_swt_graphics_TextLayout {
	Display display;
	
@Before
public void setUp() {
	display = Display.getDefault();
}

/*Test suite start*/
@Test
public void test_getLevel() {
	TextLayout layout = new TextLayout(display);
	String text = "abc55\u05e9\u05e066";
	layout.setText(text);
	assertEquals(0, layout.getLevel(0));
	assertEquals(0, layout.getLevel(2));
//	assertEquals(0, layout.getLevel(4)); //bug in windows (uniscribe)
	assertEquals(1, layout.getLevel(5));
	assertEquals(1, layout.getLevel(6));	
	assertEquals(2, layout.getLevel(7));
	assertEquals(0, layout.getLevel(9));
	try {
		layout.getLevel(-1);
		fail("invalid range expection expected");
	} catch (Exception e) {} 
	try {
		layout.getLevel(text.length() + 1);
		fail("invalid range expection expected");
	} catch (Exception e) {} 
	layout.dispose();
}

@Test
public void test_getSegments() {
	TextLayout layout = new TextLayout(display);
	layout.setText("AB");
	String[] messages = {"no segments", "segments", "segments (duplicate at 0)", "segments (duplicate at 1)", "segments (duplicate at 2)"};
	int[][] segments = {null, {0,1,2}, {0,0,1,2}, {0,1,1,2}, {0,1,2,2}};
	for (int i = 0; i < segments.length; i++) {
		String m = messages[i];
		layout.setSegments(segments[i]);
		assertEquals(m, 1, layout.getNextOffset(0, SWT.MOVEMENT_CLUSTER));
		assertEquals(m, 2, layout.getNextOffset(1, SWT.MOVEMENT_CLUSTER));
		assertEquals(m, 2, layout.getNextOffset(2, SWT.MOVEMENT_CLUSTER));
		assertEquals(m, 1, layout.getPreviousOffset(2, SWT.MOVEMENT_CLUSTER));
		assertEquals(m, 0, layout.getPreviousOffset(1, SWT.MOVEMENT_CLUSTER));
		assertEquals(m, 0, layout.getPreviousOffset(0, SWT.MOVEMENT_CLUSTER));
	}
	
	// Bug 295513
	layout.setText("Line");
	layout.setAscent(20);
	layout.setDescent(6);
	layout.setSegments(new int[] {0, layout.getText().length()});
	layout.getBounds();
	layout.dispose();
	layout = new TextLayout(display);
	
	// Bug 241482 comment 74
	layout.setText("word word word");
	layout.setSegments(new int[] {0, 5, 10});
	int offset = 0;
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(5, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(10, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(14, offset);

	layout.setWidth(layout.getBounds().width / 2);
	layout.setAscent(20);
	layout.setDescent(6);
	offset = 0;
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(5, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(10, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(14, offset);
	layout.dispose();
	layout = new TextLayout(display);


	//Bug 241482 comment 64
	layout.setText("\nAB");
	layout.setSegments(new int[] {0, 1, 3});
	int[] expected = new int[] {0, 1, 3};
	int[] offsets = layout.getLineOffsets();
	for (int i = 0; i < offsets.length; i++) {
		assertEquals(" i = " + i, expected[i], offsets[i]);    
	}
	layout.dispose();
	layout = new TextLayout(display);
	
	//Bug 241482 comment  80
	layout.setText("MNMNMN");
	layout.setSegments(new int[] {0,1,6});
	layout.getBounds();
	assertEquals(layout.getText().length() - 1, layout.getOffset(layout.getBounds().width, 0, null));
	layout.setAscent(9);
	assertEquals(layout.getText().length() - 1, layout.getOffset(layout.getBounds().width, 0, null));
	layout.dispose();
	layout = new TextLayout(display);
	
	//Bug 486600 comment 2
	layout.setText("Abcdef\nGhij\nKl");
	Rectangle bounds1 = layout.getBounds(0, 6 - 1);
	int[] trailing = new int[1];
	offset = layout.getOffset(bounds1.width, bounds1.height + 2, trailing);
	assertEquals(10, offset);
	assertEquals(1, trailing[0]);
	layout.dispose();
	layout = new TextLayout(display);
	
	layout.setText("AbcdefGhijKl");
	layout.setSegments(new int[] {6, 10});
	layout.setSegmentsChars(new char[] {'\n', '\n'});
	bounds1 = layout.getBounds(0, 6 - 1);
	trailing = new int[1];
	offset = layout.getOffset(bounds1.width, bounds1.height + 2, trailing);
	assertEquals(9, offset);
	assertEquals(1, trailing[0]);
	layout.dispose();
	layout = new TextLayout(display);
	
	//Lina's bug (bug 241482, comment 37)
	boolean doit = false; //known to be broken
	if (doit) {
		int length = layout.getText().length();
		layout.setSegments(new int[] { length});
		trailing = new int [1];
		int width = layout.getBounds().width + 20;
		assertEquals("hit test to the left", 0, layout.getOffset(0, 0, trailing));
		assertEquals("hit test to the left (trailing)", 0, trailing[0]);
		assertEquals("hit test to the right", length - 1, layout.getOffset(width, 0, trailing));
		assertEquals("hit test to the right (trailing)", 1, trailing[0]);
		layout.setSegmentsChars(new char[] { '*' });
		assertEquals("hit test to the left", 0, layout.getOffset(0, 0, trailing));
		assertEquals("hit test to the left (trailing)", 0, trailing[0]);
		assertEquals("hit test to the right", length - 1, layout.getOffset(width, 0, trailing));
		assertEquals("hit test to the right (trailing)", 1, trailing[0]);
	}

    /* wrong: internal testing */
//	String text = "AB";
//	int textLength = text.length();
//	layout.setText(text);
//	messages = new String [] { 
//			"no segments", 
//			"segments",
//			"segments (duplicate at 0)", 
//			"segments (duplicate at 1)",
//			"segments (duplicate at 2)" };
//	segments = new int [][] { 
//			null, 
//			{ 0, 1, 2 }, 
//			{ 0, 0, 1, 2 }, 
//			{ 0, 1, 1, 2 },
//			{ 0, 1, 2, 2 } };
//	int[][] translatedOffsets = { 
//			{ 0, 1, 2 }, 
//			{ 1, 3, 5 }, 
//			{ 2, 4, 6 },
//			{ 1, 4, 6 }, 
//			{ 1, 3, 6 } };
//	int[][] untranslatedOffsets = { 
//			{ 0, 1, 2 }, 
//			{ 0, 0, 1, 1, 2, 2 },
//			{ 0, 0, 0, 1, 1, 2, 2 }, 
//			{ 0, 0, 1, 1, 1, 2, 2 },
//			{ 0, 0, 1, 1, 2, 2, 2 } };
//	for (int i = 0; i < segments.length; i++) {
//		layout.setSegments(segments[i]);
//		layout.getBounds();
//		for (int j = 0; j <= textLength; j++) {
//			assertEquals(messages[i] + " j = " + j,	translatedOffsets[i][j], layout.translateOffset(j));
//		}
//		for (int j = 0, n = layout.getSegments() == null ? 0 : textLength + layout.getSegments().length; j < n; j++) {
//			assertEquals(messages[i] + " j = " + j,	untranslatedOffsets[i][j], layout.untranslateOffset(j));
//		}
//	}
	layout.dispose();
}

@Test
public void test_getSegmentsChars() {
	if (SwtTestUtil.isCocoa) {
		// TODO Fix Cocoa failure.
		if (SwtTestUtil.verbose) {
			System.out
					.println("Excluded test_getSegmentsChars(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_TextLayout).");
		}
		return;
	}
	TextLayout layout = new TextLayout(display);
	String text = "ab\u05d0\u05d1.\u05d2cd";
	int textLength = text.length();
	layout.setText(text);

	String[] messages = {
			"no segments", 
			"Embedding RTL dir test", 
			"Embedding LTR dir test",
			"LRO test", 
			"RLO test", 
			"Traditional segments", 
			"Traditional segments invalid"};
	int[][] segments = {
			null, 
			{0, 0, 4, 4, 5, 5, 8, 8}, 
			{0, 0, 4, 4, 5, 5, 8, 8},
			{0, textLength}, 
			{0, textLength}, 
			{0, 4, 8}, 
			{1}};
	char[][] chars = {
			null, 
			{'\u202a', '\u202b', '\u202c', '\u200e', '\u200e', '\u202b', '\u202c', '\u202c'},
			{'\u202b', '\u202a', '\u202c', '\u200f', '\u200f', '\u202a', '\u202c', '\u202c'},
			{0x202d, 0x202c}, 
			{0x202e, 0x202c},
			null, 
			null};
	int[][] levels = {
			{0, 0, 1, 1, 1, 1, 0, 0}, 
			{4, 4, 3, 3, 2, 3, 4, 4}, 
			{2, 2, 3, 3, 1, 3, 2, 2},
			{2, 2, 2, 2, 2, 2, 2, 2}, //Fails on cocoa, where it returns {0, 0, 0, 0, 0, 0, 0, 0}
			{1, 1, 1, 1, 1, 1, 1, 1}, 
			{0, 0, 1, 1, 0, 1, 0, 0},
			{0, 0, 1, 1, 1, 1, 0, 0}};
	int[] offsets = {0, textLength};
	for (int i = 0; i < segments.length; i++) {
		layout.setSegments(segments[i]);
		layout.setSegmentsChars(chars[i]);
		assertArrayEquals("Test line offsets" + ": group: " + i, offsets, layout.getLineOffsets());
		for (int j = 0; j < textLength; j++) {
			assertEquals(messages[i] + ": group: " + i + ", index: " + j, levels[i][j], layout.getLevel(j));
		}
	}
	layout.dispose();
}

@Test
public void test_getLineOffsets() {
	TextLayout layout = new TextLayout(display);
	String text = "0123456\n890123\n";
	layout.setText(text);
	int[] offsets = layout.getLineOffsets();
	int[] expected = new int [] {0, 8, 15, 15};
	for (int i = 0; i < offsets.length; i++) {
		assertEquals(expected[i], offsets[i]);	
	}
	layout.setText("");
	offsets = layout.getLineOffsets();
	expected = new int [] {0, 0};
	for (int i = 0; i < offsets.length; i++) {
		assertEquals(expected[i], offsets[i]);	
	}
	layout.setText("\n");
	offsets = layout.getLineOffsets();
	expected = new int [] {0, 1, 1};
	for (int i = 0; i < offsets.length; i++) {
		assertEquals(expected[i], offsets[i]);	
	}
	layout.setText("WMWM");
	int width = layout.getBounds().width;
	layout.setWidth(width / 4 + 1);
	offsets = layout.getLineOffsets();
	expected = new int [] {0, 1, 2, 3, 4};
	for (int i = 0; i < offsets.length; i++) {
		assertEquals(expected[i], offsets[i]);	
	}
	layout.setWidth(width / 2 + 1);
	offsets = layout.getLineOffsets();
	expected = new int [] {0, 2, 4};
	for (int i = 0; i < offsets.length; i++) {
		assertEquals(expected[i], offsets[i]);	
	}
    
	layout.dispose();
}

@Test
public void test_getLineIndex() {
	if (SwtTestUtil.isCocoa) {
		// TODO Fix Cocoa failure.
		if (SwtTestUtil.verbose) {
			System.out
					.println("Excluded test_getLineIndex(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_TextLayout).");
		}
		return;
	}
	TextLayout layout = new TextLayout(display);
	String text = "0123456\n890123\n";
	layout.setText(text);
	assertEquals(0, layout.getLineIndex(0));
	assertEquals(0, layout.getLineIndex(5));
	assertEquals(0, layout.getLineIndex(7));
	assertEquals(1, layout.getLineIndex(8));
	assertEquals(1, layout.getLineIndex(12));
	assertEquals(1, layout.getLineIndex(14));
	assertEquals(2, layout.getLineIndex(15));
	try {
		layout.getLineIndex(-1);
		fail("invalid range expection expected");
	} catch (Exception e) {} 
	try {
		layout.getLineIndex(text.length() + 1);
		fail("invalid range expection expected");
	} catch (Exception e) {} 
	layout.dispose();
}

@Test
public void test_getLineBounds() {
	if (SwtTestUtil.isCocoa) {
		// TODO Fix Cocoa failure.
		if (SwtTestUtil.verbose) {
			System.out
					.println("Excluded test_getLineBonds(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_TextLayout).");
		}
		return;
	}
	TextLayout layout = new TextLayout(display);
	String text = "0123456\n890123\n";
	layout.setText(text);
	Rectangle rect0  = layout.getLineBounds(0);
	Rectangle rect1  = layout.getLineBounds(1);
	Rectangle rect2  = layout.getLineBounds(2);	
	
	assertTrue(rect0.width > rect1.width);
	assertEquals(0, rect2.width);
	assertEquals(0, rect0.x);
	assertEquals(0, rect1.x);
	assertEquals(0, rect2.x);
	Rectangle bounds = layout.getBounds();
	assertEquals(bounds.width, rect0.width);
	layout.setWidth(bounds.width);
	layout.setAlignment(SWT.CENTER);
	assertEquals(bounds, layout.getBounds());
	layout.setWidth(bounds.width + 100);
	Rectangle newRect1  = layout.getLineBounds(0);
	assertEquals(50, newRect1.x);
	layout.setAlignment(SWT.RIGHT);
	newRect1  = layout.getLineBounds(0);
	assertEquals(100, newRect1.x);
	assertEquals(bounds.height, rect0.height + rect1.height + rect2.height);
	
	try {
		layout.getLineBounds(-1);
		fail("invalid range expection expected");
	} catch (Exception e) {} 
	try {
		layout.getLineBounds(3);
		fail("invalid range expection expected");
	} catch (Exception e) {} 
	layout.dispose();
}

@Test
public void test_setStyle() {
	TextLayout layout;
	TextStyle s1, s2, s3, s4;
	s1 = new TextStyle (null, null, null);
	s2 = new TextStyle (null, null, null);
	s3 = new TextStyle (null, null, null);
	s4 = new TextStyle (null, null, null);
	
	layout = new TextLayout (display);
	layout.setText("aabbcc");
	layout.setStyle (s1, 2, 3);
	assertEquals(null, layout.getStyle(0));
	assertEquals(null, layout.getStyle(1));
	assertEquals(s1, layout.getStyle(2));
	assertEquals(s1, layout.getStyle(3));
	assertEquals(null, layout.getStyle(4));
	assertEquals(null, layout.getStyle(5));	
	layout.dispose();
	
	layout = new TextLayout (display);
	layout.setText("aabbcc");
	layout.setStyle (s1, 0, 1);
	layout.setStyle (s2, 2, 3);
	layout.setStyle (s3, 4, 5);
	assertEquals(s1, layout.getStyle(0));
	assertEquals(s1, layout.getStyle(1));
	assertEquals(s2, layout.getStyle(2));
	assertEquals(s2, layout.getStyle(3));
	assertEquals(s3, layout.getStyle(4));
	assertEquals(s3, layout.getStyle(5));	
	layout.dispose();	
	
	layout = new TextLayout (display);
	layout.setText("aabbcc");
	layout.setStyle (s1, 0, 1);
	layout.setStyle (s2, 2, 3);
	layout.setStyle (s3, 4, 5);
	layout.setStyle (s4, 1, 2);
	assertEquals(s1, layout.getStyle(0));
	assertEquals(s4, layout.getStyle(1));
	assertEquals(s4, layout.getStyle(2));
	assertEquals(s2, layout.getStyle(3));
	assertEquals(s3, layout.getStyle(4));
	assertEquals(s3, layout.getStyle(5));	
	layout.dispose();	
	
	layout = new TextLayout (display);
	layout.setText("aabbcc");
	layout.setStyle (s1, 0, 1);
	layout.setStyle (s2, 2, 3);
	layout.setStyle (s3, 4, 5);
	layout.setStyle (s4, 3, 4);
	assertEquals(s1, layout.getStyle(0));
	assertEquals(s1, layout.getStyle(1));
	assertEquals(s2, layout.getStyle(2));
	assertEquals(s4, layout.getStyle(3));
	assertEquals(s4, layout.getStyle(4));
	assertEquals(s3, layout.getStyle(5));	
	layout.dispose();	
	
	layout = new TextLayout (display);
	layout.setText("aabbcc");
	layout.setStyle (s1, 0, 1);
	layout.setStyle (s2, 2, 3);
	layout.setStyle (s3, 4, 5);
	layout.setStyle (s4, 1, 4);	
	assertEquals(s1, layout.getStyle(0));
	assertEquals(s4, layout.getStyle(1));
	assertEquals(s4, layout.getStyle(2));
	assertEquals(s4, layout.getStyle(3));
	assertEquals(s4, layout.getStyle(4));
	assertEquals(s3, layout.getStyle(5));	
	layout.dispose();	

	layout = new TextLayout (display);
	layout.setText("aabbcc");
	layout.setStyle (s1, 0, 0);
	layout.setStyle (s2, 1, 4);
	layout.setStyle (s3, 5, 5);
	layout.setStyle (s4, 2, 3);
	assertEquals(s1, layout.getStyle(0));
	assertEquals(s2, layout.getStyle(1));
	assertEquals(s4, layout.getStyle(2));
	assertEquals(s4, layout.getStyle(3));
	assertEquals(s2, layout.getStyle(4));
	assertEquals(s3, layout.getStyle(5));
	layout.dispose();	
	
	layout = new TextLayout (display);
	layout.setText("aabbcc");
	layout.setStyle (s1, 0, 1);
	layout.setStyle (s2, 2, 3);
	layout.setStyle (s3, 4, 5);
	layout.setStyle (s4, 0, 3);
	assertEquals(s4, layout.getStyle(0));
	assertEquals(s4, layout.getStyle(1));
	assertEquals(s4, layout.getStyle(2));
	assertEquals(s4, layout.getStyle(3));
	assertEquals(s3, layout.getStyle(4));
	assertEquals(s3, layout.getStyle(5));	
	layout.dispose();	
	
	layout = new TextLayout (display);
	layout.setText("aabbcc");
	layout.setStyle (s1, 0, 0);
	layout.setStyle (s2, 1, 4);
	layout.setStyle (s3, 5, 5);
	layout.setStyle (s4, 2, 4);
	assertEquals(s1, layout.getStyle(0));
	assertEquals(s2, layout.getStyle(1));
	assertEquals(s4, layout.getStyle(2));
	assertEquals(s4, layout.getStyle(3));
	assertEquals(s4, layout.getStyle(4));
	assertEquals(s3, layout.getStyle(5));
	layout.dispose();	
	
	layout = new TextLayout (display);
	layout.setText("aabbcc");
	layout.setStyle (s1, 0, 0);
	layout.setStyle (s2, 1, 4);
	layout.setStyle (s3, 5, 5);
	layout.setStyle (s4, 1, 3);
	assertEquals(s1, layout.getStyle(0));
	assertEquals(s4, layout.getStyle(1));
	assertEquals(s4, layout.getStyle(2));
	assertEquals(s4, layout.getStyle(3));
	assertEquals(s2, layout.getStyle(4));
	assertEquals(s3, layout.getStyle(5));
	layout.dispose();	
	
	layout = new TextLayout (display);
	layout.setText("aabbcc");
	layout.setStyle (s1, 0, 1);
	layout.setStyle (s2, 2, 3);
	layout.setStyle (s3, 4, 5);
	layout.setStyle (null, 0, 5);
	assertEquals(null, layout.getStyle(0));
	assertEquals(null, layout.getStyle(1));
	assertEquals(null, layout.getStyle(2));
	assertEquals(null, layout.getStyle(3));
	assertEquals(null, layout.getStyle(4));
	assertEquals(null, layout.getStyle(5));	
	layout.dispose();		
	
	layout = new TextLayout (display);
	layout.setText("aabbcc");
	layout.setStyle (s1, 0, 1);
	layout.setStyle (s2, 2, 3);
	layout.setStyle (s3, 4, 5);
	layout.setStyle (s4, 0, 5);
	assertEquals(s4, layout.getStyle(0));
	assertEquals(s4, layout.getStyle(1));
	assertEquals(s4, layout.getStyle(2));
	assertEquals(s4, layout.getStyle(3));
	assertEquals(s4, layout.getStyle(4));
	assertEquals(s4, layout.getStyle(5));	
	layout.dispose();	
	
	layout = new TextLayout (display);
	layout.setText("aabbcc");
	layout.setStyle (s1, 2, 2);
	layout.setStyle (s2, 2, 3);
	layout.setStyle (null, 3, 3);
	assertEquals(null, layout.getStyle(0));
	assertEquals(null, layout.getStyle(1));
	assertEquals(s2, layout.getStyle(2));
	assertEquals(null, layout.getStyle(3));
	assertEquals(null, layout.getStyle(4));
	assertEquals(null, layout.getStyle(5));	
	layout.dispose();		
}

@Test
public void test_getAlignment() {
	TextLayout layout = new TextLayout(display);
	layout.setAlignment(SWT.LEFT);
	assertEquals(SWT.LEFT, layout.getAlignment());
	layout.setAlignment(SWT.CENTER);
	assertEquals(SWT.CENTER, layout.getAlignment());
	layout.setAlignment(SWT.RIGHT);
	assertEquals(SWT.RIGHT, layout.getAlignment());
	
	layout.setAlignment(SWT.PUSH);
	assertEquals(SWT.RIGHT, layout.getAlignment());

	layout.setAlignment(SWT.CENTER| SWT.PUSH);
	assertEquals(SWT.CENTER, layout.getAlignment());
	
	layout.setAlignment(SWT.CENTER| SWT.LEFT | SWT.RIGHT);
	assertEquals(SWT.LEFT, layout.getAlignment());

	layout.dispose();
}

@Test
public void test_getOrientation() {
	TextLayout layout = new TextLayout(display);
	layout.setOrientation(SWT.LEFT_TO_RIGHT);
	assertEquals(SWT.LEFT_TO_RIGHT, layout.getOrientation());
	layout.setOrientation(SWT.RIGHT_TO_LEFT);
	assertEquals(SWT.RIGHT_TO_LEFT, layout.getOrientation());
	
	layout.setOrientation(SWT.PUSH);
	assertEquals(SWT.RIGHT_TO_LEFT, layout.getOrientation());

	layout.setOrientation(SWT.LEFT_TO_RIGHT | SWT.PUSH);
	assertEquals(SWT.LEFT_TO_RIGHT, layout.getOrientation());
	
	layout.setOrientation(SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
	assertEquals(SWT.LEFT_TO_RIGHT, layout.getOrientation());

	layout.dispose();
}

@Test
public void test_getText() {
	TextLayout layout = new TextLayout(display);
	String text = "Test";
	layout.setText(text);
	assertEquals(text, layout.getText());
	layout.dispose();
}

@Test
public void test_getLocation() {
	if (SwtTestUtil.isCocoa) {
		// TODO Fix Cocoa failure.
		if (SwtTestUtil.verbose) {
			System.out
					.println("Excluded test_getLocation(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_TextLayout).");
		}
		return;
	}
	TextLayout layout = new TextLayout(display);
	String text = "AB\u05E9\u05E0";
	layout.setText(text);
	assertEquals(0, layout.getLocation(0, false).x);
	assertEquals(layout.getLocation(0, true).x, layout.getLocation(1, false).x);
	assertEquals(layout.getLocation(2, false).x, layout.getLineBounds(0).width);
	assertEquals(layout.getLocation(2, true).x, layout.getLocation(3, false).x);
	assertEquals(layout.getLocation(3, true).x, layout.getLocation(1, true).x);	

	assertEquals(layout.getLocation(4, false).x, layout.getLineBounds(0).width);
	assertEquals(layout.getLocation(4, true).x, layout.getLineBounds(0).width);
	layout.dispose();
}

@Test
public void test_getNextOffset() {
	if (SwtTestUtil.isCocoa) {
		// TODO Fix Cocoa failure.
		if (SwtTestUtil.verbose) {
			System.out
					.println("Excluded test_getNextOffset(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_TextLayout).");
		}
		return;
	}
	TextLayout layout = new TextLayout(display);
	String text;
	int offset;
	
	text = "word word word";
	layout.setText(text);
	offset = 0;
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_END);
	assertEquals(4, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_END);
	assertEquals(9, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_END);
	assertEquals(14, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_WORD_END);
	assertEquals(9, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_WORD_END);
	assertEquals(4, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_WORD_END);
	assertEquals(0, offset);
	assertEquals(4, layout.getNextOffset(2, SWT.MOVEMENT_WORD_END));
	assertEquals(4, layout.getNextOffset(3, SWT.MOVEMENT_WORD_END));
	assertEquals(9, layout.getNextOffset(8, SWT.MOVEMENT_WORD_END));
	assertEquals(14, layout.getNextOffset(10, SWT.MOVEMENT_WORD_END));
	assertEquals(14, layout.getNextOffset(13, SWT.MOVEMENT_WORD_END));
	assertEquals(14, layout.getNextOffset(14, SWT.MOVEMENT_WORD_END));
	assertEquals(0, layout.getPreviousOffset(0, SWT.MOVEMENT_WORD_END));
	assertEquals(0, layout.getPreviousOffset(4, SWT.MOVEMENT_WORD_END));
	assertEquals(4, layout.getPreviousOffset(5, SWT.MOVEMENT_WORD_END));
	assertEquals(9, layout.getPreviousOffset(10, SWT.MOVEMENT_WORD_END));
	assertEquals(9, layout.getPreviousOffset(11, SWT.MOVEMENT_WORD_END));

	offset = 0;
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(5, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(10, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(14, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(10, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(5, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(0, offset);
	assertEquals(5, layout.getNextOffset(2, SWT.MOVEMENT_WORD_START));
	assertEquals(5, layout.getNextOffset(4, SWT.MOVEMENT_WORD_START));
	assertEquals(10, layout.getNextOffset(9, SWT.MOVEMENT_WORD_START));
	assertEquals(14, layout.getNextOffset(10, SWT.MOVEMENT_WORD_START));
	assertEquals(14, layout.getNextOffset(13, SWT.MOVEMENT_WORD_START));
	assertEquals(14, layout.getNextOffset(14, SWT.MOVEMENT_WORD_START));
	assertEquals(0, layout.getPreviousOffset(0, SWT.MOVEMENT_WORD_START));
	assertEquals(0, layout.getPreviousOffset(3, SWT.MOVEMENT_WORD_START));
	assertEquals(0, layout.getPreviousOffset(4, SWT.MOVEMENT_WORD_START));
	assertEquals(0, layout.getPreviousOffset(5, SWT.MOVEMENT_WORD_START));
	assertEquals(5, layout.getPreviousOffset(6, SWT.MOVEMENT_WORD_START));

	
	
	text = "AB \u05E9\u05E0 CD\nHello";
	layout.setText(text);
	offset = 0;
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(3, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(6, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(8, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(6, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(3, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_WORD_START);
	assertEquals(0, offset);
	offset = 7;
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);	
	assertEquals(8, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);	
	assertEquals(9, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_WORD_START);	
	assertEquals(text.length(), offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_WORD_START);	
	assertEquals(9, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_WORD_START);	
	assertEquals(8, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_CLUSTER);	
	assertEquals(9, offset);
	offset = layout.getNextOffset(offset, SWT.MOVEMENT_CLUSTER);	
	assertEquals(10, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_CLUSTER);	
	assertEquals(9, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_CLUSTER);	
	assertEquals(8, offset);
	offset = layout.getPreviousOffset(offset, SWT.MOVEMENT_CLUSTER);	
	assertEquals(7, offset);
	for (int i = 0; i < text.length(); i++) {			
		assertEquals(i+1, layout.getNextOffset(i, SWT.MOVEMENT_CLUSTER));
	}
	for (int i = text.length(); i > 0; i--) {			
		assertEquals(i-1, layout.getPreviousOffset(i, SWT.MOVEMENT_CLUSTER));
	}
	layout.dispose();
}

@Test
public void test_getNextOffset2() {
	if (SwtTestUtil.isGTK||SwtTestUtil.isCocoa) {
		//TODO Fix GTK and Cocoa failure.
		if (SwtTestUtil.verbose) {
			System.out.println("Excluded test_getNextOffset2(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_TextLayout)");
		}
		return;
	}
	//Text thai cluster separate so it can be excluded 
	//for gtk, testing machine (rhel4) is too old to 
	//support thai.
	
    TextLayout layout = new TextLayout(display);
    layout.setText("A\u0E19\u0E49\u0E33B");
    String[] messages = {"no segments", "segments", "segments (duplicate at 0)", "segments (duplicate at 1)", "segments (duplicate at 2)",        
    					"segments (duplicate at 3)", "segments (duplicate at 4)", "segments (duplicate at 5)"};
//    int[][] segments = {null, {0, 1, 2, 3, 4, 5}, {0, 0, 1, 2, 3, 4, 5}, {0, 1, 1, 2, 3, 4, 5}, {0, 1, 2, 2, 3, 4, 5}, {0, 1, 2, 3, 3, 4, 5},
//            			{0, 1, 2, 3, 4, 4, 5}, {0, 1, 2, 3, 4, 5, 5}};
    
    int[][] segments = {null};

    for (int i = 0; i < segments.length; i++) {
        String m = messages[i];
        layout.setSegments(segments[i]);
        assertEquals(m, 1, layout.getNextOffset(0, SWT.MOVEMENT_CLUSTER));
        assertEquals(m, 4, layout.getNextOffset(1, SWT.MOVEMENT_CLUSTER));
        assertEquals(m, 5, layout.getNextOffset(4, SWT.MOVEMENT_CLUSTER));
        assertEquals(m, 4, layout.getPreviousOffset(5, SWT.MOVEMENT_CLUSTER));
        assertEquals(m, 1, layout.getPreviousOffset(4, SWT.MOVEMENT_CLUSTER));
        assertEquals(m, 0, layout.getPreviousOffset(1, SWT.MOVEMENT_CLUSTER));
    }
    layout.dispose();
}

@Test
public void test_getLineSpacing() {
	TextLayout layout = new TextLayout(display);
	layout.setSpacing(10);
	assertEquals(10, layout.getSpacing());
	layout.setSpacing(Short.MAX_VALUE);
	assertEquals(Short.MAX_VALUE, layout.getSpacing());
	layout.setSpacing(50);
	assertEquals(50, layout.getSpacing());
	try {
		layout.setSpacing(-1);
		fail("invalid range expection expected");
	} catch (Exception e) {} 	
	assertEquals(50, layout.getSpacing());	
	layout.setSpacing(0);
	assertEquals(0, layout.getSpacing());
	layout.dispose();
}

@Test
public void test_getOffset() {
	boolean isCocoa = SwtTestUtil.isCocoa;
	if (isCocoa) {
		// TODO Fix Cocoa failure.
		if (SwtTestUtil.verbose) {
			System.out
					.println("Partially excluded test_getOffset(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_TextLayout).");
		}
	}
	TextLayout layout = new TextLayout(display);
	String text = "AB \u05E9\u05E0 CD\nHello";
	layout.setText(text);	
	int[] trailing = new int[1];
	
	assertEquals(0, layout.getOffset(0, 0, trailing));
	assertEquals(0, trailing[0]);
	Point point = layout.getLocation(0, true);
	assertEquals(1, layout.getOffset(point.x + 1, 0, trailing));	
	assertEquals(0, trailing[0]);	
	point = layout.getLocation(1, false);
	assertEquals(0, layout.getOffset(point.x - 1, 0, trailing));
	assertEquals(1, trailing[0]);
	point = layout.getLocation(2, true);
	assertEquals(4, layout.getOffset(point.x + 1, 0, trailing));	
	assertEquals(1, trailing[0]);
	point = layout.getLocation(4, true);
	assertEquals(2, layout.getOffset(point.x - 1, 0, trailing));	
	assertEquals(1, trailing[0]);	
	point = layout.getLocation(4, false);
	assertEquals(3, layout.getOffset(point.x + 1, 0, trailing));	
	assertEquals(1, trailing[0]);
	
	Rectangle bounds = layout.getBounds();
	layout.setWidth(bounds.width + 100);
	layout.setAlignment(SWT.CENTER);

	assertEquals(0, layout.getOffset(0, 0, trailing));
	assertEquals(0, trailing[0]);
	point = layout.getLocation(0, true);
	assertEquals(1, layout.getOffset(point.x + 1, 0, trailing));	
	assertEquals(0, trailing[0]);	
	point = layout.getLocation(1, false);
	assertEquals(0, layout.getOffset(point.x - 1, 0, trailing));
	assertEquals(1, trailing[0]);
	point = layout.getLocation(2, true);
	assertEquals(4, layout.getOffset(point.x + 1, 0, trailing));	
	assertEquals(1, trailing[0]);
	point = layout.getLocation(4, true);
	assertEquals(2, layout.getOffset(point.x - 1, 0, trailing));	
	assertEquals(1, trailing[0]);	
	point = layout.getLocation(4, false);
	assertEquals(3, layout.getOffset(point.x + 1, 0, trailing));	
	assertEquals(1, trailing[0]);

	layout.setAlignment(SWT.RIGHT);

	assertEquals(0, layout.getOffset(0, 0, trailing));
	assertEquals(0, trailing[0]);
	point = layout.getLocation(0, true);
	assertEquals(1, layout.getOffset(point.x + 1, 0, trailing));	
	assertEquals(0, trailing[0]);	
	point = layout.getLocation(1, false);
	assertEquals(0, layout.getOffset(point.x - 1, 0, trailing));
	assertEquals(1, trailing[0]);
	point = layout.getLocation(2, true);
	assertEquals(4, layout.getOffset(point.x + 1, 0, trailing));	
	assertEquals(1, trailing[0]);
	point = layout.getLocation(4, true);
	assertEquals(2, layout.getOffset(point.x - 1, 0, trailing));	
	if (!isCocoa) assertEquals(1, trailing[0]);	
	point = layout.getLocation(4, false);
	assertEquals(3, layout.getOffset(point.x + 1, 0, trailing));	
	assertEquals(1, trailing[0]);
	
	text = "Text";
	layout.setText(text);
	int width = layout.getBounds().width;
	layout.setAlignment(SWT.LEFT);
	assertEquals(0, layout.getOffset(1, 0, null));
	assertEquals(text.length()-1, layout.getOffset(width-1, 0, null));
	layout.setWidth(width + 100 );
	layout.setAlignment(SWT.CENTER);
	assertEquals(0, layout.getOffset(1+50, 0, null));
	assertEquals(text.length()-1, layout.getOffset(width-1+50, 0, null));
	layout.setAlignment(SWT.RIGHT);
	assertEquals(0, layout.getOffset(1+100, 0, null));
	assertEquals(text.length()-1, layout.getOffset(width-1+100, 0, null));
	
	layout.dispose();
}

@Test
public void test_getTabs() {
	TextLayout layout = new TextLayout(display);
	assertEquals(null, layout.getTabs());
	int[] tabs = new int[] {8, 18, 28, 38, 50, 80};
	layout.setTabs(tabs);
	int[] result = layout.getTabs();
	assertEquals(tabs.length, result.length);
	for (int i = 0; i < result.length; i++) {		
		assertEquals("pos: " + i, tabs[i], result[i]);
	}
	layout.setTabs(null);
	assertEquals(null, layout.getTabs());
	layout.dispose();
}

@Test
public void test_getTextDirection() {
	if (!SwtTestUtil.isWindows) {
		// TODO Fix GTK and Cocoa failure.
		if (SwtTestUtil.verbose) {
			System.out
					.println("Excluded test_getTextDirection(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_TextLayout).");
		}
		return;
	}
	int[] styles = {SWT.LEFT_TO_RIGHT, SWT.RIGHT_TO_LEFT, SWT.NONE, -1};
	int n = styles.length;
	int prevDirection = SWT.NONE;
	TextLayout layout = new TextLayout(display);
	for (int i = 0; i < n; i++) {
		int orientation = styles[i];
		if (orientation != -1) {
			layout.setOrientation(orientation);
			if (orientation != 0) prevDirection = orientation;
		}
		for (int j = n - 1; j >= 0; j--) {
			int direction = styles[j];
			if (direction != -1) {
				layout.setTextDirection(direction);
			}
			if (direction == SWT.NONE || direction == -1) {
				assertEquals("orientation: " + orientation + ", text direction: " + direction,
						layout.getTextDirection(), prevDirection);
			} else {
				prevDirection = direction;
				assertEquals("orientation: " + orientation + ", text direction: " + direction,
						layout.getTextDirection(), direction);
			}
		}
	}
	layout.dispose();
}
}
