/*******************************************************************************
 * Copyright (c) 2004, 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.jsf.facesconfig.ui.preference;

import java.util.Iterator;

import org.eclipse.draw2d.ActionEvent;
import org.eclipse.draw2d.ActionListener;
import org.eclipse.draw2d.FreeformFigure;
import org.eclipse.draw2d.FreeformListener;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.Layer;
import org.eclipse.draw2d.LayoutManager;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jst.jsf.facesconfig.ui.EditorPlugin;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;

/**
 * The figure for Compound nodes
 */
/*package*/ class CompoundNodeFigure extends BaseNodeFigure implements
		FreeformFigure, IContainerFigure {
	private final static int MINIMIZED = 1;

	final static int RESTORED = 2;

	private final static int MAXIMIZED = 3;

	private int state = RESTORED;

	private TitleBarButton minButton;

	private TitleBarButton maxButton;

	private IconFigure iconFigure;

	private WindowFigure windowFigure;

	private static String DEFAULT_NAME = "CompoundNode";

	private static String DEFAULT_ICON = "editor/CompoundNode.gif";

	private static Image minimizeImage = EditorPlugin.getDefault().getImage(
			"minimize.gif");

	private static Image minimizeHiliteImage = EditorPlugin.getDefault()
			.getImage("minimize_hilite.gif");

	private static Image maximizeImage = EditorPlugin.getDefault().getImage(
			"maximize.gif");

	private static Image maximizeHiliteImage = EditorPlugin.getDefault()
			.getImage("maximize_hilite.gif");

	private static Image restoreImage = EditorPlugin.getDefault().getImage(
			"restore.gif");

	private static Image restoreHiliteImage = EditorPlugin.getDefault()
			.getImage("restore_hilite.gif");

	/**
	 * Default constructor
	 */
	public CompoundNodeFigure() {
		// create all of the figures and adornments:
		// the icon figure
		super(new IconFigure(DEFAULT_NAME, EditorPlugin.getDefault().getImage(
				DEFAULT_ICON)));
		iconFigure = (IconFigure) getBaseFigure();
		// and the window figure
		windowFigure = new WindowFigure();
		windowFigure.setForegroundColor(IconFigure.defaultForegroundColor);
		windowFigure.setFont(IconFigure.defaultFont);

		// then the minimize/maximize buttons.
		// Note that the maxButton is also used for the "Restore" action
		// TODO:
		// The reason for putting these buttons in CompoundNodeFigure instead of
		// WindowFigure where they really belong, is that the TitleBarButton is
		// a
		// draw2d Button (which subclasses Figure) and these must be placed in
		// the
		// titlebar (i.e. a SchemeBorder) because that's where they belong. The
		// problem
		// with this is that the Figure.paint() method first draws all of its
		// children
		// figures, then the border which means that the buttons would be
		// obscured.
		// This should be fixed as time allows and the WindowFigureListener
		// interface
		// should then also be modified to include a buttonPressed()
		// notification
		// for which CompoundNodeFigure can be a listener.
		minButton = new TitleBarButton(minimizeImage, minimizeHiliteImage,
				null, null);
		maxButton = new TitleBarButton(maximizeImage, maximizeHiliteImage,
				restoreImage, restoreHiliteImage);

		add(minButton);
		add(maxButton);

		minButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				setState(CompoundNodeFigure.MINIMIZED);
			}
		});
		maxButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				setState(maxButton.getState() ? CompoundNodeFigure.MAXIMIZED
						: CompoundNodeFigure.RESTORED);
			}
		});

		// show as a normal window initially
		showIcon();

		// testing BaseFigureDecorators:
		// BaseFigureDecorator decorator;
		// decorator = new
		// BaseFigureDecorator(EditorPlugin.getDefault().getGEMImage("delete.gif"),
		// "top right",
		// PositionConstants.NORTH_EAST);
		// addDecorator(decorator);
		// decorator = new
		// BaseFigureDecorator(EditorPlugin.getDefault().getGEMImage("delete.gif"),
		// "top left",
		// PositionConstants.NORTH_WEST);
		// addDecorator(decorator);
		// decorator = new
		// BaseFigureDecorator(EditorPlugin.getDefault().getGEMImage("delete.gif"),
		// "bottom right",
		// PositionConstants.SOUTH_EAST);
		// addDecorator(decorator);
		// decorator = new
		// BaseFigureDecorator(EditorPlugin.getDefault().getGEMImage("delete.gif"),
		// "bottom left",
		// PositionConstants.SOUTH_WEST);
		// addDecorator(decorator);
	}

	public void setOpaque(boolean flag) {
		windowFigure.setOpaque(flag);
	}

	/*
	 * Remove the window figure and its buttons and replace them with the icon
	 * figure.
	 */
	private void showIcon() {
		// CR400779: GEM minimizing a complex activity sometimes leaves junk on
		// the screen
		setVisible(false);
		minButton.setVisible(false);
		maxButton.setVisible(false);
		super.setBaseFigure(iconFigure);

		setAnchorsVisible(true);
		// CR400779: GEM minimizing a complex activity sometimes leaves junk on
		// the screen
		setVisible(true);
	}

	/*
	 * Remove the icon figure and replace with the window figure. Make sure the
	 * buttons are reset to their correct states.
	 */
	private void showWindow() {
		// CR400779: GEM minimizing a complex activity sometimes leaves junk on
		// the screen
		setVisible(false);
		if (state == RESTORED) {
			super.setBaseFigure(windowFigure);

			minButton.setVisible(true);
			minButton.setState(false);
			minButton.setToolTip(new Label("Minimize"));

			maxButton.setVisible(true);
			maxButton.setState(false);
			maxButton.setToolTip(new Label("Maximize"));

			setAnchorsVisible(true);
		} else if (state == MAXIMIZED) {
			setAnchorsVisible(false);

			Rectangle constraint = new Rectangle(0, 0, -1, -1);
			IFigure parent = getParent();
			if (parent != null) {
				constraint = parent.getBounds().getCopy();
				constraint.width += constraint.x;
				constraint.height += constraint.y;
				constraint.x = 0;
				constraint.y = 0;
			}

			super.setBaseFigure(windowFigure, constraint);
			if (parent != null && parent.getLayoutManager() != null) {
				// System.out.println("CompoundNode.showWindow: maximize
				// "+constraint);
				parent.getLayoutManager().setConstraint(this, constraint);
			}

			// the maximize button is used for both Maximize and Restore actions
			minButton.setVisible(false);

			maxButton.setVisible(true);
			maxButton.setState(true);
			maxButton.setToolTip(new Label("Restore"));
		}
		// CR400779: GEM minimizing a complex activity sometimes leaves junk on
		// the screen
		setVisible(true);
	}

	public void addDecorator(BaseFigureDecorator decorator) {
		iconFigure.addDecorator(decorator);
	}

	public void removeDecorator() {
		iconFigure.removeDecorator();
	}

	public void removeDecorator(int position) {
		iconFigure.removeDecorator(position);
	}

	/**
	 * @param flag
	 */
	public void setHilight(boolean flag) {
		windowFigure.setHighlight(flag);
		if (flag)
			moveToTop();
	}

	public void setText(String name) {
		iconFigure.setText(name);
		windowFigure.setText(name);
	}

	public void setIcon(Image image) {
		iconFigure.setIcon(image);
	}

	public void setToolTipText(String text) {
		iconFigure.setToolTipText(text);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Figure#layout()
	 */
	public void validate() {
		LayoutManager layout = getLayoutManager();
		if (state == MINIMIZED) {
			// iconFigure.validate();
		} else if (state == RESTORED) {
			Rectangle r = windowFigure.getBounds().getCopy();
			Insets i = windowFigure.getInsets();
			Dimension dm = maxButton.getSize();
			Insets p = windowFigure.getTabbedTitleBarBorder().getPadding();
			layout.setConstraint(maxButton, new Rectangle(r.x + r.width
					- dm.width - p.right - i.right, r.y + p.top + i.top
					- dm.height - i.bottom, -1, -1));
			layout.setConstraint(minButton, new Rectangle(r.x + r.width - 2
					* dm.width - 2 * p.right - i.right, r.y + p.top + i.top
					- dm.height - i.bottom, -1, -1));
		} else if (state == MAXIMIZED) {
			// CR387660: restore icon on complex activity bounces around
			// we need to use the parent's bounds when maximized instead of
			// current window bounds
			if (getParent() == null)
				return;
			Rectangle r = getParent().getBounds().getCopy();
			Insets i = windowFigure.getInsets();
			Dimension dm = maxButton.getSize();
			Insets p = windowFigure.getTabbedTitleBarBorder().getPadding();
			layout.setConstraint(maxButton, new Rectangle(r.x + r.width
					- dm.width - p.right - i.right, r.y + p.top, -1, -1));
		}
		super.validate();
	}
	/**
	 * @return the window figure
	 */
	public WindowFigure getWindowFigure() {
		return windowFigure;
	}

	public void setFont(Font f) {
		iconFigure.setFont(f);
		windowFigure.setFont(f);
	}

	public void setForegroundColor(Color c) {
		iconFigure.setForegroundColor(c);
		windowFigure.setForegroundColor(c);
	}

	public void setBackgroundColor(Color c) {
		iconFigure.setBackgroundColor(c);
		windowFigure.setBackgroundColor(c);
	}

	/**
	 * @return the state
	 */
	public int getState() {
		return state;
	}

	/**
	 * @param newState
	 */
	public void setState(int newState) {
		int oldState = state;
		state = newState;

		if (state == CompoundNodeFigure.MINIMIZED) {
			if (getParent() != null && getParent().getLayoutManager() != null) {
				Rectangle constraint = (Rectangle) getParent()
						.getLayoutManager().getConstraint(this);
				constraint.width = -1;
				constraint.height = -1;
			}
			showIcon();
		} else if (state == CompoundNodeFigure.MAXIMIZED) {
			if (getParent() != null && getParent().getLayoutManager() != null) {
				Rectangle constraint = (Rectangle) getParent()
						.getLayoutManager().getConstraint(this);
				constraint.x = 0;
				constraint.y = 0;
				constraint.width = -1;
				constraint.height = -1;
			}
			showWindow();
		} else if (state == CompoundNodeFigure.RESTORED) {
			if (getParent() != null && getParent().getLayoutManager() != null) {
				Rectangle constraint = (Rectangle) getParent()
						.getLayoutManager().getConstraint(this);
				constraint.setSize(windowFigure.getBounds().getSize());
			}
			showWindow();
		}
		fireStateChanged(oldState, newState);
	}

	private void fireStateChanged(int oldState, int newState) {
		Object l[] = windowFigure.getTabbedTitleBarBorder().getListeners();
		for (int i = 0; i < l.length; ++i) {
			if (l[i] instanceof CompoundFigureListener)
				((CompoundFigureListener) l[i])
						.stateChanged(oldState, newState);
		}
	}

	public Dimension getMinimumSize(int wHint, int hHint) {
		if (getState() == CompoundNodeFigure.RESTORED) {
			Dimension d = windowFigure.getMinimumSize(wHint, hHint);
			d.width += minButton.getSize().width
					+ maxButton.getSize().width
					+ 2
					* windowFigure.getTabbedTitleBarBorder().getPadding()
							.getWidth();
			return d;
		}
		if (getState() == CompoundNodeFigure.MINIMIZED)
			return iconFigure.getMinimumSize(wHint, hHint);
		return super.getMinimumSize(wHint, hHint);
	}

	// //////////////////////////////////////////////////////////////////////
	// FreeformFigure methods
	// //////////////////////////////////////////////////////////////////////

	private WindowFreeformHelper helper = new WindowFreeformHelper(this);

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.FreeformFigure#addFreeformListener(org.eclipse.draw2d.FreeformListener)
	 */
	public void addFreeformListener(FreeformListener listener) {
		addListener(FreeformListener.class, listener);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.FreeformFigure#fireExtentChanged()
	 */
	public void fireExtentChanged() {
		// CR389495: Working with nested complex activities causes in the BP
		// editor causes lockup
		// not specifically related to this CR, but caused a problem when
		// compound node
		// was moved beyond viewport's client area and de-selected - this would
		// resize
		// the viewport so that compound node no longer participated in bounds
		// calculation.
		if (state == MAXIMIZED) {
			Iterator iter = getListeners(FreeformListener.class);
			while (iter.hasNext())
				((FreeformListener) iter.next()).notifyFreeformExtentChanged();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.FreeformFigure#getFreeformExtent()
	 */
	public Rectangle getFreeformExtent() {
		// CR389495: Working with nested complex activities causes in the BP
		// editor causes lockup
		// same as above
		if (state == MAXIMIZED)
			return helper.getFreeformExtent();
		return getBounds();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.FreeformFigure#removeFreeformListener(org.eclipse.draw2d.FreeformListener)
	 */
	public void removeFreeformListener(FreeformListener listener) {
		removeListener(FreeformListener.class, listener);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.FreeformFigure#setFreeformBounds(org.eclipse.draw2d.geometry.Rectangle)
	 */
	public void setFreeformBounds(Rectangle bounds) {
		if (getState() == MAXIMIZED)
			helper.setFreeformBounds(bounds);
	}

	/*
	 * CR389070: Figures are abbreviating rule figures names and making them
	 * unreadable New Method on IContainerFigure
	 * 
	 * @see com.sybase.stf.gem.diagram.editor.figures.IContainerFigure#getLayer(java.lang.Object)
	 */
	public Layer getLayer(Object key) {
		if (windowFigure != null && windowFigure.isVisible())
			return windowFigure.getLayer(key);
		return null;
	}
}