/*******************************************************************************
 * Copyright (c) 2000, 2010 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
 *******************************************************************************/
package org.eclipse.draw2d.text;

import com.ibm.icu.text.BreakIterator;

import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.TextLayout;
import org.eclipse.swt.widgets.Display;

import org.eclipse.draw2d.FigureUtilities;
import org.eclipse.draw2d.TextUtilities;
import org.eclipse.draw2d.rap.swt.SWT;

/**
 * Utility class for FlowFigures.
 * 
 * @author hudsonr
 * @since 3.4
 */
public class FlowUtilities {

	interface LookAhead {
		int getWidth();
	}

	/**
	 * a singleton default instance
	 */
	public static FlowUtilities INSTANCE = new FlowUtilities();

	private static final BreakIterator INTERNAL_LINE_BREAK = BreakIterator
			.getLineInstance();
	private static TextLayout layout;

	static final BreakIterator LINE_BREAK = BreakIterator.getLineInstance();

	static boolean canBreakAfter(char c) {
		boolean result = Character.isWhitespace(c) || c == '-';
		if (!result && (c < 'a' || c > 'z')) {
			// chinese characters and such would be caught in here
			// LINE_BREAK is used here because INTERNAL_LINE_BREAK might be in
			// use
			LINE_BREAK.setText(c + "a"); //$NON-NLS-1$
			result = LINE_BREAK.isBoundary(1);
		}
		return result;
	}

	private static int findFirstDelimeter(String string) {
		int macNL = string.indexOf('\r');
		int unixNL = string.indexOf('\n');

		if (macNL == -1)
			macNL = Integer.MAX_VALUE;
		if (unixNL == -1)
			unixNL = Integer.MAX_VALUE;

		return Math.min(macNL, unixNL);
	}

	/**
	 * Gets the average character width.
	 * 
	 * @param fragment
	 *            the supplied TextFragmentBox to use for calculation. if the
	 *            length is 0 or if the width is or below 0, the average
	 *            character width is taken from standard font metrics.
	 * @param font
	 *            the font to use in case the TextFragmentBox conditions above
	 *            are true.
	 * @return the average character width
	 */
	protected float getAverageCharWidth(TextFragmentBox fragment, Font font) {
		if (fragment.getWidth() > 0 && fragment.length != 0)
			return fragment.getWidth() / (float) fragment.length;
		return FigureUtilities.getFontMetrics(font).getAverageCharWidth();
	}

	static int getBorderAscent(InlineFlow owner) {
		if (owner.getBorder() instanceof FlowBorder) {
			FlowBorder border = (FlowBorder) owner.getBorder();
			return border.getInsets(owner).top;
		}
		return 0;
	}

	static int getBorderAscentWithMargin(InlineFlow owner) {
		if (owner.getBorder() instanceof FlowBorder) {
			FlowBorder border = (FlowBorder) owner.getBorder();
			return border.getTopMargin() + border.getInsets(owner).top;
		}
		return 0;
	}

	static int getBorderDescent(InlineFlow owner) {
		if (owner.getBorder() instanceof FlowBorder) {
			FlowBorder border = (FlowBorder) owner.getBorder();
			return border.getInsets(owner).bottom;
		}
		return 0;
	}

	static int getBorderDescentWithMargin(InlineFlow owner) {
		if (owner.getBorder() instanceof FlowBorder) {
			FlowBorder border = (FlowBorder) owner.getBorder();
			return border.getBottomMargin() + border.getInsets(owner).bottom;
		}
		return 0;
	}

	/**
	 * Provides a TextLayout that can be used by the Draw2d text package for
	 * Bidi. This TextLayout should not be disposed by clients. The provided
	 * TextLayout's orientation will be LTR.
	 * 
	 * @return an SWT TextLayout that can be used for Bidi
	 * @since 3.1
	 */
	static TextLayout getTextLayout() {
		if (layout == null)
			layout = new TextLayout(Display.getDefault());
		layout.setOrientation(SWT.LEFT_TO_RIGHT);
		return layout;
	}

