/*******************************************************************************
 * Copyright (c) 2007, 2010 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.ui.internal.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

/**
 * This class is responsible to set a preferred width on the registered widgets
 * (either <code>Control</code> or <code>ControlAligner</code>) based on the
 * widest widget.
 * <p>
 * Important: The layout data has to be a <code>GridData</code>. If none is set,
 * then a new <code>GridData</code> is automatically created.
 * <p>
 * Here an example of the result if this aligner is used to align controls
 * within either one or two group boxes, the controls added are the labels in
 * this case. It is also possible to align controls on the right side of the
 * main component, a spacer can be used for extra space.
 * <p>
 * Here's an example:
 * <pre>
 * - Group Box 1 --------------------------------------------------------------
 * |                     -------------------------------------- ------------- |
 * | Name:               | I                                  | | Browse... | |
 * |                     -------------------------------------- ------------- |
 * |                     ---------                                            |
 * | Preallocation Size: |     |I|                                            |
 * |                     ---------                                            |
 * |                     --------------------------------------               |
 * | Descriptor:         |                                  |v|               |
 * |                     --------------------------------------               |
 * ----------------------------------------------------------------------------
 *
 * - Group Box 2 --------------------------------------------------------------
 * |                     --------------------------------------               |
 * | Mapping Type:       |                                  |V|               |
 * |                     --------------------------------------               |
 * |                     --------------------------------------               |
 * | Check in Script:    | I                                  |               |
 * |                     --------------------------------------               |
 * ----------------------------------------------------------------------------</pre>
 *
 * @version 2.0
 * @since 2.0
 */
@SuppressWarnings("nls")
public final class ControlAligner
{
	/**
	 * Flag used to prevent a validation so it can be done after an operation
	 * completed.
	 */
	private boolean autoValidate;

	/**
	 * The utility class used to support bound properties.
	 */
	private Collection<Listener> changeSupport;

	/**
	 * The listener added to each of the controls that listens only to a text
	 * change.
	 */
	private Listener listener;

	/**
	 * Prevents infinite recursion when recalculating the preferred width.
	 * This happens in an hierarchy of <code>ControlAligner</code>s. The lock
	 * has to be placed here and not in the {@link ControlAlignerWrapper}.
	 */
	private boolean locked;

	/**
	 * The length of the widest control. If the length was not calculated, then
	 * this value is 0.
	 */
	private int maximumWidth;

	/**
	 * The collection of {@link Wrapper}s encapsulating either <code>Control</code>s
	 * or {@link ControlAligner}s.
	 */
	private Collection<Wrapper> wrappers;

	/**
	 * A null-<code>Point</code> object used to clear the preferred size.
	 */
	private static final Point DEFAULT_SIZE = new Point(SWT.DEFAULT, SWT.DEFAULT);

	/**
	 * The types of events to listen in order to properly adjust the size of all
	 * the widgets.
	 */
	private static final int[] EVENT_TYPES = {
		SWT.Dispose,
		SWT.Hide,
		SWT.Resize,
		SWT.Show
	};

	/**
	 * Creates a new <code>ControlAligner</code>.
	 */
	public ControlAligner() {
		super();
		initialize();
	}

	/**
	 * Creates a new <code>ControlAligner</code>.
	 *
	 * @param controls The collection of <code>Control</code>s
	 */
	public ControlAligner(Collection<? extends Control> controls) {
		this();
		addAllControls(controls);
	}

	/**
	 * Adds the given control. Its width will be used along with the width of all
	 * the other registered controls in order to get the greater witdh and use
	 * it as the width for all the controls.
	 *
	 * @param control The <code>Control</code> to be added
	 */
	public void add(Control control) {

		Assert.isNotNull(control, "Can't add null to this ControlAligner");

		Wrapper wrapper = buildWrapper(control);
		wrapper.addListener(listener);
		wrappers.add(wrapper);

		revalidate(false);
	}

	/**
	 * Adds the given control. Its width will be used along with the width of all
	 * the other registered controls in order to get the greater witdh and use
	 * it as the width for all the controls.
	 *
	 * @param controlAligner The <code>ControlAligner</code> to be added
	 * @exception IllegalArgumentException Can't add the <code>ControlAligner</code>
	 * to itself
	 */
	public void add(ControlAligner controlAligner) {

		Assert.isNotNull(controlAligner, "Can't add null to this ControlAligner");
		Assert.isLegal(controlAligner != this, "Can't add the ControlAligner to itself");

		Wrapper wrapper = buildWrapper(controlAligner);
		wrapper.addListener(listener);
		wrappers.add(wrapper);

		if (!controlAligner.wrappers.isEmpty()) {
			revalidate(false);
		}
	}

