/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.css2.layout;

import java.util.List;

import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
import org.eclipse.swt.graphics.Font;

/**
 * @author mengbo
 */
// NOTE: CSSTextLayout does not extends CSSFlowLayout. Since text is a little
// special,
// we don't want to do things like "preLayout()" as in CSSFlowLayout.
public class CSSTextLayout extends FlowFigureLayout {
	/**
	 * Wrapping will ONLY occur at valid line breaks
	 */
	public static final int WORD_WRAP_HARD = 0;

	/**
	 * Wrapping will always occur at the end of the available space, breaking in
	 * the middle of a word.
	 */
	public static final int WORD_WRAP_SOFT = 1;

	/**
	 * Wrapping will always occur at the end of available space, truncating a
	 * word if it doesn't fit.
	 */
	// don't support this flag
	// public static final int WORD_WRAP_TRUNCATE = 2;
	private int _wrappingStyle = WORD_WRAP_HARD;

	public CSSTextLayout(CSSTextFigure textfigure) {
		super(textfigure);
	}

	// --------------------------------------------------------------------------------------------------
	FlowBox findLastNonLineBox(LineBox box) {
		List fragments = box.getFragments();
		for (int i = fragments.size() - 1; i >= 0; i--) {
			FlowBox item = (FlowBox) fragments.get(i);
			if (item instanceof LineBox) {
				FlowBox found = findLastNonLineBox((LineBox) item);
				if (found != null) {
					return found;
				}
			} else {
				return item;
			}
		}
		return null;
	}

	// boolean isElementContentWhitespaceEnding()
	// {
	// if (!this._context.isCurrentLineOccupied())
	// return true;
	// LineBox line = this._context.getCurrentLine();
	// FlowBox lastNoneLinebox = findLastNonLineBox(line);
	// if (lastNoneLinebox instanceof TextFragmentBox)
	// return ((TextFragmentBox) lastNoneLinebox)._isLastCharWhitespace;
	// else
	// return true;
	// }
	//
	// String normalize(String text)
	// {
	// text = EntityMap.translateAndCompact(text);
	// if (text.length() > 0 &&
	// Character.isElementContentWhitespace(text.charAt(0)) &&
	// isElementContentWhitespaceEnding())
	// return text.substring(1);
	// else
	// return text;
	// }

	private void layoutEmptyString(List fragments, Font font) {
		// empty node! we want to create a fake fragment, so things can be
		// consistent
		// that all the CSSTextFigure will have something inside, also in this
		// way, even
		// empty text node will have a position, thus we can support showing
		// caret associated
		// with this text figure.
		fragments.clear();
		TextFragmentBox box = TextLayoutSupport.getFragment(0, fragments);
		box._length = 0;
		box._offset = 0;
		box._height = 0;
		box._width = 0;
		box.setTextData("");

		// {following comments deprecated XXX: If is empty string, we only want
		// to this figure to have a size, but don't
		// want to it to be added into current line. Otherwise, a line with only
		// a empty string
		// will also take a line's space.}

		// please reference LineBox.isOccupied()
		// now we treat a line with only an empty text as not occupied.
		getFlowContext().getCurrentLine().add(box);
	}

	/**
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#layout()
	 */
	protected void layout() {
		CSSTextFigure flowFigure = (CSSTextFigure) getFlowFigure();

		List fragments = flowFigure.getFragments();// Reuse the previous List
		// of fragments
		String text = flowFigure.getText();
		Font font = flowFigure.getCSSStyle().getCSSFont().getSwtFont();
		Object whitespace = flowFigure.getCSSStyle().getStyleProperty(
				ICSSPropertyID.ATTR_WHITESPACE);

		if (whitespace == ICSSPropertyID.VAL_PRE) {
			if (text == null || text.length() == 0)
				layoutEmptyString(fragments, font);
			else
				TextLayoutSupport.layoutNoWrap(getFlowContext(), text,
						fragments, font);
		} else if (whitespace == ICSSPropertyID.VAL_NOWRAP) {
			if (text == null || text.length() == 0)
				layoutEmptyString(fragments, font);
			else
				TextLayoutSupport.layoutNoWrap(getFlowContext(), text,
						fragments, font);
		} else {
			if (text == null || text.length() == 0)
				layoutEmptyString(fragments, font);
			else {
				boolean trimLeadingChar = (text.charAt(0) == ' ' && shouldTrimLeadingWhitespace(getFlowContext()));
				TextLayoutSupport.layoutNormal(getFlowContext(), text,
						fragments, font, _wrappingStyle, trimLeadingChar);
			}
		}
	}

	// XXX: maybe should move to TextSupport later.
	public boolean shouldTrimLeadingWhitespace(FlowContext context) {
		if (!context.isCurrentLineOccupied()) {
			return true;
		}
		while (context instanceof CSSInlineFlowLayout) {
			context = ((CSSInlineFlowLayout) context).getFlowContext();
		}
		LineBox line = context.getCurrentLine();
		if (line == null || !line.isOccupied()) {
			return true;
		}
		FlowBox lastNoneLinebox = findLastNonLineBox(line);
		if (lastNoneLinebox == null || lastNoneLinebox.getWidth() == 0) {
			return true;
		} else if (lastNoneLinebox instanceof TextFragmentBox) {
			return ((TextFragmentBox) lastNoneLinebox)._isLastCharWhitespace;
		} else {
			return false;
		}
	}

	public void dispose() {
	}
}
