/*******************************************************************************
 * Copyright (c) 2005 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.bpel.ui.editparts.borders;

import org.eclipse.bpel.ui.BPELUIPlugin;
import org.eclipse.bpel.ui.IBPELUIConstants;
import org.eclipse.core.resources.IMarker;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.RoundedRectangle;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;


/**
 * This is the border for sequence, switch, pick and while.
 * 
 * When expanded it displays a label and text at the top as well as showing the
 * contents.
 */
public class ContainerBorder extends CollapsableBorder {
	
	// The horizontal margin between the border and the image/text 
	private static final int leftMargin = 6;
	private static final int rightMargin = 10;
	// The vertical margin between the border and the image/text
	private static final int topMargin = 6;
	private static final int bottomMargin = 3;
	
	// space between image and label
	static final int spacing = 5;
	static final int borderWidth = 1;
	static final int margin = 11;
	
	// space between the inside of the border and the contents
	static final int hBorderInsets = 3;
	static final int vBorderInsets = 22;
	
	// We keep this round rect around to paint.
	private RoundedRectangle roundRect;
	
	// The bounds of the "-" icon at the top and bottom of the expanded figure
	private Rectangle rectExpandedTop, rectExpandedBottom;

	// The calculated bounds of the label and the image when expanded
	private Rectangle rectLabel, rectImageLabel;

	// The bounds of the round rectangle surrounding the label and image 
	// when expanded
	private Rectangle rectLabelBorder;
	
	// The bounds of the rectangle surrounding the children when expanded.
	// Computed to take into account drawers.
	private Rectangle expandedBounds;
	
	public ContainerBorder(IFigure parentFigure, Image image, String labelText) {
		super(true, IBPELUIConstants.ARC_WIDTH, parentFigure, labelText, image);

		this.roundRect = new RoundedRectangle();
		this.roundRect.setOpaque(true);
		this.roundRect.setCornerDimensions(new Dimension(IBPELUIConstants.ARC_WIDTH, IBPELUIConstants.ARC_WIDTH));
	}

	public Dimension getPreferredSize(IFigure f) {
		calculate(f);
		Dimension d = new Dimension(rectLabelBorder.getSize().width, rectLabelBorder.getSize().height + expandedHeight);
		d.width += DRAWER_WIDTH * 2;
		if (!isCollapsed()) {
			d.width += IBPELUIConstants.ARC_WIDTH * 2;
		}
		return d;
	}
	
	protected void doPaint(IFigure figure, Graphics graphics, Insets insets) {
		super.doPaint(figure, graphics, insets);
		ColorRegistry registry = BPELUIPlugin.getPlugin().getColorRegistry();
		graphics.setForegroundColor(registry.get(IBPELUIConstants.COLOR_COMPOSITE_ACTIVITY_BORDER));
		if (!isCollapsed()) {
			// Paint the round rectangle around the lower part of the figure (surrounding the
			// children figures).
			graphics.drawRoundRectangle(expandedBounds, IBPELUIConstants.ARC_WIDTH, IBPELUIConstants.ARC_WIDTH);
		}
				
		// Paint the round rectangle at the top.
		// First determine whether or not square corners are needed on the left edge.
		boolean needSquareCorners = (getTopMarker() != null) || (getBottomMarker() != null);		
		if (isCollapsed() && needSquareCorners) {
			// Remember the clipping rectangle
			Rectangle oldClip = new Rectangle();
			oldClip = graphics.getClip(oldClip);

			Rectangle clippingRect = new Rectangle(rectLabelBorder.x + rectLabelBorder.width / 2, rectLabelBorder.y, rectLabelBorder.width / 2 + 2, rectLabelBorder.height + 1);
			graphics.setClip(clippingRect);
			graphics.drawRoundRectangle(rectLabelBorder, IBPELUIConstants.ARC_WIDTH, IBPELUIConstants.ARC_WIDTH);
			clippingRect = new Rectangle(rectLabelBorder.x, rectLabelBorder.y, rectLabelBorder.width / 2 + 1, rectLabelBorder.height + 1);
			graphics.setClip(clippingRect);
			graphics.drawRectangle(rectLabelBorder);
			
			// Restore the clipping
			graphics.setClip(oldClip);
		} else {
			roundRect.setBounds(rectLabelBorder);
			roundRect.setForegroundColor(BPELUIPlugin.getPlugin().getColorRegistry().get(IBPELUIConstants.COLOR_ACTIVITY_BORDER));
			roundRect.paint(graphics);
		}
		
		Color old = graphics.getForegroundColor();
		graphics.setForegroundColor(registry.get(IBPELUIConstants.COLOR_BLACK));
		collapsedNameLabel.setBounds(rectLabel);
		collapsedNameLabel.paint(graphics);
		imageLabel.setBounds(rectImageLabel);
		imageLabel.paint(graphics);
		graphics.setForegroundColor(old);
				
		if (isCollapsed()) {
			graphics.drawImage(collapsedImage, rectCollapsed.getLocation());
		} else {
			graphics.drawImage(expandedImage, rectExpandedTop.getLocation());
			graphics.drawImage(expandedImage, rectExpandedBottom.getLocation());
		}			
	}
	
