/*******************************************************************************
 * 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.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Rectangle;

/**
 * The base implementation for text flow figures. A flow figure is used to
 * render a document in which elements are laid out horizontally within a "line"
 * until that line is filled. Layout continues on the next line.
 * <p>
 * WARNING: This class is not intended to be subclassed by clients. Future
 * versions may contain additional abstract methods.
 * 
 * @author mengbo
 * @since 2.1
 */
public abstract class FlowFigure extends Figure {

	// static final boolean SHOW_BASELINE = true;

	/**
	 * Constructs a new FlowFigure.
	 */
	public FlowFigure() {
		// setLayoutManager(createDefaultFlowLayout());
	}

	/**
	 * If the child is a <code>FlowFigure</code>, its FlowContext is passed
	 * to it.
	 * 
	 * @see org.eclipse.draw2d.IFigure#add(IFigure, Object, int)
	 */
	public void add(IFigure child, Object constraint, int index) {
		super.add(child, constraint, index);
		if (child instanceof FlowFigure) {
			FlowFigure ff = (FlowFigure) child;
			if (getLayoutManager() instanceof FlowContext) {
				ff.setOriginalFlowContext((FlowContext) getLayoutManager());
			} else {
				// should not happen
				// FIXME: logging
				System.err.println("layout is not FlowContext");
			}
		}
	}

	/**
	 * Creates the default layout manager
	 * 
	 * @return The default layout
	 */
	// protected abstract FlowFigureLayout createDefaultFlowLayout();
	/**
	 * @see Figure#paintFigure(Graphics)
	 */
	protected void paintFigure(Graphics g) {
		super.paintFigure(g);
		// g.drawRectangle(getBounds().getResized(-1,-1));
	}

	/**
	 * Called after validate has occurred. This is used to update the bounds of
	 * the FlowFigure to encompass its new flow boxed created during validate.
	 */
	public abstract void postValidate();

	/**
	 * FlowFigures override setBounds() to prevent translation of children.
	 * "bounds" is a derived property for FlowFigures, calculated from the
	 * fragments that make up the FlowFigure.
	 * 
	 * @see Figure#setBounds(Rectangle)
	 */
	public void setBounds(Rectangle r) {
		if (getBounds().equals(r))
			return;
		erase();
		bounds.x = r.x;
		bounds.y = r.y;
		bounds.width = r.width;
		bounds.height = r.height;
		fireFigureMoved();
		repaint();
	}

	/**
	 * Sets the flow context.
	 * 
	 * @param flowContext
	 *            the flow context for this flow figure
	 */
	public void setOriginalFlowContext(FlowContext flowContext) {
		((FlowFigureLayout) getLayoutManager())
				.setOriginalFlowContext(flowContext);
	}

	public void setDisplayString(String s) {
		_displayString = s;
	}

	public String toString() {
		if (_displayString == null)
        {
			return super.toString();
        }
        return _displayString + " " + getClass().getName();
	}

	String _displayString; // for debug

	/**
	 * @return
	 */
	public FlowContext getFlowContext() {
		return ((FlowFigureLayout) getLayoutManager()).getFlowContext();
	}

	// ----------------------------------------------------------------------
	// as absolute positioning and relative positioning may have children
	// out-side
	// of parent bounds, so we want to disable clipping when drawing figures
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Figure#paintChildren(org.eclipse.draw2d.Graphics)
	 */
	protected void paintChildren(Graphics graphics) {
		IFigure child;

		Rectangle clip = Rectangle.SINGLETON;
		List children = this.getChildren();
		for (int i = 0; i < children.size(); i++) {
			child = (IFigure) children.get(i);
			if (child.isVisible() && child.intersects(graphics.getClip(clip))) {
				// graphics.clipRect(child.getBounds());
				child.paint(graphics);
				graphics.restoreState();
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Figure#paintClientArea(org.eclipse.draw2d.Graphics)
	 */
	protected void paintClientArea(Graphics graphics) {
		if (this.getChildren().isEmpty())
			return;

		// boolean optimizeClip = getBorder() == null || getBorder().isOpaque();

		if (useLocalCoordinates()) {
			graphics.translate(getBounds().x + getInsets().left, getBounds().y
					+ getInsets().top);
			// if (!optimizeClip)
			// graphics.clipRect(getClientArea(PRIVATE_RECT));
			graphics.pushState();
			paintChildren(graphics);
			graphics.popState();
			graphics.restoreState();
		} else {
			// if (optimizeClip)
			paintChildren(graphics);
			// else {
			// graphics.clipRect(getClientArea(PRIVATE_RECT));
			// graphics.pushState();
			// paintChildren(graphics);
			// graphics.popState();
			// graphics.restoreState();
			// }
		}

	}
}