	/**
	 * Adds the items contained in the given collection into this
	 * <code>ControlAligner</code>. The preferred width of each item will be
	 * used along with the width of all the other items in order to get the
	 * widest control and use its width as the width for all the controls.
	 *
	 * @param aligners The collection of <code>ControlAligner</code>s
	 */
	public void addAllControlAligners(Collection<ControlAligner> aligners) {

		// Deactivate the auto validation while adding all the Controls and/or
		// ControlAligners in order to improve performance
		boolean oldAutoValidate = autoValidate;
		autoValidate = false;

		for (ControlAligner aligner : aligners) {
			add(aligner);
		}

		autoValidate = oldAutoValidate;
		revalidate(false);
	}

   /**
	 * Adds the items contained in the given collection into this
	 * <code>ControlAligner</code>. The preferred width of each item will be
	 * used along with the width of all the other items in order to get the
	 * widest control and use its width as the width for all the controls.
	 *
	 * @param controls The collection of <code>Control</code>s
	 */
	public void addAllControls(Collection<? extends Control> controls) {

		// Deactivate the auto validation while adding all the Controls and/or
		// ControlAligners in order to improve performance
		boolean oldAutoValidate = autoValidate;
		autoValidate = false;

		for (Control control : controls) {
			add(control);
		}

		autoValidate = oldAutoValidate;
		revalidate(false);
	}

   /**
	 * Adds the given <code>ControListener</code>.
	 *
	 * @param listener The <code>Listener</code> to be added
	 */
	private void addListener(Listener listener) {

		if (changeSupport == null) {
		    changeSupport = new ArrayList<Listener>();
		}

		changeSupport.add(listener);
   }

	/**
	 * Creates a new <code>Wrapper</code> that encapsulates the given source.
	 *
	 * @param control The control to be wrapped
	 * @return A new {@link Wrapper}
	 */
	private Wrapper buildWrapper(Control control) {
		return new ControlWrapper(control);
	}

   /**
	 * Creates a new <code>Wrapper</code> that encapsulates the given source.
	 *
	 * @param ControlAligner The <code>ControlAligner</code> to be wrapped
	 * @return A new {@link ControlAlignerWrapper}
	 */
	private Wrapper buildWrapper(ControlAligner ControlAligner) {
		return new ControlAlignerWrapper(ControlAligner);
	}

	/**
	 * Calculates the width taken by the widgets and returns the maximum width.
	 *
	 * @param recalculateSize <code>true</code> to recalculate the preferred size
	 * of all the wrappers contained within them rather than using the cached
	 * size; <code>false</code> to use the cached size
	 */
	private int calculateWidth(boolean recalculateSize) {

		int width = 0;

		for (Wrapper wrapper : wrappers) {
			Point size = wrapper.cachedSize();

			// The size has not been calculated yet
			if (recalculateSize || (size.x == 0)) {
				size = wrapper.calculateSize();
			}

			// Only keep the greatest width
			width = Math.max(size.x, width);
		}

		return width;
	}

	/**
	 * Reports a bound property change.
	 *
	 * @param oldValue the old value of the property (as an int)
	 * @param newValue the new value of the property (as an int)
	 */
	private void controlResized(int oldValue, int newValue) {

		if ((changeSupport != null) && (oldValue != newValue)) {
			Event event  = new Event();
			event.widget = SWTUtil.getShell();
			event.data   = this;

			for (Listener listener : changeSupport) {
				listener.handleEvent(event);
			}
		}
	}

	/**
	 * Disposes this <code>ControlAligner</code>, this can improve the speed of
	 * disposing a pane. When a pane is disposed, this aligner doesn't need to
	 * revalidate its size upon dispose of its widgets.
	 */
	public void dispose() {

		for (Iterator<Wrapper> iter = wrappers.iterator(); iter.hasNext(); ) {
			Wrapper wrapper = iter.next();
			wrapper.removeListener(listener);
			iter.remove();
		}

		this.wrappers.clear();
	}

	/**
	 * Returns the length of the widest control. If the length was not
	 * calculated, then this value is 0.
	 *
	 * @return The width of the widest control or 0 if the length has not been
	 * calculated yet
	 */
	public int getMaximumWidth() {
		return maximumWidth;
	}

	/**
	 * Initializes this <code>ControlAligner</code>.
	 */
	private void initialize() {

		this.autoValidate = true;
		this.maximumWidth = 0;
		this.listener     = new ListenerHandler();
		this.wrappers     = new ArrayList<Wrapper>();
	}

