/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jface.text.tests;

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

import java.util.Iterator;

import org.junit.Before;
import org.junit.Test;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;

import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextPresentation;

public class TextPresentationTest {

	private static final int NORMAL= SWT.NORMAL;
	private static final int BOLD= SWT.BOLD;
//	private static final int ITALIC= SWT.ITALIC;

	private TextPresentation fTextPresentation;
	private StyleRange[] fAllRanges;
	private StyleRange[] fNonDefaultRanges;

	@Before
	public void setUp() {
		setUpStyleRanges();
		setUpTextPresentation();
	}

	private void setUpStyleRanges() {
		fAllRanges= new StyleRange[] {
			createStyleRange(  0,   4, NORMAL),
			createStyleRange(  4,  20, BOLD),
			createStyleRange( 20,  47, NORMAL),
			createStyleRange( 47,  54, BOLD),
			createStyleRange( 54,  96, NORMAL),
			createStyleRange( 96, 102, BOLD),
			createStyleRange(102, 140, NORMAL)
		};

		fNonDefaultRanges= new StyleRange[] {
			createStyleRange(  4,  20, BOLD),
			createStyleRange( 47,  54, BOLD),
			createStyleRange( 96, 102, BOLD)
		};
	}

	private void setUpTextPresentation() {
		fTextPresentation= new TextPresentation();
		fTextPresentation.setDefaultStyleRange(createStyleRange(0, 140, NORMAL));
		for (StyleRange fAllRange : fAllRanges) {
			fTextPresentation.addStyleRange(fAllRange);
		}
	}

	private StyleRange createStyleRange(int start, int end, int style) {
		return createStyleRange(start, end, null, null, style);
	}

	private StyleRange createStyleRange(int start, int end, Color foreground, Color background, int style) {
		return new StyleRange(start, end - start, foreground, background, style);
	}

	private StyleRange createStyleRange(int start, int end, int foreground, int background, int style) {
		return createStyleRange(start, end, createColor(foreground, foreground, foreground), createColor(background, background, background), style);
	}

	private Display fDisplay= Display.getDefault();

	/**
	 * Creates a new color.
	 * 
	 * @param red the amount of red in the color
	 * @param green the amount of green in the color
	 * @param blue the amount of blue in the color
	 * @return <code>null</code> if any of the parameters is smaller than 0 or greater than 255
	 */
	private Color createColor(int red, int green, int blue) {
		if (red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255)
			return null;
		return new Color(fDisplay, red, green, blue);
	}

	private void checkRegions(StyleRange[] expectedAllRanges, StyleRange[] expectedNonDefaultRanges) {
		Iterator<StyleRange> e= fTextPresentation.getAllStyleRangeIterator();
		for (StyleRange expectedAllRange : expectedAllRanges) {
			assertTrue(e.hasNext());
			assertEquals(expectedAllRange, e.next());
		}
		assertTrue(!e.hasNext());

		e= fTextPresentation.getNonDefaultStyleRangeIterator();
		for (StyleRange expectedNonDefaultRange : expectedNonDefaultRanges) {
			assertTrue(e.hasNext());
			assertEquals(expectedNonDefaultRange, e.next());
		}
		assertTrue(!e.hasNext());
	}

	@Test
	public void testUnclippedRegions() {
		checkRegions(fAllRanges, fNonDefaultRanges);
	}
	
	@Test
	public void testClippedRegions1() {
		fTextPresentation.setResultWindow(new Region(0, 140));
		checkRegions(fAllRanges, fNonDefaultRanges);
	}

