/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.refactoring.nls;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;

import org.eclipse.jdt.internal.ui.refactoring.contentassist.JavaSourcePackageFragmentRootCompletionProcessor;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField;

class SourceFolderSelectionDialogButtonField extends StringButtonDialogField implements IDialogFieldListener {

	private IPackageFragmentRoot fRoot;
	private SourceChangeListener fListener;
	private IDialogFieldListener fUpdateListener;

	public SourceFolderSelectionDialogButtonField(String descriptionLabel, String browseLabel, IStringButtonAdapter adapter) {
		super(adapter);
		setContentAssistProcessor(new JavaSourcePackageFragmentRootCompletionProcessor());
		setLabelText(descriptionLabel);
		setButtonLabel(browseLabel);
		setDialogFieldListener(this);
	}

	@Override
	public void dialogFieldChanged(DialogField field) {
		// propagate a textchange to the fragment root of this
		setRoot(getRootFromString(getText()));
	}

	public void setUpdateListener(IDialogFieldListener updateListener) {
		fUpdateListener= updateListener;
	}

	public Control[] doFillIntoGrid(Composite parent, int nColumns, int textWidth) {
		Control[] res= super.doFillIntoGrid(parent, nColumns);

		final Text text= getTextControl(null);
		LayoutUtil.setWidthHint(text, textWidth);
		LayoutUtil.setHorizontalGrabbing(text);

		return res;
	}

	public void setSourceChangeListener(SourceChangeListener listener) {
		fListener= listener;
	}

	/**
	 * tries to build a packagefragmentroot out of a string and sets the string into this
	 * packagefragmentroot.
	 *
	 * @param rootString
	 */
	private IPackageFragmentRoot getRootFromString(String rootString) {
		if (rootString.length() == 0) {
			return null;
		}
		IPath path= new Path(rootString);
		IWorkspaceRoot workspaceRoot= ResourcesPlugin.getWorkspace().getRoot();
		IResource res= workspaceRoot.findMember(path);
		if (res == null) {
			return null;
		}
		int resType= res.getType();
		if (resType == IResource.PROJECT || resType == IResource.FOLDER) {
			IProject proj= res.getProject();
			if (!proj.isOpen()) {
				return null;
			}
			IJavaProject jproject= JavaCore.create(proj);
			IPackageFragmentRoot root= jproject.getPackageFragmentRoot(res);
			if (root.exists()) {
				return root;
			}
		}
		return null;
	}

	public void setRoot(IPackageFragmentRoot root) {
		fRoot= root;

		if (fRoot != null) {
			String str= getRootString();
			if (!getText().equals(str)) {
				setText(str);
			}
		} else {
			// dont ripple if the root is not a real root
		}

		fListener.sourceRootChanged(fRoot);
		if (fUpdateListener != null) {
			fUpdateListener.dialogFieldChanged(this);
		}
	}

	public IPackageFragmentRoot getRoot() {
		return fRoot;
	}

	private String getRootString() {
		return (fRoot == null) ? "" : fRoot.getPath().makeRelative().toString(); //$NON-NLS-1$
	}


}
