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

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jdt.core.IType;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.window.Window;
import org.eclipse.jst.jsf.common.ui.internal.dialogfield.ClassButtonDialogField;
import org.eclipse.jst.jsf.common.ui.internal.dialogfield.ComboDialogField;
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.IStringButtonAdapter;
import org.eclipse.jst.jsf.common.ui.internal.dialogfield.LayoutUtil;
import org.eclipse.jst.jsf.common.ui.internal.dialogfield.StringButtonDialogField;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigFactory;
import org.eclipse.jst.jsf.facesconfig.emf.ListEntriesType;
import org.eclipse.jst.jsf.facesconfig.emf.ManagedBeanType;
import org.eclipse.jst.jsf.facesconfig.emf.ManagedPropertyType;
import org.eclipse.jst.jsf.facesconfig.emf.MapEntriesType;
import org.eclipse.jst.jsf.facesconfig.ui.EditorMessages;
import org.eclipse.jst.jsf.facesconfig.ui.EditorPlugin;
import org.eclipse.jst.jsf.facesconfig.ui.IFacesConfigConstants;
import org.eclipse.jst.jsf.facesconfig.ui.section.AbstractFacesConfigSection;
import org.eclipse.jst.jsf.facesconfig.ui.util.JavaBeanProperty;
import org.eclipse.jst.jsf.facesconfig.ui.util.JavaBeanUtils;
import org.eclipse.jst.jsf.facesconfig.ui.util.JavaClassUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;

/**
 * The dialog is for adding and editing managed property.
 * 
 * @author sfshi
 * 
 */
public class AddEditManagedPropertyDialog extends Dialog {

	private static final int MIN_DIALOG_WIDTH = 300;

	private static final int DEFAULT_CONTROL_WIDTH = 200;

	private ComboDialogField nameField;

	private ClassButtonDialogField classField;

	private ComboDialogField valueTypeField;

	private StringButtonDialogField valueField;

	private IProject project;

	private String propertyName;

	private String propertyClass;

	private String valueType;

	/**
	 * the value could be a string, or instance of <code>NullValueType</code>,
	 * <code>MapEntriesType</code> and <code>ListEntriesType</code>.
	 */
	private Object valueObject;

	private ManagedBeanType managedBean;

	/**
	 * the list of this bean properties.
	 */
	private List beanPropertyList;

	/**
	 * the managed-property object that is editing, but it will be read-only.
	 */
	private ManagedPropertyType managedProperty;

	// private FormToolkit toolkit;

	private Composite parent;

	public static final String[] valueTypes = { IFacesConfigConstants.VALUE,
			IFacesConfigConstants.NULL_VALUE,
			IFacesConfigConstants.MAP_ENTRIES,
			IFacesConfigConstants.LIST_ENTRIES };

	private boolean isNew;

	private AbstractFacesConfigSection section;

	/**
	 * constructor for adding a managed property.
	 * 
	 * @param parentShell
	 * @param managedBean
	 */
	public AddEditManagedPropertyDialog(Shell parentShell,
			ManagedBeanType managedBean, AbstractFacesConfigSection section) {
		super(parentShell);
		this.isNew = true;
		this.managedBean = managedBean;
		this.section = section;
	}

	/**
	 * 
	 * @param parentShell
	 * @param managedProperty
	 */
	public AddEditManagedPropertyDialog(Shell parentShell,
			ManagedPropertyType managedProperty, AbstractFacesConfigSection section) {
		super(parentShell);
		this.isNew = false;
		this.managedProperty = managedProperty;
		this.managedBean = (ManagedBeanType) managedProperty.eContainer();
		this.section = section;
	}