	@Test
	public void testClippedRegions2() {

		fTextPresentation.setResultWindow(new Region(30, 70));

		StyleRange[] expectedAllRanges= new StyleRange[] {
			createStyleRange(  0, 17, NORMAL),
			createStyleRange( 17, 24, BOLD),
			createStyleRange( 24, 66, NORMAL),
			createStyleRange( 66, 70, BOLD)
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
			createStyleRange( 17, 24, BOLD),
			createStyleRange( 66, 70, BOLD)
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range at start of first existing range.
	 */
	@Test
	public void testMergeStyleRange1() {
		StyleRange range= createStyleRange(0, 2, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(0, 2, 1, -1, NORMAL),
				createStyleRange(  2,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 20,  47, NORMAL),
				createStyleRange( 47,  54, BOLD),
				createStyleRange( 54,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(0, 2, 1, -1, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 47,  54, BOLD),
				createStyleRange( 96, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range at end of last existing range.
	 */
	@Test
	public void testMergeStyleRange2() {
		StyleRange range= createStyleRange(138, 140, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 20,  47, NORMAL),
				createStyleRange( 47,  54, BOLD),
				createStyleRange( 54,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 138, NORMAL),
				createStyleRange(138, 140, 1, -1, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 47,  54, BOLD),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(138, 140, 1, -1, NORMAL),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range at start of existing default range.
	 */
	@Test
	public void testMergeStyleRange3() {
		StyleRange range= createStyleRange(20, 22, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange(20, 22, 1, -1, NORMAL),
				createStyleRange( 22,  47, NORMAL),
				createStyleRange( 47,  54, BOLD),
				createStyleRange( 54,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange(20, 22, 1, -1, NORMAL),
				createStyleRange( 47,  54, BOLD),
				createStyleRange( 96, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range within existing default range.
	 */
	@Test
	public void testMergeStyleRange4() {
		StyleRange range= createStyleRange(22, 24, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 20,  22, NORMAL),
				createStyleRange(22, 24, 1, -1, NORMAL),
				createStyleRange( 24,  47, NORMAL),
				createStyleRange( 47,  54, BOLD),
				createStyleRange( 54,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange(22, 24, 1, -1, NORMAL),
				createStyleRange( 47,  54, BOLD),
				createStyleRange( 96, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range at end of existing default range.
	 */
	@Test
	public void testMergeStyleRange5() {
		StyleRange range= createStyleRange(45, 47, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 20,  45, NORMAL),
				createStyleRange(45, 47, 1, -1, NORMAL),
				createStyleRange( 47,  54, BOLD),
				createStyleRange( 54,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange(45, 47, 1, -1, NORMAL),
				createStyleRange( 47,  54, BOLD),
				createStyleRange( 96, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range at start of existing non-default range.
	 */
	@Test
	public void testMergeStyleRange6() {
		StyleRange range= createStyleRange(47, 49, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 20,  47, NORMAL),
				createStyleRange(47, 49, 1, -1, BOLD),
				createStyleRange( 49,  54, BOLD),
				createStyleRange( 54,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange(47, 49, 1, -1, BOLD),
				createStyleRange( 49,  54, BOLD),
				createStyleRange( 96, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range within existing non-default range.
	 */
	@Test
	public void testMergeStyleRange7() {
		StyleRange range= createStyleRange(49, 51, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 20,  47, NORMAL),
				createStyleRange( 47,  49, BOLD),
				createStyleRange(49, 51, 1, -1, BOLD),
				createStyleRange( 51,  54, BOLD),
				createStyleRange( 54,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 47,  49, BOLD),
				createStyleRange(49, 51, 1, -1, BOLD),
				createStyleRange( 51,  54, BOLD),
				createStyleRange( 96, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range at end of existing non-default range.
	 */
	@Test
	public void testMergeStyleRange8() {
		StyleRange range= createStyleRange(52, 54, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 20,  47, NORMAL),
				createStyleRange( 47,  52, BOLD),
				createStyleRange(52, 54, 1, -1, BOLD),
				createStyleRange( 54,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 47,  52, BOLD),
				createStyleRange(52, 54, 1, -1, BOLD),
				createStyleRange( 96, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range from existing default to non-default range.
	 */
	@Test
	public void testMergeStyleRange9() {
		StyleRange range= createStyleRange(45, 49, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 20,  45, NORMAL),
				createStyleRange(45, 47, 1, -1, NORMAL),
				createStyleRange(47, 49, 1, -1, BOLD),
				createStyleRange( 49,  54, BOLD),
				createStyleRange( 54,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange(45, 47, 1, -1, NORMAL),
				createStyleRange(47, 49, 1, -1, BOLD),
				createStyleRange( 49,  54, BOLD),
				createStyleRange( 96, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range from existing non-default to default range.
	 */
	@Test
	public void testMergeStyleRange10() {
		StyleRange range= createStyleRange(52, 56, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 20,  47, NORMAL),
				createStyleRange( 47,  52, BOLD),
				createStyleRange(52, 54, 1, -1, BOLD),
				createStyleRange(54, 56, 1, -1, NORMAL),
				createStyleRange( 56,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 47,  52, BOLD),
				createStyleRange(52, 54, 1, -1, BOLD),
				createStyleRange(54, 56, 1, -1, NORMAL),
				createStyleRange( 96, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range from existing default over non-default to default range.
	 */
	@Test
	public void testMergeStyleRange11() {
		StyleRange range= createStyleRange(45, 56, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 20,  45, NORMAL),
				createStyleRange(45, 47, 1, -1, NORMAL),
				createStyleRange(47, 54, 1, -1, BOLD),
				createStyleRange(54, 56, 1, -1, NORMAL),
				createStyleRange( 56,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange(45, 47, 1, -1, NORMAL),
				createStyleRange(47, 54, 1, -1, BOLD),
				createStyleRange(54, 56, 1, -1, NORMAL),
				createStyleRange( 96, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range from existing non-default over default to non-default range.
	 */
	@Test
	public void testMergeStyleRange12() {
		StyleRange range= createStyleRange(52, 98, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 20,  47, NORMAL),
				createStyleRange( 47,  52, BOLD),
				createStyleRange(52, 54, 1, -1, BOLD),
				createStyleRange(54, 96, 1, -1, NORMAL),
				createStyleRange(96, 98, 1, -1, BOLD),
				createStyleRange( 98, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 47,  52, BOLD),
				createStyleRange(52, 54, 1, -1, BOLD),
				createStyleRange(54, 96, 1, -1, NORMAL),
				createStyleRange(96, 98, 1, -1, BOLD),
				createStyleRange( 98, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range over existing default range.
	 */
	@Test
	public void testMergeStyleRange13() {
		StyleRange range= createStyleRange(20, 47, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange(20, 47, 1, -1, NORMAL),
				createStyleRange( 47,  54, BOLD),
				createStyleRange( 54,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange(20, 47, 1, -1, NORMAL),
				createStyleRange( 47,  54, BOLD),
				createStyleRange( 96, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	/**
	 * Merge range over existing non-default range.
	 */
	@Test
	public void testMergeStyleRange14() {
		StyleRange range= createStyleRange(47, 54, 1, -1, NORMAL);
		fTextPresentation.mergeStyleRange(range);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(  0,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange( 20,  47, NORMAL),
				createStyleRange(47, 54, 1, -1, BOLD),
				createStyleRange( 54,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 140, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(  4,  20, BOLD),
				createStyleRange(47, 54, 1, -1, BOLD),
				createStyleRange( 96, 102, BOLD),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

	@Test
	public void testMergeStyleRanges1() {
		StyleRange[] ranges= new StyleRange[] {
				createStyleRange(0, 2, 1, -1, NORMAL), // at start of first existing
				createStyleRange(20, 22, 1, -1, NORMAL), // at start of existing default
				createStyleRange(24, 26, 1, -1, NORMAL), // within existing default
				createStyleRange(45, 47, 1, -1, NORMAL), // at end of existing default
				createStyleRange(47, 49, 1, -1, NORMAL), // at start of existing non-default
				createStyleRange(50, 51, 1, -1, NORMAL), // within existing non-default
				createStyleRange(52, 54, 1, -1, NORMAL), // at end of existing non-default
				createStyleRange(138, 140, 1, -1, NORMAL), // at end of last existing
		};
		fTextPresentation.mergeStyleRanges(ranges);

		StyleRange[] expectedAllRanges= new StyleRange[] {
				createStyleRange(0, 2, 1, -1, NORMAL),
				createStyleRange(  2,   4, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange(20, 22, 1, -1, NORMAL),
				createStyleRange( 22,  24, NORMAL),
				createStyleRange(24, 26, 1, -1, NORMAL),
				createStyleRange( 26,  45, NORMAL),
				createStyleRange(45, 47, 1, -1, NORMAL),
				createStyleRange(47, 49, 1, -1, BOLD),
				createStyleRange( 49,  50, BOLD),
				createStyleRange(50, 51, 1, -1, BOLD),
				createStyleRange( 51,  52, BOLD),
				createStyleRange(52, 54, 1, -1, BOLD),
				createStyleRange( 54,  96, NORMAL),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(102, 138, NORMAL),
				createStyleRange(138, 140, 1, -1, NORMAL),
		};

		StyleRange[] expectedNonDefaultRanges= new StyleRange[] {
				createStyleRange(0, 2, 1, -1, NORMAL),
				createStyleRange(  4,  20, BOLD),
				createStyleRange(20, 22, 1, -1, NORMAL),
				createStyleRange(24, 26, 1, -1, NORMAL),
				createStyleRange(45, 47, 1, -1, NORMAL),
				createStyleRange(47, 49, 1, -1, BOLD),
				createStyleRange( 49,  50, BOLD),
				createStyleRange(50, 51, 1, -1, BOLD),
				createStyleRange( 51,  52, BOLD),
				createStyleRange(52, 54, 1, -1, BOLD),
				createStyleRange( 96, 102, BOLD),
				createStyleRange(138, 140, 1, -1, NORMAL),
		};

		checkRegions(expectedAllRanges, expectedNonDefaultRanges);
	}

}
