/*******************************************************************************
 * 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.pagedesigner.ui.dialogfields;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jst.jsf.common.ui.internal.dialogfield.DialogField;
import org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogFieldApplyListener;
import org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogFieldChangeListener;
import org.eclipse.jst.jsf.common.ui.internal.dialogfield.IStringButtonAdapter;
import org.eclipse.jst.jsf.common.ui.internal.dialogfield.ISupportTextValue;
import org.eclipse.jst.pagedesigner.editors.properties.IPropertyPageDescriptor;
import org.eclipse.jst.pagedesigner.meta.IAttributeDescriptor;
import org.eclipse.jst.pagedesigner.meta.IBindingHandler;
import org.eclipse.jst.pagedesigner.properties.attrgroup.IElementContextable;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

/**
 * This is a wrapper to a dialog field, by adding a small image button at the
 * end. The caller is responsible to provide the image and the button click
 * handler.
 * 
 * @author mengbo
 * @version 1.5
 * @see org.eclipse.jst.pagedesigner.properties.celleditors.CellEditorWrapper
 */
// NOTE: currently this class is dedicated to page designer by using the
// IElementContextable interface.
// It should be very easy to make it standard alone and reused in other places.
@SuppressWarnings("deprecation")
public class DialogFieldWrapper implements DialogField, ISupportTextValue,
		IElementContextable {
	private DialogField _wrapped;

	private IDOMNode _ancester;

	private IDOMElement _element;

	private Button _databindingButton;

	private boolean _databindingEnabled;

	private Image _image;

	private Image _disabledImage;

	private IStringButtonAdapter _adapter;

	private String _uri;

	private String _tagName;

    private IAttributeDescriptor _attr;

    private IBindingHandler _handler;

	private IPropertyPageDescriptor _pdattr;

	/**
	 * @param field 
	 * @param image 
	 * @param disabledImage 
	 * @param uri 
	 * @param tagName 
	 * @param attr 
	 * @param handler 
	 * 
	 */
    public DialogFieldWrapper(DialogField field, Image image,
			Image disabledImage, String uri, String tagName,
			IAttributeDescriptor attr, IBindingHandler handler) {
		super();
		if (!(field instanceof ISupportTextValue)) {
			throw new IllegalArgumentException(
					"Field must be ISupportTextValue"); //$NON-NLS-1$
		}
		_wrapped = field;
		this._image = image;
		this._disabledImage = disabledImage;
		this._uri = uri;
		this._tagName = tagName;
		this._attr = attr;
		this._handler = handler;

		setDatabindingPressedHandler(new IStringButtonAdapter() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.IStringButtonAdapter#changeControlPressed(org.eclipse.jst.jsf.common.ui.internal.dialogfield.DialogField)
			 */
            public void changeControlPressed(DialogField field1) {
				Shell shell = field1.getLabelControl(null, null).getShell();
				DialogFieldWrapper wrapper = (DialogFieldWrapper) field1;
				String result = _handler
						.handleBinding(shell, wrapper.getAncester(), wrapper
								.getElement(), wrapper.getText());
				if (result != null) {
					wrapper.setText(result);
				}
			}
		});
	}
	
	/**
	 * @param field 
	 * @param image 
	 * @param disabledImage 
	 * @param uri 
	 * @param tagName 
	 * @param attr 
	 * @param handler 
	 * 
	 */
    public DialogFieldWrapper(DialogField field, Image image,
			Image disabledImage, String uri, String tagName,
			IPropertyPageDescriptor attr, IBindingHandler handler) {
		super();
		if (!(field instanceof ISupportTextValue)) {
			throw new IllegalArgumentException(
					"Field must be ISupportTextValue"); //$NON-NLS-1$
		}
		_wrapped = field;
		this._image = image;
		this._disabledImage = disabledImage;
		this._uri = uri;
		this._tagName = tagName;
		this._pdattr = attr;
		this._handler = handler;

		setDatabindingPressedHandler(new IStringButtonAdapter() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.IStringButtonAdapter#changeControlPressed(org.eclipse.jst.jsf.common.ui.internal.dialogfield.DialogField)
			 */
			public void changeControlPressed(DialogField field1) {
				Shell shell = field1.getLabelControl(null, null).getShell();
				DialogFieldWrapper wrapper = (DialogFieldWrapper) field1;
				String result = _handler
						.handleBinding(shell, wrapper.getAncester(), wrapper
								.getElement(), wrapper.getText());
				if (result != null) {
					wrapper.setText(result);
				}
			}
		});
	}

	private void setDatabindingPressedHandler(IStringButtonAdapter adapter) {
		this._adapter = adapter;
		this.updateDatabindingControl();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.ISupportTextValue#setTextWithoutUpdate(java.lang.String)
	 */
	public void setTextWithoutUpdate(String value) {
		((ISupportTextValue) _wrapped).setTextWithoutUpdate(value);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.ISupportTextValue#getText()
	 */
	public String getText() {
		return ((ISupportTextValue) _wrapped).getText();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.ISupportTextValue#setText(java.lang.String)
	 */
	public void setText(String value) {
		((ISupportTextValue) _wrapped).setText(value);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.properties.attrgroup.IElementContextable#setElementContext(org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode,
	 *      org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement)
	 */
    public void setElementContext(IDOMNode ancester, IDOMElement element) {
		if (_wrapped instanceof IElementContextable) {
			((IElementContextable) _wrapped).setElementContext(ancester,
					element);
		}
		this._ancester = ancester;
		this._element = element;

		boolean bindingEnabled = false;
		
		if (_attr != null)
			bindingEnabled = _handler.isEnabled(_ancester, _element, _uri,
				_tagName, _attr);
		else if (_pdattr != null)
			bindingEnabled = false;//_handler.isEnabled(_ancester, _element, _pdattr);
		
		this.setDatabindingEnabled(bindingEnabled);
	}

	// --------------------------------------------------------------------------------------------
	// wrapped method to add the data binding browse button
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.DialogField#doFillIntoGrid(org.eclipse.ui.forms.widgets.FormToolkit,
	 *      org.eclipse.swt.widgets.Composite, int)
	 */
	public Control[] doFillIntoGrid(FormToolkit toolkit, Composite parent,
			int nColumns) {
		Control[] wrappedControls = _wrapped.doFillIntoGrid(toolkit, parent,
				nColumns - 1);
		Control[] result = new Control[wrappedControls.length];

		Control button = getDatabingingButton(toolkit, parent);
		button.setLayoutData(gridDataForDatabindingButton(1));
		button.setVisible(false);

		System.arraycopy(wrappedControls, 0, result, 0, wrappedControls.length);
		result[result.length - 1] = _databindingButton;
		return result;
	}

	/**
	 * @param span
	 * @return
	 */
	private GridData gridDataForDatabindingButton(int span) {
		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gd.horizontalSpan = span;
		gd.widthHint = gd.heightHint = 18;
		return gd;
	}

	/**
	 * @param toolkit
	 * @param parent
	 * @return
	 */
	private Control getDatabingingButton(FormToolkit toolkit, Composite parent) {
		if (_databindingButton == null || _databindingButton.isDisposed()) {
			Assert.isNotNull(parent,
					"uncreated control requested with composite null"); //$NON-NLS-1$
			if (toolkit != null) {
				_databindingButton = toolkit.createButton(parent, "", SWT.PUSH); //$NON-NLS-1$
				_databindingButton.setImage(getImage());
			} else {
				_databindingButton = new Button(parent, SWT.PUSH);
				_databindingButton.setImage(getImage());
			}
			_databindingButton.addPaintListener(new PaintListener() {
				public void paintControl(PaintEvent e) {
					if (!_databindingButton.isEnabled()
							&& getDisabledImage() != null) {
						Rectangle buttonBounds = _databindingButton.getBounds();
						Rectangle imageBounds = getDisabledImage().getBounds();
						e.gc.drawImage(getDisabledImage(),
								(buttonBounds.width - imageBounds.width) / 2,
								(buttonBounds.height - imageBounds.height) / 2);
					}
				}
			});
			_databindingButton.setEnabled(isEnabled() && _databindingEnabled);
			_databindingButton.addSelectionListener(new SelectionListener() {
				public void widgetDefaultSelected(SelectionEvent e) {
					databindingControlPressed();
				}

				public void widgetSelected(SelectionEvent e) {
					databindingControlPressed();
				}
			});

		}
		return _databindingButton;
	}

	/**
	 * @return
	 */
	private Image getImage() {
		return _image;
	}

	private Image getDisabledImage() {
		return _disabledImage;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.DialogField#getLabelControl(org.eclipse.ui.forms.widgets.FormToolkit,
	 *      org.eclipse.swt.widgets.Composite)
	 */
	public Control getLabelControl(FormToolkit _formToolkit, Composite parent) {
		return _wrapped.getLabelControl(_formToolkit, parent);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogField#setHyperLink(org.eclipse.ui.forms.events.IHyperlinkListener)
	 */
	public void setHyperLink(IHyperlinkListener listener) {
		_wrapped.setHyperLink(listener);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogField#setLabelText(java.lang.String)
	 */
	public void setLabelText(String labeltext) {
		_wrapped.setLabelText(labeltext);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogField#setDialogFieldChangeListener(org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogFieldChangeListener)
	 */
	public void setDialogFieldChangeListener(IDialogFieldChangeListener listener) {
		_wrapped.setDialogFieldChangeListener(listener);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogField#setDialogFieldApplyListener(org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogFieldApplyListener)
	 */
	public void setDialogFieldApplyListener(IDialogFieldApplyListener listener) {
		_wrapped.setDialogFieldApplyListener(listener);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogField#setFocus()
	 */
	public boolean setFocus() {
		return _wrapped.setFocus();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogField#getNumberOfControls()
	 */
	public int getNumberOfControls() {
		return _wrapped.getNumberOfControls() + 1;
	}

	/**
	 * @param enabled
	 */
	public void setDatabindingEnabled(boolean enabled) {
		this._databindingEnabled = enabled;
		updateDatabindingControl();
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogField#setEnabled(boolean)
	 */
	public void setEnabled(boolean enabled) {
		_wrapped.setEnabled(enabled);
		updateDatabindingControl();
	}

	/**
	 * 
	 */
	private void updateDatabindingControl() {
		if (this._databindingButton != null && !_databindingButton.isDisposed()) {
			this._databindingButton.setEnabled(this.isEnabled()
					&& _databindingEnabled && _adapter != null);
			_databindingButton.redraw();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogField#isEnabled()
	 */
	public boolean isEnabled() {
		return _wrapped.isEnabled();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogField#getAttachedData(java.lang.Object)
	 */
	public Object getAttachedData(Object key) {
		return _wrapped.getAttachedData(key);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.IDialogField#putAttachedData(java.lang.Object,
	 *      java.lang.Object)
	 */
	public void putAttachedData(Object key, Object value) {
		_wrapped.putAttachedData(key, value);
	}

	private void databindingControlPressed() {
		if (_adapter != null) {
			_adapter.changeControlPressed(this);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.DialogField#handleGrabHorizontal()
	 */
	public void handleGrabHorizontal() {
		_wrapped.handleGrabHorizontal();
	}

	private IDOMNode getAncester() {
		return _ancester;
	}

	private IDOMElement getElement() {
		return _element;
	}

	/**
	 * @return the wrapped field
	 */
	public DialogField getWrappedDialogField() {
		return _wrapped;
	}

	public boolean isRequired() {
		return _wrapped.isRequired();
	}

	public void setToolTip(String toolTip) {
		_wrapped.setToolTip(toolTip);
	}

	public Shell getShell() {
		return _wrapped.getShell();
	}
}
