/*******************************************************************************
 * 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 java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.SWT;

import org.eclipse.draw2d.Border;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.geometry.Rectangle;

/**
 * A <code>FlowFigure</code> represented by multiple <code>LineBox</code>
 * fragments. An <code>InlineFlow</code>'s parent must be either a
 * {@link BlockFlow} or another InlineFlow.
 * 
 * <P>
 * An InlineFlow may contain other InlineFlow figures.
 * 
 * <P>
 * WARNING: This class is not intended to be subclassed by clients.
 * 
 * @author Randy Hudson
 * @since 2.0
 */
public class InlineFlow extends FlowFigure {

	List fragments = new ArrayList(1);

	/**
	 * Iterates over the children to find the width before a line-break is
	 * encountered.
	 * 
	 * @see org.eclipse.draw2d.text.FlowFigure#addLeadingWordRequirements(int[])
	 */
	public boolean addLeadingWordRequirements(int[] width) {
		Iterator iter = getChildren().iterator();
		while (iter.hasNext()) {
			if (((FlowFigure) iter.next()).addLeadingWordRequirements(width))
				return true;
		}
		return false;
	}

	/**
	 * Extended to return false if the point is not also contained by at least
	 * one fragment.
	 * 
	 * @return <code>true</code> if a fragment contains the given point
	 * @param x
	 *            the relative x coordinate
	 * @param y
	 *            the relative y coordinate
	 */
	public boolean containsPoint(int x, int y) {
		if (super.containsPoint(x, y)) {
			List frags = getFragments();
			for (int i = 0; i < frags.size(); i++)
				if (((FlowBox) frags.get(i)).containsPoint(x, y))
					return true;
		}

		return false;
	}

	/**
	 * @see FlowFigure#createDefaultFlowLayout()
	 */
	protected FlowFigureLayout createDefaultFlowLayout() {
		return new InlineFlowLayout(this);
	}

	/**
	 * Returns the <code>FlowBox</code> fragments contained in this InlineFlow.
	 * The returned list should not be modified.
	 * 
	 * @return The fragments
	 */
	public List getFragments() {
		return fragments;
	}

	/**
	 * Overridden to paint a {@link FlowBorder} if present, and draw selection.
	 * The border is painted first, followed by selection which is generally
	 * done in XOR, which still allows the border to be seen.
	 * 
	 * @param graphics
	 *            the graphics
	 */
	protected void paintBorder(Graphics graphics) {
		if (getBorder() != null) {
			FlowBorder fb = (FlowBorder) getBorder();
			List frags = getFragments();
			Rectangle where = new Rectangle();
			int sides;
			for (int i = 0; i < frags.size(); i++) {
				FlowBox box = (FlowBox) frags.get(i);

				where.x = box.getX();
				where.width = box.getWidth();
				where.y = -box.getAscentWithBorder();
				where.height = box.getDescentWithBorder() - where.y;
				where.y += box.getBaseline();
				sides = 0;
				if (i == 0)
					sides = SWT.LEAD;
				if (i == frags.size() - 1)
					sides |= SWT.TRAIL;
				fb.paint(this, graphics, where, sides);
			}
			graphics.restoreState();
		}
		if (selectionStart != -1)
			paintSelection(graphics);
	}

	/**
	 * Renders the XOR selection rectangles to the graphics.
	 * 
	 * @param graphics
	 *            the graphics to paint on
	 * @since 3.1
	 */
	protected void paintSelection(Graphics graphics) {
		graphics.restoreState();
		graphics.setXORMode(true);
		graphics.setBackgroundColor(ColorConstants.white);
		List list = getFragments();
		FlowBox box;
		for (int i = 0; i < list.size(); i++) {
			box = (FlowBox) list.get(i);
			int top = box.getLineRoot().getVisibleTop();
			int bottom = box.getLineRoot().getVisibleBottom();
			graphics.fillRectangle(box.getX(), top, box.getWidth(), bottom
					- top);
		}
	}

	/**
	 * @see FlowFigure#postValidate()
	 */
	public void postValidate() {
		List list = getFragments();
		FlowBox box;
		int left = Integer.MAX_VALUE, top = left;
		int right = Integer.MIN_VALUE, bottom = right;

		for (int i = 0; i < list.size(); i++) {
			box = (FlowBox) list.get(i);
			left = Math.min(left, box.getX());
			right = Math.max(right, box.getX() + box.getWidth());
			top = Math.min(top, box.getLineRoot().getVisibleTop());
			bottom = Math.max(bottom, box.getLineRoot().getVisibleBottom());
		}

		setBounds(new Rectangle(left, top, right - left, bottom - top));
		repaint();
		list = getChildren();
		for (int i = 0; i < list.size(); i++)
			((FlowFigure) list.get(i)).postValidate();
	}

	/**
	 * Overridden to assert that only {@link FlowBorder} is used.
	 * <code>null</code> is still a valid value as well.
	 * 
	 * @param border
	 *            <code>null</code> or a FlowBorder
	 */
	public void setBorder(Border border) {
		if (border == null || border instanceof FlowBorder)
			super.setBorder(border);
		else
			throw new RuntimeException(
					"Border must be an instance of FlowBorder"); //$NON-NLS-1$
	}

}