	/*
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
	 */
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		if (isNew)
			newShell.setText("Add Managed Property");
		else
			newShell.setText("Edit Managed Property");
	}

	/*
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createDialogArea(Composite parent_) {
		Composite container = new Composite(parent_, SWT.FILL);
		this.parent = container;
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginWidth = layout.marginHeight = 5;
		container.setLayout(layout);
		GridData gd = new GridData(GridData.FILL_BOTH);
		container.setLayoutData(gd);

		nameField = new ComboDialogField(SWT.DROP_DOWN | SWT.READ_ONLY
				| SWT.BORDER);
		nameField.setLabelText(EditorMessages.ManagedBeanPropertyEditDialog_PropertyName);

		int propertyCount = 0;
		beanPropertyList = getBeanPropertyList(managedBean);
		if (beanPropertyList != null)
			propertyCount = beanPropertyList.size();

		if (propertyCount > 0) {
			String[] propertyNames = new String[propertyCount];

			for (int i = 0; i < propertyCount; i++) {
				JavaBeanProperty property = (JavaBeanProperty) beanPropertyList
						.get(i);
				propertyNames[i] = property.getName();
			}
			nameField.setItems(propertyNames);
		}

		nameField.setDialogFieldApplyListener(new IDialogFieldApplyListener() {
			public void dialogFieldApplied(DialogField field) {
				handleNameSelection(((ComboDialogField) field).getText());
			}
		});

		classField = new ClassButtonDialogField(null);
		classField.setProject(getProject());
		classField.setLabelText(EditorMessages.ManagedBeanPropertyEditDialog_PropertyClass);

		valueTypeField = new ComboDialogField(SWT.DROP_DOWN | SWT.READ_ONLY
				| SWT.BORDER);
		valueTypeField.setLabelText(EditorMessages.ManagedBeanPropertyEditDialog_ValueType);

		valueTypeField.setItems(valueTypes);
		valueTypeField
				.setDialogFieldApplyListener(new IDialogFieldApplyListener() {
					public void dialogFieldApplied(DialogField field) {
						updateValueStatus();
					}
				});

		valueField = new StringButtonDialogField(new IStringButtonAdapter() {
			public void changeControlPressed(DialogField field) {
				handleChangeValue(valueTypeField.getText(),
						((StringButtonDialogField) field).getText());
			}

		});

		valueField.setLabelText(EditorMessages.ManagedBeanPropertyEditDialog_Value);//$NON-NLS-1$
		valueField.setButtonLabel(EditorMessages.UI_Button_Edit_more);

		valueField.setDialogFieldApplyListener(new IDialogFieldApplyListener() {

			public void dialogFieldApplied(DialogField field) {
				valueObject = ((StringButtonDialogField) field).getText();

			}
		});

		GridData data = new GridData(GridData.FILL_BOTH);
		container.setLayoutData(data);

		int numberOfColumns = 5;
		GridLayout gl = new GridLayout(numberOfColumns, false);
		container.setLayout(gl);

		nameField.doFillIntoGrid(null, container, numberOfColumns);
		LayoutUtil.setWidthHint(nameField.getComboControl(null, container),
				DEFAULT_CONTROL_WIDTH);

		classField.doFillIntoGrid(null, container, numberOfColumns - 1);
		data = new GridData(SWT.FILL, SWT.CENTER, false, false);
		data.horizontalSpan = 2;
		classField.getChangeControl(null, container).setLayoutData(data);
		LayoutUtil.setWidthHint(classField.getTextControl(null, container),
				DEFAULT_CONTROL_WIDTH);

		valueTypeField.doFillIntoGrid(null, container, numberOfColumns);

		valueField.doFillIntoGrid(null, container, numberOfColumns);

		LayoutUtil.setHorizontalGrabbing(classField.getTextControl(null,
				container));

		valueTypeField.selectItem(0);

		if (!isNew && managedProperty != null) {
			initFields();
		}

		return container;
	}

	private void initFields() {

		if (managedProperty.getPropertyName() != null)
			nameField.setText(managedProperty.getPropertyName()
					.getTextContent());

		if (managedProperty.getPropertyClass() != null)
			classField.setText(managedProperty.getPropertyClass()
					.getTextContent());

		if (managedProperty.getValue() != null) {
			valueTypeField.setText(valueTypes[0]);
			valueField.setText(managedProperty.getValue().getTextContent());
		} else if (managedProperty.getNullValue() != null)
			valueTypeField.setText(valueTypes[1]);
		else if (managedProperty.getMapEntries() != null)
			valueTypeField.setText(valueTypes[2]);
		else if (managedProperty.getListEntries() != null)
			valueTypeField.setText(valueTypes[3]);
		else
			valueTypeField.setText(valueTypes[0]);
		updateValueStatus();
	}

	/**
	 * @param text
	 */
	protected void handleNameSelection(String text) {
		int propertyCount = 0;
		if (beanPropertyList != null)
			propertyCount = beanPropertyList.size();

		if (propertyCount > 0) {
			for (int i = 0; i < propertyCount; i++) {
				JavaBeanProperty property = (JavaBeanProperty) beanPropertyList
						.get(i);

				if (property.getName().equals(text.trim())) {
					classField.setText(property.getQualifiedType());
					break;
				}
			}
		}

	}

	private void updateValueStatus() {
		if (valueField == null) {
			return;
		}
		valueObject = null;
		if (valueTypeField.getText().equalsIgnoreCase(
				IFacesConfigConstants.NULL_VALUE)) {
			valueField.setEnabled(false);
			valueObject = FacesConfigFactory.eINSTANCE.createNullValueType();
		} else if (valueTypeField.getText().equalsIgnoreCase(
				IFacesConfigConstants.MAP_ENTRIES)
				|| valueTypeField.getText().equalsIgnoreCase(
						IFacesConfigConstants.LIST_ENTRIES)) {
			valueField.getTextControl(null, parent).setEditable(false);
			valueField.setEnabled(true);
		} else {
			valueObject = "";
			valueField.getTextControl(null, parent).setEditable(true);
			valueField.setEnabled(true);
		}
	}

	/**
	 * @param textControl
	 */
	protected void handleChangeValue(String valueType_, String value) {
		if (valueType_.equalsIgnoreCase(IFacesConfigConstants.VALUE)) {
			handleChangeLongStringValue(value);
		} else if (valueType_
				.equalsIgnoreCase(IFacesConfigConstants.MAP_ENTRIES)) {
			handleChangeMapEntries();
		} else if (valueType_
				.equalsIgnoreCase(IFacesConfigConstants.LIST_ENTRIES)) {
			handleChangeListEntries();
		}
	}

	/**
	 * @param textControl
	 */
	private void handleChangeLongStringValue(String value) {
		EditValueDialog valueDialog = new EditValueDialog(EditorPlugin
				.getActiveShell(), value);
		if (valueDialog.open() == Window.OK) {
			valueField.setText((String) valueDialog.getResultData());
			valueObject = valueDialog.getResultData();
		}
	}

	/**
	 * 
	 */
	private void handleChangeMapEntries() {

		MapEntriesType mapEntries;

		if (valueObject instanceof MapEntriesType)
			mapEntries = (MapEntriesType) valueObject;
		else if (isNew || managedProperty.getMapEntries() == null) {
			mapEntries = FacesConfigFactory.eINSTANCE.createMapEntriesType();
		} else {
			mapEntries = (MapEntriesType) EcoreUtil.copy(managedProperty
					.getMapEntries());
		}

		EditMapEntriesDialog dialog = new EditMapEntriesDialog(EditorPlugin
				.getActiveShell(), mapEntries, section);
		if (dialog.open() == Dialog.OK) {
			valueObject = dialog.getMapEntries();
		} else {
			//user cancel the dialog, then restore.
			if (!isNew && managedProperty.getMapEntries() != null)
				valueObject = EcoreUtil.copy(managedProperty
						.getMapEntries());
			// else
			//				valueObject = null;
		}
	}

	private void handleChangeListEntries() {
		ListEntriesType listEntries;

		if (valueObject instanceof ListEntriesType)
			listEntries = (ListEntriesType) valueObject;
		else if (isNew || managedProperty.getListEntries() == null) {
			listEntries = FacesConfigFactory.eINSTANCE.createListEntriesType();
		} else {
			listEntries = (ListEntriesType) EcoreUtil.copy(managedProperty
					.getListEntries());
		}

		EditListEntriesDialog dialog = new EditListEntriesDialog(EditorPlugin
				.getActiveShell(), listEntries, section);
		if (dialog.open() == Dialog.OK) {
			valueObject = dialog.getListEntries();
		} else {
			//user cancel the dialog, then restore.
			if (!isNew && managedProperty.getListEntries() != null)
				valueObject = EcoreUtil.copy(managedProperty
						.getListEntries());
			// else
			// valueObject = null;
		}
	}

	/**
	 * Get a list of JavaBeanProperty that from the managed bean class.
	 * 
	 * @return
	 */
	private List getBeanPropertyList(ManagedBeanType managedBean_) {
		if (managedBean_.getManagedBeanClass() == null)
			return null;
		String beanClassName = managedBean_.getManagedBeanClass()
				.getTextContent();
		IType classType = JavaClassUtils.getType(getProject(), beanClassName);
		if (classType == null) {
			return null;
		}
		List list = new ArrayList();
		JavaBeanProperty[] properties = JavaBeanUtils
				.getBeanProperties(classType);
		if (properties != null) {
			for (int i = 0; i < properties.length; i++) {
				list.add(properties[i]);
			}
		}
		return list;
	}

	/*
	 * @see org.eclipse.jface.window.Window#getInitialSize()
	 */
	protected Point getInitialSize() {
		Point shellSize = super.getInitialSize();
		return new Point(Math.max(
				convertHorizontalDLUsToPixels(MIN_DIALOG_WIDTH), shellSize.x),
				shellSize.y);
	}

	public IProject getProject() {
		if (project == null) {
			project = (IProject) section.getPage().getEditor().getAdapter(
					IProject.class);
		}
		return project;
	}

	/**
	 * 
	 */
	protected void okPressed() {
		propertyName = nameField.getText();
		propertyClass = classField.getText();
		valueType = valueTypeField.getText();

		super.okPressed();
	}

	public String getPropertyClass() {
		return propertyClass;
	}

	public void setAttributeClass(String attributeClass) {
		this.propertyClass = attributeClass;
	}

	public String getPropertyName() {
		return propertyName;
	}

	public void setAttributeName(String attributeName) {
		this.propertyName = attributeName;
	}

	public String getValueType() {
		return valueType;
	}

	public void setValueType(String defaultValue) {
		this.valueType = defaultValue;
	}

	public void setProject(IProject project) {
		this.project = project;
	}

	public Object getValueObject() {
		return valueObject;
	}

	public void setValueObject(Object valueObject) {
		this.valueObject = valueObject;
	}

}
