/*******************************************************************************
 * 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.Point;
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
 */
public class CompoundNodeFigure extends BaseNodeFigure implements
		FreeformFigure, IContainerFigure {
	public final static int MINIMIZED = 1;

	public final static int RESTORED = 2;

	public 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");

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

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

	public IconFigure getIconFigure() {
		return iconFigure;
	}

	/**
	 * @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);
	}

	public int getState() {
		return state;
	}

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

	protected 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 Point getScrollPosition() {
		return windowFigure.getScrollPosition();
	}

	public int addTab(String s) {
		return windowFigure.addTab(s);
	}

	public void removeTab(int index) {
		windowFigure.removeTab(index);
	}

	public void setCurrentTab(int index) {
		windowFigure.setCurrentTab(index);
	}

	public int getCurrentTab() {
		return windowFigure.getCurrentTab();
	}

	public void setContents(int index, Object contents) {
		windowFigure.setContents(index, contents);
	}

	public Object getContents(int index) {
		return windowFigure.getContents(index);
	}

	public Object getContents() {
		return windowFigure.getContents();
	}

	public TabbedTitleBarBorder getTabbedTitleBarBorder() {
		return windowFigure.getTabbedTitleBarBorder();
	}

	public void addCompoundFigureListener(CompoundFigureListener listener) {
		windowFigure.getTabbedTitleBarBorder()
				.addTabbedWindowListener(listener);
	}

	public void removeCompoundFigureListener(CompoundFigureListener listener) {
		windowFigure.getTabbedTitleBarBorder().removeTabbedWindowListener(
				listener);
	}

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