/*******************************************************************************
 * Copyright (c) 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.common.ui.internal.dialogfield;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.Assert;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Hyperlink;

/**
 * Base class of all Dialog fields. Dialog fields manage controls together with
 * the model, independed from the creation time of the widgets. - support for
 * automated layouting. - enable / disable, set focus a concept of the base
 * class. DialogField have a label.
 * 
 * DialogField may be used in two different context:
 * <ol>
 * <li> In side dialog. In this case, whenever there is anything change in the
 * dialog field, such as user type anything, the dialog should listen to the
 * dialogFieldChanged() events and do things like validation. When user press
 * the "OK" button, dialog should call getXXX to get the value from the dialog
 * field and apply them.
 * <li> In side form based editor or properties view. In this case, whenever
 * there is anything change in the dialog field, such as user type anything, the
 * editor/view should listen to the dialogFieldChanged() events and do things
 * like validation. When user press "Enter" or move the focus out of the control
 * (finish editing), the dialog field will fire out dialogFieldApplied() events,
 * and the editor/view should listen to this event and apply the value to the
 * underlying model.
 * </ol>
 * 
 * The basic idea of the DialogField framework is comming from
 * <code>org.eclipse.jface.preference.FieldEditor</code> and
 * <code>org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField</code>
 * 
 * @author mengbo
 */
public class DialogFieldBase implements DialogField {
	private Label _label;

	private Label _requiredLabel;

	private String _labelText;

	private IDialogFieldChangeListener _dialogFieldChangeListener;

	private IDialogFieldApplyListener _dialogFieldApplyListener;

	private boolean _enabled;

	private FontMetrics _fontMetrics;

	private IHyperlinkListener _listener;

	private Hyperlink _hyperlink;

	private Map _attachedData;

	private boolean _isRequired;

	private String toolTip;

	/**
	 * default constructor
	 */
	public DialogFieldBase() {
		_enabled = true;
		_label = null;
		_requiredLabel = null;
		_hyperlink = null;
		_labelText = ""; //$NON-NLS-1$
	}

	/**
	 * this method must be called directly after constructor, in this case,
	 * system will create a hyper link label, and when the hyper link is
	 * clicked, the corresponding method on the listene will be called. A
	 * RuntimeException will throw out if this method is called after the label
	 * has been created.
	 * 
	 * @param listener
	 *            can't be null
	 */
	public void setHyperLink(IHyperlinkListener listener) {
		if (_label != null) {
			throw new RuntimeException(
					"The Label instance does not support the listener"); //$NON-NLS-1$
		}
        this._listener = listener;
	}

	/**
	 * Sets the label of the dialog field.
	 */
	public void setLabelText(String labeltext) {
		_labelText = labeltext == null ? "" : labeltext; //$NON-NLS-1$
		// if (_isRequired)
		// {
		// _labelText = "* " + _labelText;
		// }
		// else
		// {
		// _labelText = " " + _labelText;
		// }
		if (_label != null && !_label.isDisposed()) {
			_label.setText(_labelText);
		} else if (_hyperlink != null && !_hyperlink.isDisposed()) {
			_hyperlink.setText(_labelText);
		}
	}

	/**
	 * @return return the enclosing Shell or null if one cannot be determined
	 */
	public Shell getShell() {
		if (_label != null && !_label.isDisposed()) {
			return _label.getShell();
		} else if (_hyperlink != null && !_hyperlink.isDisposed()) {
			return _hyperlink.getShell();
		}
		return null;
	}

	// ------ change listener

	/**
	 * Defines the listener for this dialog field.
	 */
	public final void setDialogFieldChangeListener(
			IDialogFieldChangeListener listener) {
		_dialogFieldChangeListener = listener;
	}

	public final void setDialogFieldApplyListener(
			IDialogFieldApplyListener listener) {
		_dialogFieldApplyListener = listener;
	}

	/**
	 * fire both dialogFieldChanged and dialogFieldApplied events.
	 */
	public void dialogFieldChangedAndApplied() {
		if (_dialogFieldChangeListener != null) {
			_dialogFieldChangeListener.dialogFieldChanged(this);
		}
		if (_dialogFieldApplyListener != null) {
			_dialogFieldApplyListener.dialogFieldApplied(this);
		}
	}

	/**
	 * fire dialogFieldChanged event.
	 * 
	 */
	public void dialogFieldChanged() {
		if (_dialogFieldChangeListener != null) {
			_dialogFieldChangeListener.dialogFieldChanged(this);
		}
	}

	/**
	 * fire dialogFieldApplied event.
	 * 
	 */
	public void dialogFieldApplied() {
		if (_dialogFieldApplyListener != null) {
			_dialogFieldApplyListener.dialogFieldApplied(this);
		}
	}

	// ------- focus management


	public boolean setFocus() {
		return false;
	}