	/**
	 * Invalidates the size of the given object.
	 *
	 * @param source The source object to be invalidated
	 */
	private void invalidate(Object source) {

		Wrapper wrapper = retrieveWrapper(source);

		if (!wrapper.locked()) {
			Point size = wrapper.cachedSize();
			size.x = size.y = 0;
			wrapper.setSize(DEFAULT_SIZE);
		}
	}

	/**
	 * Updates the maximum length based on the widest control. This methods
	 * does not update the width of the controls.
	 *
	 * @param recalculateSize <code>true</code> to recalculate the preferred size
	 * of all the wrappers contained within them rather than using the cached
	 * size; <code>false</code> to use the cached size
	 */
	private void recalculateWidth(boolean recalculateSize) {

		int width = calculateWidth(recalculateSize);

		try {
			locked = true;
			setMaximumWidth(width);
		}
		finally {
			locked = false;
		}
	}

	/**
	 * Removes the given control. Its preferred width will not be used when
	 * calculating the preferred width.
	 *
	 * @param control The control to be removed
	 * @exception AssertionFailedException If the given <code>Control</code> is
	 * <code>null</code>
	 */
	public void remove(Control control) {

		Assert.isNotNull(control, "The Control to remove cannot be null");

		Wrapper wrapper = retrieveWrapper(control);
		wrapper.removeListener(listener);
		wrappers.remove(wrapper);

		revalidate(true);
	}

	/**
	 * Removes the given <code>ControlAligner</code>. Its preferred width
	 * will not be used when calculating the preferred witdh.
	 *
	 * @param controlAligner The <code>ControlAligner</code> to be removed
	 * @exception AssertionFailedException If the given <code>ControlAligner</code>
	 * is <code>null</code>
	 */
	public void remove(ControlAligner controlAligner) {

		Assert.isNotNull(controlAligner, "The ControlAligner to remove cannot be null");

		Wrapper wrapper = retrieveWrapper(controlAligner);
		wrapper.removeListener(listener);
		wrappers.remove(wrapper);

		revalidate(true);
	}

	/**
	 * Removes the given <code>Listener</code>.
	 *
	 * @param listener The <code>Listener</code> to be removed
	 */
	private void removeListener(Listener listener) {

		changeSupport.remove(listener);

		if (changeSupport.isEmpty()) {
			changeSupport = null;
		}
	}

	/**
	 * Retrieves the <code>Wrapper</code> that is encapsulating the given object.
	 *
	 * @param source Either a <code>Control</code> or a <code>ControlAligner</code>
	 * @return Its <code>Wrapper</code>
	 */
	private Wrapper retrieveWrapper(Object source) {

		for (Wrapper wrapper : wrappers) {
			if (wrapper.source() == source) {
				return wrapper;
			}
		}

		throw new IllegalArgumentException("Can't retrieve the Wrapper for " + source);
	}

	/**
	 * If the count of control is greater than one and {@link #isAutoValidate()}
	 * returns <code>true</code>, then the size of all the registered
	 * <code>Control</code>s will be udpated.
	 *
	 * @param recalculateSize <code>true</code> to recalculate the preferred size
	 * of all the wrappers contained within them rather than using the cached
	 * size; <code>false</code> to use the cached size
	 */
	private void revalidate(boolean recalculateSize) {

		if (autoValidate) {
			recalculateWidth(recalculateSize);
			updateWrapperSize(recalculateSize);
		}
	}

	/**
	 * Bases on the information contained in the given <code>Event</code>,
	 * resize the controls.
	 *
	 * @param event The <code>Event</code> sent by the UI thread when the state
	 * of a widget changed
	 */
	private void revalidate(Event event) {

		// We don't need to revalidate during a revalidation process
		if (locked) {
			return;
		}

		Object source;

		if (event.widget != SWTUtil.getShell()) {
			source = event.widget;
			Control control = (Control) source;

			// When a dialog is opened, we need to actually force a layout of
			// the controls, this is required because the control is actually
			// not visible when the preferred width is caculated
			if (control == control.getShell()) {
				if (event.type == SWT.Dispose) {
					return;
				}

				source = null;
			}
		}
		else {
			source = event.data;
		}

		// Either remove the ControlWrapper if the widget was disposed or
		// invalidate the widget in order to recalculate the preferred size
		if (source != null) {
			if (event.type == SWT.Dispose) {
				Wrapper wrapper = retrieveWrapper(source);
				wrappers.remove(wrapper);
			}
			else {
				invalidate(source);
			}
		}

		// Now revalidate all the Controls and ControlAligners
		revalidate(true);
	}

