/*******************************************************************************
 * 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.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.jsf.common.ui.internal.logging.Logger;
import org.eclipse.jst.pagedesigner.PDPlugin;
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;
		}
        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() };
		}
        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;
		}
        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 border1 = new CSSBorder(this.getCSSStyle());
			border1.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);

	}

}