	//
	// /**
	// * Posts <code>setFocus</code> to the display event queue.
	// */
	// public void postSetFocusOnDialogField(Display display)
	// {
	// if (display != null)
	// {
	// display.asyncExec(new Runnable()
	// {
	// public void run()
	// {
	// setFocus();
	// }
	// }
	// );
	// }
	// }

	// ------- layout helpers

	public Control[] doFillIntoGrid(FormToolkit toolkit, Composite parent,
			int nColumns) {
		assertEnoughColumns(nColumns);

		Control label = getLabelControl(toolkit, parent);
		label.setLayoutData(gridDataForLabel(nColumns));

		return new Control[] { label };
	}

	/**
	 * Initializes the computation of horizontal and vertical dialog units based
	 * on the size of current font.
	 * <p>
	 * This method must be called before any of the dialog unit based conversion
	 * methods are called.
	 * </p>
	 * 
	 * @param control
	 *            a control from which to obtain the current font
	 * @return the font metrics for control
	 */
	protected FontMetrics getDialogUnits(Control control) {
		if (_fontMetrics == null) {
			// Compute and store a font metric
			GC gc = new GC(control);
			gc.setFont(control.getFont());
			_fontMetrics = gc.getFontMetrics();
			gc.dispose();
		}
		return _fontMetrics;
	}

	/**
	 * Returns the number of columns of the dialog field. To be reimplemented by
	 * dialog field implementors.
	 */
	public int getNumberOfControls() {
		return 1;
	}

	/**
	 * @param span
	 * @return a new GridData for the horizontal 'span' value
	 */
	protected static GridData gridDataForLabel(int span) {
		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gd.horizontalSpan = span;
		return gd;
	}

	// ------- ui creation

	/**
	 * Creates or returns the created label widget.
	 * 
	 * @param parent
	 *            The parent composite or <code>null</code> if the widget has
	 *            already been created.
	 */
	public Control getLabelControl(FormToolkit _formToolkit, Composite parent) {
		Control control = null;
		if ((_label == null || _label.isDisposed()) && (_hyperlink == null  || _hyperlink.isDisposed())) {
			assertCompositeNotNull(parent);

			String label = null;
			if (_labelText != null && !"".equals(_labelText)) { //$NON-NLS-1$
				//$NON-NLS-1$
				label = _labelText;
			} else {
				label = "."; //$NON-NLS-1$
			}

			if (_listener == null) {
				control = createLabel(_formToolkit, parent, label);
			} else {
				control = createHyperlink(_formToolkit, parent, label);
			}
			/**
			 * if(isRequired) { FontData[] fontData =
			 * parent.getFont().getFontData(); FontData[] newFontData = new
			 * FontData[fontData.length]; for(int i=0; i<fontData.length; i++) {
			 * newFontData[i] = new FontData(fontData[i].getName(),
			 * fontData[i].getHeight(), fontData[i].getStyle() | SWT.BOLD); }
			 * final Font font = new Font(control.getDisplay(),newFontData);
			 * control.setFont(font); control.addDisposeListener(new
			 * DisposeListener() {
			 * 
			 * public void widgetDisposed(DisposeEvent e) { font.dispose(); }
			 * }); } else { control.setFont(parent.getFont()); }
			 */
			control.setFont(parent.getFont());
			control.setEnabled(_enabled);
		} else {
			if (_label != null) {
				control = _label;
			} else {
				control = _hyperlink;
			}
		}
		return control;
	}

	/**
	 * @param _formToolkit
	 * @param parent
	 * @return get the Label control for required
	 */
	public Control getRequiredLabelControl(FormToolkit _formToolkit,
			Composite parent) {
		if (_requiredLabel == null || _requiredLabel.isDisposed()) {
			if (_formToolkit == null) {
				_requiredLabel = new Label(parent, SWT.LEFT | SWT.WRAP);
			} else {
				_requiredLabel = _formToolkit.createLabel(parent, "", SWT.LEFT //$NON-NLS-1$
						| SWT.WRAP);
				_requiredLabel.setForeground(getLabelColor());
			}
			if (_isRequired) {
				_requiredLabel.setText(DialogFieldResources.getInstance()
						.getString("DialogFieldBase.Label.RequiredSymbol")); //$NON-NLS-1$
			}
		}
		return _requiredLabel;
	}

	private Control createLabel(FormToolkit _formToolkit, Composite parent,
			String labelString) {
		if (_formToolkit == null) {
			_label = new Label(parent, SWT.LEFT | SWT.WRAP);
			_label.setText(labelString);
		} else {
			_label = _formToolkit.createLabel(parent, labelString, SWT.LEFT
					| SWT.WRAP);
			_label.setForeground(getLabelColor());
		}
		return _label;
	}

	/**
	 * get color for label
	 */
	private Color getLabelColor() {
		String osname = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$
		if (osname.startsWith("mac os")) { //$NON-NLS-1$
			return Display.getCurrent().getSystemColor(
					SWT.COLOR_LIST_FOREGROUND);
		}
        return Display.getCurrent()
                .getSystemColor(SWT.COLOR_LIST_SELECTION);
	}

