/*******************************************************************************
 * Copyright (c) 2006, 2009 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.ui.internal.details;

import java.util.Collection;
import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.internal.ui.refactoring.contentassist.ControlContentAssistHelper;
import org.eclipse.jdt.internal.ui.refactoring.contentassist.JavaTypeCompletionProcessor;
import org.eclipse.jdt.ui.IJavaElementSearchConstants;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.window.Window;
import org.eclipse.jpt.core.context.RelationshipMapping;
import org.eclipse.jpt.ui.JptUiPlugin;
import org.eclipse.jpt.ui.WidgetFactory;
import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
import org.eclipse.jpt.ui.internal.util.SWTUtil;
import org.eclipse.jpt.ui.internal.widgets.FormPane;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.model.value.PropertyValueModel;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.SelectionDialog;
import org.eclipse.ui.forms.widgets.Hyperlink;

/**
 * Here the layout of this pane:
 * <pre>
 * -----------------------------------------------------------------------------
 * |                -------------------------------------------- ------------- |
 * | Target Entity: | I                                      |v| | Browse... | |
 * |                -------------------------------------------- ------------- |
 * -----------------------------------------------------------------------------</pre>
 *
 * @see RelationshipMapping
 * @see ManyToManyMappingComposite - A container of this pane
 * @see ManyToOneMappingComposite - A container of this pane
 * @see OneToManyMappingComposite - A container of this pane
 * @see OneToOneMappingComposite - A container of this pane
 */
@SuppressWarnings("nls")
public class TargetEntityComposite extends FormPane<RelationshipMapping>
{
	private JavaTypeCompletionProcessor javaTypeCompletionProcessor;

	private Combo combo;

	/**
	 * Creates a new <code>TargetEntityComposite</code>.
	 *
	 * @param parentPane The parent container of this one
	 * @param parent The parent container
	 */
	public TargetEntityComposite(FormPane<? extends RelationshipMapping> parentPane,
	                             Composite parent) {

		super(parentPane, parent);
	}

	/**
	 * Creates a new <code>TargetEntityComposite</code>.
	 *
	 * @param subjectHolder The holder of the subject <code>IRelationshipMapping</code>
	 * @param parent The parent container
	 * @param widgetFactory The factory used to create various common widgets
	 */
	public TargetEntityComposite(PropertyValueModel<? extends RelationshipMapping> subjectHolder,
	                             Composite parent,
	                             WidgetFactory widgetFactory) {

		super(subjectHolder, parent, widgetFactory);
	}

	@Override
	protected void addPropertyNames(Collection<String> propertyNames) {
		super.addPropertyNames(propertyNames);
		propertyNames.add(RelationshipMapping.DEFAULT_TARGET_ENTITY_PROPERTY);
		propertyNames.add(RelationshipMapping.SPECIFIED_TARGET_ENTITY_PROPERTY);
	}
	@Override
	protected void initialize() {
		super.initialize();

		// TODO bug 156185 - when this is fixed there should be api for this
		this.javaTypeCompletionProcessor = new JavaTypeCompletionProcessor(false, false);
	}

	@Override
	protected void initializeLayout(Composite container) {
		Composite comboPane = addSubPane(container);
		this.combo = addEditableCombo(comboPane);
		this.combo.add(JptUiDetailsMessages.DefaultEmpty);
		this.combo.addModifyListener(buildTargetEntityModifyListener());

		Image image = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_CONTENT_PROPOSAL).getImage();
		GridData data = new GridData(GridData.FILL_HORIZONTAL);
		data.horizontalIndent = image.getBounds().width;
		this.combo.setLayoutData(data);

		ControlContentAssistHelper.createComboContentAssistant(
			this.combo,
			javaTypeCompletionProcessor
		);

		
		
		SWTUtil.attachDefaultValueHandler(this.combo);

		Hyperlink labelLink = addHyperlink(container,
			JptUiDetailsMessages.TargetEntityChooser_label,
			buildOpenTargetEntityAction()
		);