	/**
	 * @param frag
	 * @param string
	 * @param font
	 * @since 3.1
	 */
	private static void initBidi(TextFragmentBox frag, String string, Font font) {
		if (frag.requiresBidi()) {
			TextLayout textLayout = getTextLayout();
			textLayout.setFont(font);
			// $TODO need to insert overrides in front of string.
			textLayout.setText(string);
		}
	}

	private int measureString(TextFragmentBox frag, String string, int guess,
			Font font) {
		if (frag.requiresBidi()) {
			// The text and/or could have changed if the lookAhead was invoked.
			// This will
			// happen at most once.
			return getTextLayoutBounds(string, font, 0, guess - 1).width;
		} else
			return getTextUtilities().getTextExtents(
					string.substring(0, guess), font).width;
	}

	/**
	 * Sets up the fragment width based using the font and string passed in.
	 * 
	 * @param fragment
	 *            the text fragment whose width will be set
	 * @param font
	 *            the font to be used in the calculation
	 * @param string
	 *            the string to be used in the calculation
	 */
	final protected void setupFragment(TextFragmentBox fragment, Font font,
			String string) {
		if (fragment.getWidth() == -1 || fragment.isTruncated()) {
			int width;
			if (string.length() == 0 || fragment.length == 0)
				width = 0;
			else if (fragment.requiresBidi()) {
				width = getTextLayoutBounds(string, font, 0,
						fragment.length - 1).width;
			} else
				width = getTextUtilities().getTextExtents(
						string.substring(0, fragment.length), font).width;
			if (fragment.isTruncated())
				width += getEllipsisWidth(font);
			fragment.setWidth(width);
		}
	}