	/**
	 * Sets the length of the widest control. If the length was not calulcated,
	 * then this value is 0.
	 *
	 * @param maximumWidth The width of the widest control
	 */
	private void setMaximumWidth(int maximumWidth) {

		int oldMaximumWidth = this.maximumWidth;
		this.maximumWidth = maximumWidth;
		controlResized(oldMaximumWidth, maximumWidth);
	}

	/**
	 * Returns a string representation of this <code>ControlAligner</code>.
	 *
	 * @return Information about this object
	 */
	@Override
	public String toString() {

		StringBuffer sb = new StringBuffer();
		sb.append("maximumWidth=");
		sb.append(maximumWidth);
		sb.append(", wrappers=");
		sb.append(wrappers);
		return StringTools.buildToStringFor(this, sb);
	}

	/**
	 * Updates the size of every <code>Wrapper</code> based on the maximum width.
	 *
	 * @param forceRevalidate <code>true</code> to revalidate the wrapper's size
	 * even though its current size might be the same as the maximum width;
	 * <code>false</code> to only revalidate the wrappers with a different width
	 */
	private void updateWrapperSize(boolean forceRevalidate) {

		for (Wrapper wrapper : wrappers) {
			Point cachedSize = wrapper.cachedSize();

			// No need to change the size of the wrapper since it's always using
			// the maximum width
			if (forceRevalidate || (cachedSize.x != maximumWidth)) {
				Point size = new Point(maximumWidth, cachedSize.y);
				wrapper.setSize(size);
			}
		}
	}

	/**
	 * This <code>Wrapper</code> encapsulates a {@link ControlAligner}.
	 */
	private class ControlAlignerWrapper implements Wrapper {
		/**
		 * The cached size, which is {@link ControlAligner#maximumWidth}.
		 */
		private final Point cachedSize;

		/**
		 * The <code>ControlAligner</code> encapsulated by this
		 * <code>Wrapper</code>.
		 */
		private final ControlAligner controlAligner;

		/**
		 * Creates a new <code>ControlAlignerWrapper</code> that encapsulates
		 * the given <code>ControlAligner</code>.
		 *
		 * @param controlAligner The <code>ControlAligner</code> to be
		 * encapsulated by this <code>Wrapper</code>
		 */
		private ControlAlignerWrapper(ControlAligner controlAligner) {
			super();
			this.controlAligner = controlAligner;
			this.cachedSize     = new Point(controlAligner.maximumWidth, 0);
		}

		/*
		 * (non-Javadoc)
		 */
		public void addListener(Listener listener) {
			controlAligner.addListener(listener);
		}

		/*
		 * (non-Javadoc)
		 */
		public Point cachedSize() {
			cachedSize.x = controlAligner.maximumWidth;
			return cachedSize;
		}

		/*
		 * (non-Javadoc)
		 */
		public Point calculateSize() {

			Point size = new Point(controlAligner.calculateWidth(false), 0);

			if (size.x != SWT.DEFAULT) {
				cachedSize.x = size.x;
			}
			else {
				cachedSize.x = 0;
			}

			if (size.y != SWT.DEFAULT) {
				cachedSize.y = size.y;
			}
			else {
				cachedSize.y = 0;
			}

			return size;
		}

		/*
		 * (non-Javadoc)
		 */
		public boolean locked() {
			return controlAligner.locked;
		}

		/*
		 * (non-Javadoc)
		 */
		public void removeListener(Listener listener) {
			controlAligner.removeListener(listener);
		}

		/*
		 * (non-Javadoc)
		 */
		public void setSize(Point size) {

			if (size == DEFAULT_SIZE) {
				controlAligner.maximumWidth = 0;
			}
			else if (controlAligner.maximumWidth != size.x) {
				controlAligner.maximumWidth = size.x;
				controlAligner.updateWrapperSize(true);
			}
		}

		/*
		 * (non-Javadoc)
		 */
		public Object source() {
			return controlAligner;
		}

		/*
		 * (non-Javadoc)
		 */
		@Override
		public String toString() {

			StringBuffer sb = new StringBuffer();
			sb.append("Cached size=");
			sb.append(cachedSize);
			sb.append(", ControlAligner=");
			sb.append(controlAligner);
			return StringTools.buildToStringFor(this, sb);
		}
	}

	/**
	 * This <code>Wrapper</code> encapsulates a {@link Control}.
	 */
	private class ControlWrapper implements Wrapper {
		/**
		 * The cached size, which is control's size.
		 */
		private Point cachedSize;

		/**
		 * The control to be encapsulated by this <code>Wrapper</code>.
		 */
		private final Control control;