	private Control createHyperlink(FormToolkit _formToolkit, Composite parent,
			String label) {
		if (_formToolkit == null) {
			_hyperlink = new Hyperlink(parent, SWT.LEFT | SWT.WRAP);
			_hyperlink.setForeground(getLabelColor());
			_hyperlink.setUnderlined(true);
			_hyperlink.addMouseTrackListener(new MouseTrackAdapter() {

				public void mouseEnter(MouseEvent e) {
					_hyperlink.setForeground(Display.getCurrent()
							.getSystemColor(SWT.COLOR_BLUE));
				}

				public void mouseExit(MouseEvent e) {
					_hyperlink.setForeground(getLabelColor());
				}
			});
			_hyperlink.setText(label);
		} else {
			_hyperlink = _formToolkit.createHyperlink(parent, label, SWT.LEFT
					| SWT.WRAP);
		}
		_hyperlink.addHyperlinkListener(_listener);
		return _hyperlink;
	}

	/**
	 * Creates a spacer control.
	 * @param toolkit 
	 * 
	 * @param parent
	 *            The parent composite
	 * @return a spacer control
	 */
	public Control createEmptySpace(FormToolkit toolkit, Composite parent) {
		return createEmptySpace(toolkit, parent, 1);
	}

	/**
	 * Creates a spacer control with the given span. The composite is assumed to
	 * have <code>MGridLayout</code> as layout.
	 * @param toolkit 
	 * 
	 * @param parent
	 *            The parent composite
	 * @param span 
	 * @return a label that creates empty space
	 */
	public Control createEmptySpace(FormToolkit toolkit, Composite parent,
			int span) {
		Label label;
		if (toolkit != null) {
			label = toolkit.createLabel(parent, ""); //$NON-NLS-1$
		} else {
			label = new Label(parent, SWT.LEFT);
		}
		GridData gd = new GridData();
		gd.horizontalAlignment = GridData.BEGINNING;
		gd.grabExcessHorizontalSpace = false;
		gd.horizontalSpan = span;
		gd.horizontalIndent = 0;
		gd.widthHint = 0;
		gd.heightHint = 0;
		label.setLayoutData(gd);
		return label;
	}

	/**
	 * Tests is the control is not <code>null</code> and not disposed.
	 * @param control 
	 * @return true if the control is valid for use
	 */
	protected final boolean isOkToUse(Control control) {
		return (control != null) && !(control.isDisposed());
	}

	// --------- enable / disable management

	/**
	 * Sets the enable state of the dialog field.
	 */
	public final void setEnabled(boolean enabled) {
		if (enabled != _enabled) {
			_enabled = enabled;
			updateEnableState();
		}
	}

	/**
	 * Called when the enable state changed. To be extended by dialog field
	 * implementors.
	 */
	protected void updateEnableState() {
		if (_label != null && !_label.isDisposed()) {
			_label.setEnabled(_enabled);
		}
		if (_hyperlink != null && !_hyperlink.isDisposed()) {
			_hyperlink.setEnabled(_enabled);
		}
	}

	/**
	 * Gets the enable state of the dialog field.
	 */
	public final boolean isEnabled() {
		return _enabled;
	}

	/**
	 * @param comp
	 */
	protected final void assertCompositeNotNull(Composite comp) {
		Assert.isNotNull(comp,
				"uncreated control requested with composite null"); //$NON-NLS-1$
	}

	/**
	 * @param nColumns
	 */
	protected final void assertEnoughColumns(int nColumns) {
		Assert.isTrue(nColumns >= getNumberOfControls(),
				"given number of columns is too small"); //$NON-NLS-1$
	}

	/**
	 * Get attached data by key.
	 * 
	 * @param key
	 * @return the attached data object for key
	 */
	public Object getAttachedData(Object key) {
		if (_attachedData != null) {
			return _attachedData.get(key);
		}
        return null;
	}

	/**
	 * You can attach any data to the DialogField, and get it using the
	 * <code>getAttachedData</code> method.
	 * 
	 * @param key
	 * @param value
	 */
	public void putAttachedData(Object key, Object value) {
		if (_attachedData == null) {
			_attachedData = new HashMap();
		}
		_attachedData.put(key, value);
	}

	/**
	 * this method give the DialogField a chance to set the correct column to
	 * grab horizontal space. In the implementation of this method, should only
	 * change the GridData of control, should not do anything else.
	 * 
	 * The caller is responsible to make sure the controls for the dialog field
	 * has been created before calling this method.
	 */
	public void handleGrabHorizontal() {
		// do nothing.
	}

	public boolean isRequired() {
		return _isRequired;
	}

	/**
	 * @param isRequired
	 */
	public void setRequired(boolean isRequired) {
		this._isRequired = isRequired;
	}

	/**
	 * @return gthe tool tip text
	 */
	protected String getToolTip() {
		return toolTip;
	}

	public void setToolTip(String toolTip) {
		this.toolTip = toolTip;
	}
}
