/*******************************************************************************
 * 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.Border;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.LayoutManager;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.common.logging.Logger;
import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
import org.eclipse.jst.pagedesigner.css2.border.CSSBorder;
import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
import org.eclipse.jst.pagedesigner.css2.property.VisibilityMeta;
import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
import org.eclipse.jst.pagedesigner.css2.style.ITagEditInfo;
import org.eclipse.jst.pagedesigner.css2.widget.BorderUtil;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;

/**
 * Normally a CSSFigure is a container. It's layout will be driven by different
 * display type information from the style.
 * 
 * Each CSSFigure will be driven by ICSSStyle, the display type of the ICSSStyle
 * will decide the layout to be used for the figure.
 * 
 * @author mengbo
 */
public class CSSFigure extends FlowFigure implements ICSSFigure {
	private static Logger _log = PDPlugin.getLogger(CSSFigure.class);

	private static final Rectangle PRIVATE_RECT = new Rectangle();

	ICSSStyle _style;

	// NOTE: here keep the element is only for debug use. CSSFigure shouldn't
	// require an element.
	// Element _element;

	// if this field is set, then regetLayout() will still return this layout,
	// without going through the CSS resolution
	CSSLayout _fixedLayout;

	public CSSFigure() {
		_style = DefaultStyle.getInstance();
		invalidateCSS();
	}

	public CSSFigure(ICSSStyle style) {
		_style = style;
		// _element = element;
		invalidateCSS();
	}

	public ICSSStyle getCSSStyle() {
		return _style;
	}

	public void setCSSStyle(ICSSStyle style) {
		_style = style;
		invalidateCSS();
	}

	public void revalidate() {
		CSSLayout layout = (CSSLayout) getLayoutManager();
		layout.figureRevalidate();
		super.revalidate();
	}

	/**
	 * this method is called when the css source noticed style change. So tell
	 * the figure should invalidate its cached data.
	 */
	public void invalidateCSS() {
		// maybe we changed from inline to block or block to inline
		// XXX: or even to table?
		CSSLayout layout = regetLayout(getLayoutManager());
		this.setLayoutManager(layout);
	}