		/**
		 * Creates a new <code>controlWrapper</code> that encapsulates the given
		 * control.
		 *
		 * @param control The control to be encapsulated by this <code>Wrapper</code>
		 */
		private ControlWrapper(Control control) {
			super();

			this.control    = control;
			this.cachedSize = new Point(0, 0);
		}

		/*
		 * (non-Javadoc)
		 */
		public void addListener(Listener listener) {

			for (int eventType : EVENT_TYPES) {
				control.addListener(eventType, listener);
			}
		}

		/*
		 * (non-Javadoc)
		 */
		public Point cachedSize() {
			return cachedSize;
		}

		/*
		 * (non-Javadoc)
		 */
		public Point calculateSize() {

			cachedSize = control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);

			// Update right away the control's GridData
			GridData gridData = (GridData) control.getLayoutData();

			if (gridData == null) {
				gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
				control.setLayoutData(gridData);
			}

			gridData.widthHint  = cachedSize.x;
			gridData.heightHint = cachedSize.y;

			// Make sure the size is not -1
			if (cachedSize.x == SWT.DEFAULT) {
				cachedSize.x = 0;
			}

			if (cachedSize.y == SWT.DEFAULT) {
				cachedSize.y = 0;
			}

			return cachedSize;
		}

		/*
		 * (non-Javadoc)
		 */
		public boolean locked() {
			return false;
		}

		/*
		 * (non-Javadoc)
		 */
		public void removeListener(Listener listener) {

			for (int eventType : EVENT_TYPES) {
				control.removeListener(eventType, listener);
			}
		}

		/*
		 * (non-Javadoc)
		 */
		public void setSize(Point size) {

			if (control.isDisposed()) {
				return;
			}

			// Update the GridData with the new size
			GridData gridData = (GridData) control.getLayoutData();

			if (gridData == null) {
				gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
				control.setLayoutData(gridData);
			}

			gridData.widthHint  = size.x;
			gridData.heightHint = size.y;

			// Force the control to be resized, and tell its parent to layout
			// its widgets
			if (size.x > 0) {
//				locked = true;
//				try  {
////					control.getParent().layout(new Control[] { control });
//					control.getParent().layout(true);
//				}
//				finally {
//					locked = false;
//				}
				Rectangle bounds = control.getBounds();

				// Only update the control's width if it's
				// different from the current size
				if (bounds.width != size.x) {
					locked = true;

					try {
//						control.setBounds(bounds.x, bounds.y, size.x, size.y);
						control.getParent().layout(true);
					}
					finally
					{
						locked = false;
					}
				}
			}
		}

		/*
		 * (non-Javadoc)
		 */
		public Control source() {
			return control;
		}

		/*
		 * (non-Javadoc)
		 */
		@Override
		public String toString() {

			StringBuffer sb = new StringBuffer();
			sb.append("Cached size=");
			sb.append(cachedSize);
			sb.append(", Control=");
			sb.append(control);
			return StringTools.buildToStringFor(this, sb);
		}
	}

	/**
	 * The listener added to each of the control that is notified in order to
	 * revalidate the preferred size.
	 */
	private class ListenerHandler implements Listener {
		public void handleEvent(Event event) {
			ControlAligner.this.revalidate(event);
		}
	}

	/**
	 * This <code>Wrapper</code> helps to encapsulate heterogeneous objects and
	 * apply the same behavior on them.
	 */
	private interface Wrapper {
	   /**
		 * Adds the given <code>Listener</code> to wrapped object in order to
		 * receive notification when its property changed.
		 *
		 * @param listener The <code>Listener</code> to be added
		 */
		void addListener(Listener listener);

		/**
		 * Returns the cached size of the encapsulated source.
		 *
		 * @return A non-<code>null</code> <code>Point</code> where the x is the
		 * width and the y is the height of the widget
		 */
		Point cachedSize();

		/**
		 * Calculates the preferred size the wrapped object would take by itself.
		 *
		 * @return The calculated size
		 */
		Point calculateSize();

		/**
		 * Prevents infinite recursion when recalculating the preferred width.
		 * This happens in an hierarchy of <code>ControlAligner</code>s.
		 *
		 * @return <code>true</code> to prevent this <code>Wrapper</code> from
		 * being invalidated; otherwise <code>false</code>
		 */
		boolean locked();

		/**
		 * Removes the given <code>Listener</code>.
		 *
		 * @param listener The <code>Listener</code> to be removed
		 */
		void removeListener(Listener listener);

		/**
		 * Sets the size on the encapsulated source.
		 *
		 * @param size The new size
		 */
		void setSize(Point size);

		/**
		 * Returns the encapsulated object.
		 *
		 * @return The object that is been wrapped
		 */
		Object source();
	}
}