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

	private 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
	 * @param section 
	 */
	public AddEditManagedPropertyDialog(Shell parentShell,
			ManagedBeanType managedBean, AbstractFacesConfigSection section) {
		super(parentShell);
		this.isNew = true;
		this.managedBean = managedBean;
		this.section = section;
	}

	/**
	 * 
	 * @param parentShell
	 * @param managedProperty
	 * @param section
	 */
	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(EditorMessages.AddEditManagedPropertyDialog_Add);
		else
			newShell.setText(EditorMessages.AddEditManagedPropertyDialog_Edit);
	}

	/*
	 * @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 = ""; //$NON-NLS-1$
			valueField.getTextControl(null, parent).setEditable(true);
			valueField.setEnabled(true);
		}
	}

	/**
	 * @param valueType_ 
	 * @param value 
	 */
	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);
	}

	/**
	 * @return the project
	 */
	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();
	}

	/**
	 * @return the property class
	 */
	public String getPropertyClass() {
		return propertyClass;
	}

	/**
	 * @param attributeClass
	 */
	public void setAttributeClass(String attributeClass) {
		this.propertyClass = attributeClass;
	}

	/**
	 * @return the property name
	 */
	public String getPropertyName() {
		return propertyName;
	}

	/**
	 * @param attributeName
	 */
	public void setAttributeName(String attributeName) {
		this.propertyName = attributeName;
	}

	/**
	 * @return the value type
	 */
	public String getValueType() {
		return valueType;
	}

	/**
	 * @param defaultValue
	 */
	public void setValueType(String defaultValue) {
		this.valueType = defaultValue;
	}

	/**
	 * @param project
	 */
	public void setProject(IProject project) {
		this.project = project;
	}

	/**
	 * @return the value object
	 */
	public Object getValueObject() {
		return valueObject;
	}

	/**
	 * @param valueObject
	 */
	public void setValueObject(Object valueObject) {
		this.valueObject = valueObject;
	}

}
