/*******************************************************************************
 * Copyright (c) 2007 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 org.eclipse.jpt.utility.internal.ClassTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;

/**
 * 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.
 * <pre>
 * -Group Box 1------------------------------
 * |                     ------------------ |
 * | Name:               | I              | |
 * |                     ------------------ |
 * |                     ---------          |
 * | 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
{
	/**
	 * <code>true</code> if the length of every control needs to be updated
	 * when control are added or removed; <code>false</code> to add or remove
	 * the control and then at the end invoke {@link #revalidateSize()}.
	 */
	private boolean autoValidate;

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

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

	/**
	 * 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 -1.
	 */
	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);

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

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

	/**
	 * Adds the given control. Its preferred width will be used along with the
	 * width of all the other controls in order to get the widest control and
	 * use its width as the width for all the controls.
	 *
	 * @param control The control to be added
	 */
	public void add(Control control)
	{
		Wrapper wrapper = buildWrapper(control);
		wrapper.addControlListener(controlListener);
		wrappers.add(wrapper);

		revalidate();
	}

	/**
	 * Adds the given control. Its preferred width will be used along with the
	 * width of all the other controls in order to get the widest control and
	 * use its width as the width for all the controls.
	 *
	 * @param controlAligner The <code>ControlAligner</code> to be added
	 * @exception IllegalArgumentException Can't add the ControlAligner to itself
	 */
	public void add(ControlAligner controlAligner)
	{
		if (controlAligner == this)
		{
			throw new IllegalArgumentException("Can't add the ControlAligner to itself");
		}

		Wrapper wrapper = buildWrapper(controlAligner);
		wrapper.addControlListener(controlListener);
		wrappers.add(wrapper);

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

	/**
	 * 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 items The collection of <code>Control</code>s
	 */
	public void addAll(Collection<? extends Control> items)
	{
		// Deactivate the auto validation while adding all the Controls
		// in order to improve performance
		boolean oldAutoValidate = autoValidate;
		autoValidate = false;

		for (Control item : items)
		{
			add(item);
		}

		autoValidate = oldAutoValidate;
		revalidate();
	}

	/**
	 * 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 component and use its width as the width for all the components.
	 *
	 * @param items The collection of <code>ControlAligner</code>s
	 */
	public void addAllComponentAligners(Collection<ControlAligner> aligners)
	{
		// Deactivate the auto validation while adding all the JComponents and/or
		// ComponentAligners in order to improve performance
		boolean oldAutoValidate = autoValidate;
		autoValidate = false;

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

		autoValidate = oldAutoValidate;
		revalidate();
	}

	/**
	 * 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 component and use its width as the width for all the components.
	 *
	 * @param items The collection of <code>Control</code>s
	 */
	public void addAllComponents(Collection<? extends Control> components)
	{
		// Deactivate the auto validation while adding all the JComponents and/or
		// ComponentAligners in order to improve performance
		boolean oldAutoValidate = autoValidate;
		autoValidate = false;

		for (Control component : components)
		{
			add(component);
		}

		autoValidate = oldAutoValidate;
		revalidate();
	}

   /**
	 * Adds the given <code>ControListener</code>.
	 *
	 * @param listener The <code>ControlListener</code> to be added
	 */
	private void addControlListener(ControlListener listener)
	{
		if (changeSupport == null)
		{
		    changeSupport = new ArrayList<ControlListener>();
		}

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

   /**
	 * 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))
		{
			// Set a dummy widget otherwise EventObject will
			// throw a NPE for its source
			Event event  = new Event();
			event.widget = SWTUtil.getShell();

			ControlEvent controlEvent = new ControlEvent(event);

			// It seems we need to use reflection so the source can properly be set
			ClassTools.setFieldValue(controlEvent, "source", this);

			for (ControlListener listener : changeSupport)
			{
				listener.controlResized(controlEvent);
			}
		}
	}

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

	/**
	 * Returns the size by determining which control has the greatest
	 * width.
	 *
	 * @return The size of this <code>ControlAligner</code>, which is
	 * {@link #getMaximumWidth()} for the width
	 */
	private Point getPreferredSize()
	{
		if (maximumWidth == -1)
		{
			recalculateWidth();
		}

		return new Point(maximumWidth, 0);
	}

	/**
	 * Initializes this <code>ControlAligner</code>.
	 */
	private void initialize()
	{
		this.autoValidate    = true;
		this.maximumWidth    = -1;
		this.controlListener = new ControlHandler();
		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.isLocked())
		{
			return;
		}

		Point size = wrapper.getCachedSize();
		size.x = 0;
		size.y = 0;

		wrapper.setPreferredSize(DEFAULT_SIZE);
	}

	/**
	 * Determines whether the length of each control should be set each time a
	 * control is added or removed. If the control's text is changed and
	 * {@link #isAutoValidate()} returns <code>true</code> then the length of
	 * each control is automatically updated. When <code>false</code> is returned,
	 * {@link #revalidateSize()}has to be called manually.
	 *
	 * @return <code>true</code> to recalculate the length of every control
	 * when a control is either added or removed; <code>false</code> to allow
	 * all the controls to be either added or removed before invoking
	 * {@link #revalidateSize()}
	 */
	public boolean isAutoValidate()
	{
		return autoValidate;
	}

	/**
	 * Determines whether the wrapped component is visible or not, which will
	 * determine if its preferred width will be included in the calculation of
	 * this <code>ComponentAligner</code>'s minimum width.
	 *
	 * @return <code>true</code> if the source is visible; <code>false</code>
	 * otherwise
	 */
	private boolean isVisible()
	{
		boolean visible = true;

		for (Wrapper wrapper : wrappers)
		{
			visible &= wrapper.isVisible();
		}

		return visible;
	}

	/**
	 * Updates the maximum length based on the widest control. This methods
	 * does not update the width of the controls.
	 */
	private void recalculateWidth()
	{
		int width = -1;

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

			// The size has not been calculated yet
			if ((size.y == 0) && wrapper.isVisible())
			{
				Point newSize = wrapper.getPreferredSize();

				size.x = newSize.x;
				size.y = newSize.y;
			}

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

		locked = true;
		setMaximumWidth(width);
		locked = false;
	}

	/**
	 * Removes the given control. Its preferred width will not be used when
	 * calculating the widest control.
	 *
	 * @param control The control to be removed
	 */
	public void remove(Control control)
	{
		Wrapper wrapper = retrieveWrapper(control);
		wrapper.removeControlListener(controlListener);
		wrappers.remove(wrapper);

//		if (control.isPreferredSizeSet())
//		{
//			control.setPreferredSize(null);
//		}

		revalidate();
	}

	/**
	 * Removes the given <code>ControlAligner</code>. Its preferred width
	 * will not be used when calculating the widest control.
	 *
	 * @param controlAligner The <code>ControlAligner</code> to be removed
	 */
	public void remove(ControlAligner controlAligner)
	{
		Wrapper wrapper = retrieveWrapper(controlAligner);
		wrapper.removeControlListener(controlListener);
		wrappers.remove(wrapper);

		revalidate();
	}

	/**
	 * Removes the given <code>ControlListener</code>.
	 *
	 * @param listener The <code>ControlListener</code> to be removed
	 */
	private void removeControlListener(ControlListener 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.getSource() == 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.
	 */
	private void revalidate()
	{
		if (autoValidate)
		{
			recalculateWidth();
			revalidatePreferredSizeImp();
		}
	}

	/**
	 * Updates the preferred size of every component based on the widest
	 * component.
	 */
	private void revalidatePreferredSizeImp()
	{
		for (Wrapper wrapper : wrappers)
		{
			Point size = wrapper.getCachedSize();
			size = new Point(maximumWidth, size.y);
			wrapper.setPreferredSize(size);
		}
	}

	/**
	 * Updates the size of every control based on the widest control.
	 */
	public void revalidateSize()
	{
		recalculateWidth();
		revalidateSizeImp();
	}

	/**
	 * Updates the size of every control based on the widest control.
	 */
	private void revalidateSizeImp()
	{
		// Set the preferred width for every control
		for (Wrapper wrapper : wrappers)
		{
			Point size = wrapper.getCachedSize();
			size = new Point(maximumWidth, size.y);
			wrapper.setPreferredSize(size);
		}
	}

	/**
	 * Sets the length of the widest control. If the length was not calulcated,
	 * then this value is -1.
	 *
	 * @param maximumWidth The width of the widest control
	 */
	private void setMaximumWidth(int maximumWidth)
	{
		int oldMaximumWidth = getMaximumWidth();
		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();
		StringTools.buildToStringFor(this, sb);
		sb.append("autoValidate=");
		sb.append(autoValidate);
		sb.append(", maximumWidth=");
		sb.append(maximumWidth);
		sb.append(", wrappers=");
		sb.append(wrappers);
		return sb.toString();
	}

	/**
	 * This <code>Wrapper</code> encapsulates a {@link ControlAligner}.
	 */
	private class ControlAlignerWrapper implements Wrapper
	{
		/**
		 * The cached size, which is {@link ControlAligner#maximumWidth}.
		 */
		private 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;
			cachedSize = new Point(controlAligner.maximumWidth, 0);
		}

		/*
		 * (non-Javadoc)
		 */
		public void addControlListener(ControlListener listener)
		{
			controlAligner.addControlListener(listener);
		}

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

		/*
		 * (non-Javadoc)
		 */
		public Point getPreferredSize()
		{
			return controlAligner.getPreferredSize();
		}

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

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

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

		/*
		 * (non-Javadoc)
		 */
		public void removeControlListener(ControlListener listener)
		{
			controlAligner.removeControlListener(listener);
		}

		/*
		 * (non-Javadoc)
		 */
		public void setPreferredSize(Point size)
		{
			if (size == DEFAULT_SIZE)
			{
				controlAligner.maximumWidth = -1;
			}
			else if (controlAligner.maximumWidth != size.x)
			{
				controlAligner.maximumWidth = size.x;
				controlAligner.revalidateSizeImp();
			}
		}

		/*
		 * (non-Javadoc)
		 */
		@Override
		public String toString()
		{
			StringBuffer sb = new StringBuffer();
			StringTools.buildToStringFor(this, sb);
			sb.append("cachedSize=");
			sb.append(cachedSize);
			sb.append(", controlAligner=");
			sb.append(controlAligner);
			return sb.toString();
		}
	}

	/**
	 * The listener added to each of the control that listens only to a text
	 * change.
	 */
	private class ControlHandler implements ControlListener
	{
		/*
		 * (non-Javadoc)
		 */
		public void controlMoved(ControlEvent e)
		{
			// Nothing to do
		}

		/*
		 * (non-Javadoc)
		 */
		public void controlResized(ControlEvent e)
		{
			invalidate(e.getSource());
			revalidate();
		}
	}

	/**
	 * 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;
			cachedSize = new Point(0, 0);
		}

		/*
		 * (non-Javadoc)
		 */
		public void addControlListener(ControlListener listener)
		{
			control.addControlListener(listener);
		}

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

		/*
		 * (non-Javadoc)
		 */
		public Point getPreferredSize()
		{
			return control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
		}

		/*
		 * (non-Javadoc)
		 */
		public Object getSource()
		{
			return control;
		}

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

		/*
		 * (non-Javadoc)
		 */
		public boolean isVisible()
		{
			return control.isVisible();
		}

		/*
		 * (non-Javadoc)
		 */
		public void removeControlListener(ControlListener listener)
		{
			control.removeControlListener(listener);
		}

		/*
		 * (non-Javadoc)
		 */
		public void setPreferredSize(Point size)
		{
			GridData data = (GridData) control.getLayoutData();

			if (data == null)
			{
				data = new GridData();
				data.horizontalAlignment = SWT.FILL;
				control.setLayoutData(data);
			}

			data.widthHint  = size.x;
			data.heightHint = size.y;
		}

		/*
		 * (non-Javadoc)
		 */
		@Override
		public String toString()
		{
			StringBuffer sb = new StringBuffer();
			StringTools.buildToStringFor(this, sb);
			sb.append("cachedSize=");
			sb.append(cachedSize);
			sb.append(", control=");
			sb.append(control);
			return sb.toString();
		}
	}

	/**
	 * This <code>Wrapper</code> helps to encapsulate heterogeneous objects and
	 * apply the same behavior on them.
	 */
	private interface Wrapper
	{
	   /**
		 * Adds a <code>IPropertyChangeListener</code> for a specific property.
		 * The listener will be invoked only when a call on
		 * <code>firePropertyChange</code> names that specific property.
		 *
		 * @param listener The <code>ControlListener</code> to be added
		 */
		public void addControlListener(ControlListener listener);

		/**
		 * Returns the cached size of the encapsulated source.
		 *
		 * @return A non-<code>null</code> size
		 */
		public Point getCachedSize();

		/**
		 * Returns the preferred size of the wrapped source.
		 *
		 * @return The preferred size
		 */
		public Point getPreferredSize();

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

		/**
		 * 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>
		 */
		public boolean isLocked();

		/**
		 * Determines whether the wrapped component is visible or not, which will
		 * determine if its preferred width will be included in the calculation of
		 * this <code>ComponentAligner</code>'s minimum width.
		 *
		 * @return <code>true</code> if the source is visible; <code>false</code>
		 * otherwise
		 */
		boolean isVisible();

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

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