		addLabeledComposite(
			container,
			labelLink,
			comboPane,
			addTargetEntitySelectionButton(container),
			JpaHelpContextIds.MAPPING_TARGET_ENTITY
		);
	}

	private void openEditor() {

		String targetEntity = getSubject().getTargetEntity();

		if (targetEntity != null) {

			try {
				IType type = getSubject().getJpaProject().getJavaProject().findType(targetEntity.replace('$', '.'));

				if (type != null) {
					IJavaElement javaElement = type.getParent();
					JavaUI.openInEditor(javaElement, true, true);
				}
			}
			catch (JavaModelException e) {
				JptUiPlugin.log(e);
			}
			catch (PartInitException e) {
				JptUiPlugin.log(e);
			}
		}
	}
	private Runnable buildOpenTargetEntityAction() {
		return new Runnable() {
			public void run() {
				TargetEntityComposite.this.openEditor();
			}
		};
	}

	private Runnable buildOpenTypeAction() {
		return new Runnable() {
			public void run() {
				BusyIndicator.showWhile(combo.getDisplay(), new Runnable() {
					public void run() {
						doOpenSelectionDialog();
					}
				});
			}
		};
	}

	private ModifyListener buildTargetEntityModifyListener() {
		return new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				if (!isPopulating()) {
					Combo combo = (Combo) e.widget;
					valueChanged(combo.getText());
				}
			}
		};
	}

	private Button addTargetEntitySelectionButton(Composite parent) {
		return addPushButton(
			parent,
			JptUiDetailsMessages.TargetEntityChooser_browse,
			buildOpenTypeAction()
		);
	}

	private void doOpenSelectionDialog() {
		SelectionDialog dialog;

		try {
			dialog = JavaUI.createTypeDialog(
				getControl().getShell(),
				PlatformUI.getWorkbench().getProgressService(),
				SearchEngine.createWorkspaceScope(),
				IJavaElementSearchConstants.CONSIDER_ALL_TYPES,
				false
			);
		}
		catch (JavaModelException e) {
			JptUiPlugin.log(e);
			return;
		}

		dialog.setTitle(JptUiDetailsMessages.TargetEntityChooser_selectTypeTitle);

		if (dialog.open() == Window.OK) {
			IType type = (IType) dialog.getResult()[0];
			this.combo.setText(type.getFullyQualifiedName(getSubject().getTargetEntityEnclosingTypeSeparator()));
		}
	}

	@Override
	protected void doPopulate() {

		super.doPopulate();
		populateCombo();
		updatePackageFragment();
	}
	
	private void updatePackageFragment() {

		if (getSubject() != null) {
			IPackageFragmentRoot root = getPackageFragmentRoot();

			if (root != null) {
				javaTypeCompletionProcessor.setPackageFragment(root.getPackageFragment(""));
				return;
			}
		}

		javaTypeCompletionProcessor.setPackageFragment(null);
	}
	
	/**
	 * Retrieves the ??
	 *
	 * @return Either the root of the package fragment or <code>null</code> if it
	 * can't be retrieved
	 */
	protected IPackageFragmentRoot getPackageFragmentRoot() {
		IProject project = getSubject().getJpaProject().getProject();
		IJavaProject root = JavaCore.create(project);

		try {
			return root.getAllPackageFragmentRoots()[0];
		}
		catch (JavaModelException e) {
			JptUiPlugin.log(e);
		}
		return null;
	}



	private void populateCombo() {

		combo.removeAll();
		populateDefaultValue();
		// TODO Add possible target entity names
		updateSelectedItem();
	}

	/**
	 * Adds the default value to the combo if one exists.
	 */
	private void populateDefaultValue() {

		RelationshipMapping entity = getSubject();
		String defaultValue = (entity != null) ? entity.getDefaultTargetEntity() : null;

		if (defaultValue != null) {
			combo.add(NLS.bind(
				JptUiDetailsMessages.DefaultWithOneParam,
				defaultValue
			));
		}
		else {
			combo.add(JptUiDetailsMessages.DefaultEmpty);
		}
	}

	/*
	 * (non-Javadoc)
	 */
	@Override
	protected void propertyChanged(String propertyName) {
		super.propertyChanged(propertyName);

		if (propertyName == RelationshipMapping.DEFAULT_TARGET_ENTITY_PROPERTY ||
		    propertyName == RelationshipMapping.SPECIFIED_TARGET_ENTITY_PROPERTY) {

			populateCombo();
		}
	}

	/**
	 * Updates the selected item by selected the current value, if not
	 * <code>null</code>, or select the default value if one is available,
	 * otherwise remove the selection.
	 * <p>
	 * <b>Note:</b> It seems the text can be shown as truncated, changing the
	 * selection to (0, 0) makes the entire text visible.
	 */
	private void updateSelectedItem() {
		RelationshipMapping subject = getSubject();
		String value = (subject != null) ? subject.getSpecifiedTargetEntity() : null;

		if (value != null) {
			combo.setText(value);
			combo.setSelection(new Point(0, 0));
		}
		else {
			String defaultValue = (subject != null) ? subject.getDefaultTargetEntity() : null;
			String displayString = JptUiDetailsMessages.DefaultEmpty;

			if (defaultValue != null) {
				displayString = NLS.bind(
					JptUiDetailsMessages.DefaultWithOneParam,
					defaultValue
				);
			}

			// Selected the default value
			if (displayString != null) {
				combo.select(0);
				combo.setSelection(new Point(0, 0));
			}
			// Remove the selection
			else {
				combo.select(-1);
			}
		}
	}

	private void valueChanged(String value) {

		RelationshipMapping subject = getSubject();
		String oldValue = (subject != null) ? subject.getSpecifiedTargetEntity() : null;

		// Check for null value
		if (StringTools.stringIsEmpty(value)) {
			value = null;

			if (StringTools.stringIsEmpty(oldValue)) {
				return;
			}
		}

		// The default value
		if (value != null &&
		    combo.getItemCount() > 0 &&
		    value.equals(combo.getItem(0)))
		{
			value = null;
		}

		// Nothing to change
		if ((oldValue == value) && value == null) {
			return;
		}

		// Set the new value
		if ((value != null) && (oldValue == null) ||
		   ((oldValue != null) && !oldValue.equals(value))) {

			setPopulating(true);

			try {
				subject.setSpecifiedTargetEntity(value);
			}
			finally {
				setPopulating(false);
			}
		}
	}
}