	/**
	 * Sets up a fragment and returns the number of characters consumed from the
	 * given String. An average character width can be provided as a hint for
	 * faster calculation. If a fragment's bidi level is set, a TextLayout will
	 * be used to calculate the width.
	 * 
	 * @param frag
	 *            the TextFragmentBox
	 * @param string
	 *            the String
	 * @param font
	 *            the Font used for measuring
	 * @param context
	 *            the flow context
	 * @param wrapping
	 *            the word wrap style
	 * @return the number of characters that will fit in the given space; can be
	 *         0 (eg., when the first character of the given string is a
	 *         newline)
	 */
	final protected int wrapFragmentInContext(TextFragmentBox frag,
			String string, FlowContext context, LookAhead lookahead, Font font,
			int wrapping) {
		frag.setTruncated(false);
		int strLen = string.length();
		if (strLen == 0) {
			frag.setWidth(-1);
			frag.length = 0;
			setupFragment(frag, font, string);
			context.addToCurrentLine(frag);
			return 0;
		}

		INTERNAL_LINE_BREAK.setText(string);

		initBidi(frag, string, font);
		float avgCharWidth = getAverageCharWidth(frag, font);
		frag.setWidth(-1);

		/*
		 * Setup initial boundaries within the string.
		 */
		int absoluteMin = 0;
		int max, min = 1;
		if (wrapping == ParagraphTextLayout.WORD_WRAP_HARD) {
			absoluteMin = INTERNAL_LINE_BREAK.next();
			while (absoluteMin > 0
					&& Character.isWhitespace(string.charAt(absoluteMin - 1)))
				absoluteMin--;
			min = Math.max(absoluteMin, 1);
		}
		int firstDelimiter = findFirstDelimeter(string);
		if (firstDelimiter == 0)
			min = max = 0;
		else
			max = Math.min(strLen, firstDelimiter) + 1;

		int availableWidth = context.getRemainingLineWidth();
		int guess = 0, guessSize = 0;

		while (true) {
			if ((max - min) <= 1) {
				if (min == absoluteMin
						&& context.isCurrentLineOccupied()
						&& !context.getContinueOnSameLine()
						&& availableWidth < measureString(frag, string, min,
								font)
								+ ((min == strLen && lookahead != null) ? lookahead
										.getWidth() : 0)) {
					context.endLine();
					availableWidth = context.getRemainingLineWidth();
					max = Math.min(strLen, firstDelimiter) + 1;
					if ((max - min) <= 1)
						break;
				} else
					break;
			}
			// Pick a new guess size
			// New guess is the last guess plus the missing width in pixels
			// divided by the average character size in pixels
			guess += 0.5f + (availableWidth - guessSize) / avgCharWidth;

			if (guess >= max)
				guess = max - 1;
			if (guess <= min)
				guess = min + 1;

			guessSize = measureString(frag, string, guess, font);

			if (guess == strLen && lookahead != null
					&& !canBreakAfter(string.charAt(strLen - 1))
					&& guessSize + lookahead.getWidth() > availableWidth) {
				max = guess;
				continue;
			}

			if (guessSize <= availableWidth) {
				min = guess;
				frag.setWidth(guessSize);
				if (guessSize == availableWidth)
					max = guess + 1;
			} else
				max = guess;
		}

		int result = min;
		boolean continueOnLine = false;
		if (min == strLen) {
			// Everything fits
			if (string.charAt(strLen - 1) == ' ') {
				if (frag.getWidth() == -1) {
					frag.length = result;
					frag.setWidth(measureString(frag, string, result, font));
				}
				if (lookahead.getWidth() > availableWidth - frag.getWidth()) {
					frag.length = result - 1;
					frag.setWidth(-1);
				} else
					frag.length = result;
			} else {
				continueOnLine = !canBreakAfter(string.charAt(strLen - 1));
				frag.length = result;
			}
		} else if (min == firstDelimiter) {
			// move result past the delimiter
			frag.length = result;
			if (string.charAt(min) == '\r') {
				result++;
				if (++min < strLen && string.charAt(min) == '\n')
					result++;
			} else if (string.charAt(min) == '\n')
				result++;
		} else if (string.charAt(min) == ' '
				|| canBreakAfter(string.charAt(min - 1))
				|| INTERNAL_LINE_BREAK.isBoundary(min)) {
			frag.length = min;
			if (string.charAt(min) == ' ')
				result++;
			else if (string.charAt(min - 1) == ' ') {
				frag.length--;
				frag.setWidth(-1);
			}
		} else
			out: {
				// In the middle of an unbreakable offset
				result = INTERNAL_LINE_BREAK.preceding(min);
				if (result == 0) {
					switch (wrapping) {
					case ParagraphTextLayout.WORD_WRAP_TRUNCATE:
						int truncatedWidth = availableWidth
								- getEllipsisWidth(font);
						if (truncatedWidth > 0) {
							// $TODO this is very slow. It should be using
							// avgCharWidth to go faster
							while (min > 0) {
								guessSize = measureString(frag, string, min,
										font);
								if (guessSize <= truncatedWidth)
									break;
								min--;
							}
							frag.length = min;
						} else
							frag.length = 0;
						frag.setTruncated(true);
						result = INTERNAL_LINE_BREAK.following(max - 1);
						break out;

					default:
						result = min;
						break;
					}
				}
				frag.length = result;
				if (string.charAt(result - 1) == ' ')
					frag.length--;
				frag.setWidth(-1);
			}

		setupFragment(frag, font, string);
		context.addToCurrentLine(frag);
		context.setContinueOnSameLine(continueOnLine);
		return result;
	}

	/**
	 * @see TextLayout#getBounds()
	 */
	protected Rectangle getTextLayoutBounds(String s, Font f, int start, int end) {
		TextLayout textLayout = getTextLayout();
		textLayout.setFont(f);
		textLayout.setText(s);
		return textLayout.getBounds(start, end);
	}

	/**
	 * Returns an instance of a <code>TextUtililities</code> class on which text
	 * calculations can be performed. Clients may override to customize.
	 * 
	 * @return the <code>TextUtililities</code> instance
	 * @since 3.4
	 */
	protected TextUtilities getTextUtilities() {
		return TextUtilities.INSTANCE;
	}

	/**
	 * Gets the ellipsis width.
	 * 
	 * @param font
	 *            the font to be used in the calculation
	 * @return the width of the ellipsis
	 * @since 3.4
	 */
	private int getEllipsisWidth(Font font) {
		return getTextUtilities().getTextExtents(TextFlow.ELLIPSIS, font).width;
	}
}