	// Initialize a bunch of location and size variables based on the contents
	protected void calculate(IFigure figure) {
		super.calculate(figure);

		// bounds of the figure that we are given
		Rectangle figureBounds = figure.getBounds().getCopy();
		
		// preferred size of the image
		Dimension imageLabelSize = imageLabel.getPreferredSize().getCopy();
		// preferred size of the text label
		Dimension labelSize = collapsedNameLabel.getPreferredSize().getCopy();
		
		// calculate the label border for the round rectangle
		// surrounding the label and image
		int w = labelSize.width + spacing + imageLabelSize.width;
		int h = Math.max(labelSize.height, imageLabelSize.height);
		int x = figureBounds.x + figureBounds.width / 2 - (w/2);
		int y = figureBounds.y;
		rectLabelBorder = new Rectangle(x, y, w, h);

		// expand the border for aesthetics and to account for arc size.
		// note we don't use the entire arc size to conserve space.
		// also remember we can't expand in the upwards direction.
		int verticalMargin = topMargin + bottomMargin;
		if (isCollapsed()) verticalMargin--;
		rectLabelBorder.expand(new Insets(0, leftMargin, verticalMargin, rightMargin));
		
		// rectangle for image label
		x = rectLabelBorder.x + leftMargin;
		y = rectLabelBorder.y + topMargin;
		w = imageLabelSize.width;
		h = imageLabelSize.height;
		rectImageLabel = new Rectangle(x, y, w, h);
					
		// rectangle for text label	
		x = rectLabelBorder.x + leftMargin + imageLabelSize.width + spacing;
		y = rectLabelBorder.y + topMargin;
		w = labelSize.width;
		h = labelSize.height;
		rectLabel = new Rectangle(x, y, w, h);
		
		// calculate the size of the round rectangle surrounding the children,
		// taking into account arc size and drawer width
		this.expandedBounds = figureBounds.getCopy();
		// adjust for drawer width
		expandedBounds.x += DRAWER_WIDTH;
		expandedBounds.width -= DRAWER_WIDTH * 2;
		// adjust for half height of the label and image
		expandedBounds.y += rectLabelBorder.height / 2;
		expandedBounds.height -= rectLabelBorder.height / 2;
		// subtract half the height of the minus button at the bottom.
		expandedBounds.height -= expandedHeight / 2;
		
		// area for plus/minus buttons
		rectExpandedTop = new Rectangle(rectLabelBorder.x + rectLabelBorder.width/2 - expandedWidth/2, rectLabelBorder.y + rectLabelBorder.height - 1, expandedWidth, expandedHeight);
		rectExpandedBottom = new Rectangle(figureBounds.x + figureBounds.width / 2 - expandedWidth / 2, figureBounds.y + figureBounds.height - expandedHeight, expandedWidth, expandedHeight);
		
		// Top drawer
		IMarker topMarker = getTopMarker();
		if (topMarker != null) {
			// Draw the image for the top drawer
			if (isCollapsed()) {
				topDrawerLocation.x = collapsedRectangle.x - DRAWER_WIDTH + DRAWER_INSET + 1;
				topDrawerLocation.y = collapsedRectangle.y;
			} else {
				topDrawerLocation.x = expandedBounds.x - DRAWER_WIDTH;
				topDrawerLocation.y = expandedBounds.y + IBPELUIConstants.ARC_WIDTH;
			}
		}
		// Bottom drawer
		IMarker bottomMarker = getBottomMarker();
		if (bottomMarker != null) {
			// Draw the image for the bottom drawer
			if (isCollapsed()) {
				bottomDrawerLocation.x = collapsedRectangle.x - DRAWER_WIDTH + DRAWER_INSET + 1;
				bottomDrawerLocation.y = collapsedRectangle.y + DRAWER_HALF_HEIGHT;
			} else {
				bottomDrawerLocation.x = expandedBounds.x - DRAWER_WIDTH;
				bottomDrawerLocation.y = expandedBounds.y + DRAWER_HALF_HEIGHT + IBPELUIConstants.ARC_WIDTH;
			}
		}
		// Top drawer marker image
		Image topImage = getTopImage();
		if (topImage != null) {
			if (isCollapsed()) {
				topImageLocation.x = collapsedRectangle.x - DRAWER_WIDTH + DRAWER_INSET + 2;
				topImageLocation.y = collapsedRectangle.y + DRAWER_INSET;
			} else {
				topImageLocation.x = expandedBounds.x - DRAWER_WIDTH + DRAWER_INSET;
				topImageLocation.y = expandedBounds.y + IBPELUIConstants.ARC_WIDTH + DRAWER_INSET;
			}
		}
		// Bottom drawer marker image
		Image bottomImage = getBottomImage();
		if (bottomImage != null) {
			if (isCollapsed()) {
				bottomImageLocation.x = collapsedRectangle.x - DRAWER_WIDTH + DRAWER_INSET + 2;
				bottomImageLocation.y = collapsedRectangle.y + DRAWER_INSET + DRAWER_HALF_HEIGHT;
			} else {
				bottomImageLocation.x = expandedBounds.x - DRAWER_WIDTH + DRAWER_INSET;
				bottomImageLocation.y = expandedBounds.y + IBPELUIConstants.ARC_WIDTH + DRAWER_HALF_HEIGHT + DRAWER_INSET;
			}
		}
		
	}
	