	public void setFixedLayoutManager(CSSLayout layout) {
		this._fixedLayout = layout;
		this.setLayoutManager(regetLayout(getLayoutManager()));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Figure#setLayoutManager(org.eclipse.draw2d.LayoutManager)
	 */
	public void setLayoutManager(LayoutManager manager) {
		LayoutManager old = getLayoutManager();
		if (old != manager) {
			FlowContext context = null;
			if (old instanceof FlowFigureLayout) {
				context = ((FlowFigureLayout) old).getOriginalFlowContext();
			}
			if (manager instanceof FlowFigureLayout) {
				((FlowFigureLayout) manager).setOriginalFlowContext(context);
			}

			if (manager instanceof FlowContext) {
				List list = getChildren();
				for (int i = 0, size = list.size(); i < size; i++) {
					try {
						((FlowFigure) list.get(i))
								.setOriginalFlowContext((FlowContext) manager);
					} catch (ClassCastException classcastexception) {
						// Error in flowContext setting.
						_log.error("Error.CSSFigure.0", classcastexception); //$NON-NLS-1$
					}
				}
			}
		}
		super.setLayoutManager(manager);
	}

	protected CSSLayout regetLayout(LayoutManager old) {
		if (_fixedLayout != null) {
			return _fixedLayout;
		}
		CSSLayout layout = DisplayToLayout.displayToLayout(this, getCSSStyle()
				.getDisplay(), old);
		if (layout != null) {
			return layout;
		} else {
			return new CSSInlineFlowLayout(this);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Figure#containsPoint(int, int)
	 */
	public boolean containsPoint(int x, int y) {
		// check whether any float figure contains it.
		// FIXME: need check floating figure here!!!
		if (!super.containsPoint(x, y)) {
			return false;
		}
		List frags = getFragmentsForRead();
		// Here we should not get void pointer.
		if (frags != null) {
			for (int i = 0; i < frags.size(); i++) {
				FlowBox box = (FlowBox) frags.get(i);
				if (box != null && box.containsPoint(x, y)) {
					return true;
				}
			}
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure#getFragmentsForRead()
	 */
	public List getFragmentsForRead() {
		CSSLayout layout = (CSSLayout) getLayoutManager();
		return layout.getFragmentsForRead();
	}

	/**
	 * this method is a shortcut to getFragmentsForRead
	 * 
	 * @return
	 */
	public Rectangle[] getFragmentsBounds() {
		List list = getFragmentsForRead();
		if (list == null || list.size() == 0) {
			// should not happen. but still handle it.
			return new Rectangle[] { getBounds() };
		} else {
			Rectangle[] ret = new Rectangle[list.size()];
			for (int i = 0, size = list.size(); i < size; i++) {
				FlowBox box = (FlowBox) list.get(i);
				ret[i] = new Rectangle(box._x, box._y, box.getWidth(), box
						.getHeight());
			}
			return ret;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.IFigure#setBounds(org.eclipse.draw2d.geometry.Rectangle)
	 */
	public void setBounds(Rectangle r) {
		if (getBounds().equals(r)) {
			return;
		}
		boolean invalidate = getBounds().width != r.width
				|| getBounds().height != r.height;
		super.setBounds(r);

		CSSLayout layout = (CSSLayout) this.getLayoutManager();
		layout.setBoundsCalled(r, invalidate);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigure#postValidate()
	 */
	public void postValidate() {
		CSSLayout layout = (CSSLayout) getLayoutManager();
		layout.postValidateForAbsolute();
		layout.postValidate();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.IFigure#validate()
	 */
	public void validate() {
		super.validate();
		// should not call this.postValidate() here. PostValidate() should
		// only be started from the FlowPage. Otherwise it will be called
		// multiple times on a figure.
		// this.postValidate();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Figure#useLocalCoordinates()
	 */
	protected boolean useLocalCoordinates() {
		CSSLayout layout = (CSSLayout) getLayoutManager();
		if (layout == null) {
			return false;
		} else {
			return layout.useLocalCoordinates();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.IFigure#paint(org.eclipse.draw2d.Graphics)
	 */
	public void paint(Graphics graphics) {
		ICSSStyle style = getCSSStyle();
		if (style != null) {
			Object visibility = style
					.getStyleProperty(ICSSPropertyID.ATTR_VISIBILITY);
			// handle visibility: hidden here.
			// TODO: "collapse" is not supported yet!
			if (VisibilityMeta.HIDDEN.equals(visibility)) {
				return;
			}
		}

		CSSLayout layout = (CSSLayout) this.getLayoutManager();
		graphics.pushState();
		try {
			paintFigure(graphics);
			graphics.restoreState();
			paintClientArea(graphics);
			if (layout instanceof ICSSPainter2) {
				if (useLocalCoordinates()) {
					graphics.translate(getBounds().x + getInsets().left,
							getBounds().y + getInsets().top);
					((ICSSPainter2) layout).paintFigurePostClientArea(graphics);
					graphics.restoreState();
				} else {
					((ICSSPainter2) layout).paintFigurePostClientArea(graphics);
				}
			}
			paintBorder(graphics);
		} finally {
			graphics.popState();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigure#paintFigure(org.eclipse.draw2d.Graphics)
	 */
	protected void paintFigure(Graphics g) {
		Color rgbColor = null;
		boolean fillArea = false;
		Object bg = getCSSStyle().getBackgroundColor();
		if (bg instanceof RGB) {
			rgbColor = new Color(null, (RGB) bg);
			g.setBackgroundColor(rgbColor);
			fillArea = true;
		} else if (bg instanceof Color) {
			g.setBackgroundColor((Color) bg);
			fillArea = true;
		}
		if (fillArea) {
			List fragments = getFragmentsForRead();

			for (int i = 0, n = fragments.size(); i < n; i++) {
				Object obj = fragments.get(i);
				if (obj instanceof FlowBox) {
					FlowBox box = (FlowBox) obj;
					g.fillRectangle(box._x, box._y, box.getWidth(), box
							.getHeight());
				}
			}
		}
		if (rgbColor != null) {
			rgbColor.dispose();
		}
		g.restoreState();

		LayoutManager layout = getLayoutManager();
		if (layout instanceof ICSSPainter) {
			if (useLocalCoordinates()) {
				g.translate(getBounds().x + getInsets().left, getBounds().y
						+ getInsets().top);
				((ICSSPainter) layout).paintFigure(g);
				g.restoreState();
			} else {
				((ICSSPainter) layout).paintFigure(g);
			}
		}

		// paint selected mode here.
		paintSelection(g);

		if (Debug.DEBUG_BOX) {
			// draw two levels of boxes. Since normally each figure will only
			// have two levels of boxes.
			List fragments = this.getFragmentsForRead();
			for (int i = 0, size = fragments.size(); i < size; i++) {
				FlowBox box = (FlowBox) fragments.get(i);
				BoxUtil.drawBox(g, box);
				if (box instanceof BlockBox) {
					BlockBox compositeBox = (BlockBox) box;
					List list = compositeBox.getFragments();
					for (int j = 0; j < list.size(); j++) {
						g.translate(this.getInsets().left,
								this.getInsets().right);
						BoxUtil.drawBox(g, (FlowBox) list.get(j));
						g.restoreState();
					}
				}
			}
		}
		if (Debug.DEBUG_BASELINE) {
			List fragments = this.getFragmentsForRead();
			for (int i = 0, size = fragments.size(); i < size; i++) {
				Object obj = fragments.get(i);
				if (obj instanceof LineBox) {
					LineBox linebox = (LineBox) obj;
					g.setForegroundColor(ColorConstants.red);
					g.drawLine(linebox._x, linebox._y + linebox.getAscent(),
							linebox._x + linebox.getWidth(), linebox._y
									+ linebox.getAscent());
				}
			}
		}

		if (Debug.DEBUG_BORDERPADDING) {
			if (this.getLayoutManager() instanceof CSSBlockFlowLayout) {
				g.setLineWidth(1);
				Rectangle rect = getBounds().getCopy().crop(getInsets());
				g.setForegroundColor(ColorConstants.green);
				g.drawRectangle(rect);
				g.setForegroundColor(ColorConstants.red);
				g.drawRectangle(getBounds());
			}
		}

		if (Debug.DEBUG_BOX) {
			CSSLayout csslayout = (CSSLayout) this.getLayoutManager();
			if (csslayout._absoluteContext != null) {
				BlockBox blockbox = csslayout._absoluteContext._blockBox;
				g.setLineWidth(1);
				g.setForegroundColor(ColorConstants.green);
				g.drawRectangle(blockbox._x, blockbox._y, blockbox.getWidth(),
						blockbox.getHeight());
			}
		}
	}

	/**
	 * Paints this Figure's client area. The client area is typically defined as
	 * the anything inside the Figure's {@link Border} or {@link Insets}, and
	 * by default includes the children of this Figure. On return, this method
	 * must leave the given Graphics in its initial state.
	 * 
	 * @param graphics
	 *            The Graphics used to paint
	 * @since 2.0
	 */
	protected void paintClientArea(Graphics graphics) {
		if (this.getChildren().isEmpty()) {
			return;
		}

		Object overflow = ICSSPropertyID.VAL_VISIBLE;
		ICSSStyle style = this.getCSSStyle();
		if (style != null) {
			overflow = style.getStyleProperty(ICSSPropertyID.ATTR_OVERFLOW);
		}

		boolean optimizeClip = ICSSPropertyID.VAL_VISIBLE.equals(overflow);

		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();
			}
		}
	}

	/**
	 * @param g
	 */
	protected void paintSelection(Graphics g) {
		ICSSStyle style = this.getCSSStyle();
		if (style != null) {
			if (style.isInSelection()) {
				ITagEditInfo editInfo = (ITagEditInfo) style
						.getAdapter(ITagEditInfo.class);
				if (editInfo != null && editInfo.isWidget()) {
					BorderUtil.maskFigure(this, g);
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Figure#paintBorder(org.eclipse.draw2d.Graphics)
	 */
	protected void paintBorder(Graphics graphics) {
		CSSLayout layout = (CSSLayout) getLayoutManager();
		if (layout != null && !layout.handlingBorderForBlock()) {
			return;
		}

		ICSSStyle style = this.getCSSStyle();
		if (style != null) {
			CSSBorder border = new CSSBorder(this.getCSSStyle());
			border.paint(this, graphics, NO_INSETS);

			// draw a border for those special elements like <h:form>, etc.
			ITagEditInfo editInfo = (ITagEditInfo) style
					.getAdapter(ITagEditInfo.class);
			if (editInfo != null && editInfo.needBorderDecorator()) {
				BorderUtil.drawBorderDecorator(this, graphics);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.IFigure#getInsets()
	 */
	public Insets getInsets() {
		CSSLayout layout = (CSSLayout) getLayoutManager();
		if (layout != null && !layout.handlingBorderForBlock()) {
			return new Insets();
		}
		ICSSStyle style = this.getCSSStyle();
		if (style != null) {
			return style.getBorderInsets().getAdded(style.getPaddingInsets());
		}
		return new Insets();
	}

	/**
	 * FIXME: need trace the implementation of Figure.invalidate() We want to
	 * just mark this figure as invalid, but don't want to the layout get
	 * invalidated.
	 * 
	 */
	public void invalidate2() {
		if (!isValid())
			return;
		// if (getLayoutManager() != null)
		// getLayoutManager().invalidate();
		setValid(false);

	}

}
