/*******************************************************************************
 * 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.facesconfig.common.dialogfield.ClassButtonDialogField;
import org.eclipse.jst.jsf.facesconfig.common.dialogfield.ComboDialogField;
import org.eclipse.jst.jsf.facesconfig.common.dialogfield.DialogField;
import org.eclipse.jst.jsf.facesconfig.common.dialogfield.IDialogFieldApplyListener;
import org.eclipse.jst.jsf.facesconfig.common.dialogfield.IStringButtonAdapter;
import org.eclipse.jst.jsf.facesconfig.common.dialogfield.LayoutUtil;
import org.eclipse.jst.jsf.facesconfig.common.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.EditorPlugin;
import org.eclipse.jst.jsf.facesconfig.ui.IFacesConfigConstants;
import org.eclipse.jst.jsf.facesconfig.ui.EditorMessages;
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 = (MapEntriesType) 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 = (ListEntriesType) 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;
	}

}