	/**
	 * Compute the insets. We only know how to do this for expanded borders,
	 * so delegate to super in the collapsed state.
	 */
	public Insets getInsets(IFigure figure) {
		if (isCollapsed()) return super.getInsets(figure);
		calculate(figure);
		Insets result = new Insets(vBorderInsets + rectLabelBorder.height, hBorderInsets, vBorderInsets, hBorderInsets);
		result.left += DRAWER_WIDTH;
		result.right += DRAWER_WIDTH;
		return result;
	}

	/**
	 * throw away values that determine the layout
	 */
	public void invalidate() {
		super.invalidate();
		rectLabelBorder = null;
		rectLabel = null;
		rectExpandedTop = null;
		rectExpandedBottom = null;
	}

	/**
	 * Tests whether the given point is inside the collapse image. The superclass
	 * does not know where the collapse image(s) is located.
	 */
	public boolean isPointInCollapseImage(int x, int y) {
		if (isCollapsed()) return super.isPointInCollapseImage(x, y);
		Point p = new Point(x,y);
		parentFigure.translateToRelative(p);
		Rectangle rect = rectExpandedTop.getCopy();
		rect.expand(new Insets(1,1,1,1));
		if (rect.contains(p)) return true;
		if (!isCollapsed()) {
			rect = rectExpandedBottom.getCopy();
			rect.expand(new Insets(1,1,1,1));
			return rect.contains(p);
		}
		return false;
	}
	
	/**
	 * Provide gradient rectangle.
	 */
	protected Rectangle getGradientRect() {
		if (isCollapsed()) return super.getGradientRect();
		invalidate();
		calculate(parentFigure);
		return expandedBounds;
	}
	
	/**
	 * Edit parts may like to know what the top inset is - this is
	 * the distance between the top of the border and the top of the
	 * container round rectangle. This is useful because this is where
	 * selection handles are often located.
	 */
	public int getTopInset() {
		// HACK! This is necessary to prevent certain NPEs.
		if (rectLabelBorder == null || expandedBounds == null) {
			calculate(parentFigure);
		}
		
		return expandedBounds.y - rectLabelBorder.y;
	}
}
