/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.ui.internal.ide.dialogs;

import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IPathVariableManager;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.ide.dialogs.PathVariableSelectionDialog;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;

/**
 * Widget group for specifying a linked file or folder target.
 * 
 * @since 2.1
 */
public class CreateLinkedResourceGroup {
    private Listener listener;

    private String linkTarget = ""; //$NON-NLS-1$

    private int type;

    private boolean createLink = false;

    // used to compute layout sizes
    private FontMetrics fontMetrics;

    // widgets
    private Composite groupComposite;

    private Text linkTargetField;

    private Button browseButton;

    private Button variablesButton;

    private Label resolvedPathLabelText;

    private Label resolvedPathLabelData;

	private final IStringValue updatableResourceName;
    
    /**
     * Helper interface intended for updating a string value based on the
     * currently selected link target.
     * @since 3.2
     */
    public static interface IStringValue {
    	/**
    	 * Sets the String value.
    	 * @param string a non-null String
    	 */
    	void setValue(String string);
    	/**
    	 * Gets the String value.
    	 * @return the current value, or <code>null</code>
    	 */
    	String getValue();
    }
    
    private String lastUpdatedValue;

    /**
     * Creates a link target group 
     *
     * @param type specifies the type of resource to link to. 
     * 	<code>IResource.FILE</code> or <code>IResource.FOLDER</code>
     * @param listener listener to notify when one of the widgets'
     * 	value is changed.
     * @param updatableResourceName an updatable string value that will be
     *  updated to reflect the link target's last segment, or <code>null</code>.
     *  Updating will only happen if the current value of that string is null
     *  or the empty string, or if it has not been changed since the last time
     *  it was updated. 
     */
    public CreateLinkedResourceGroup(int type, Listener listener, IStringValue updatableResourceName) {
        this.type = type;
        this.listener = listener;
		this.updatableResourceName = updatableResourceName;
		if (updatableResourceName != null) {
			lastUpdatedValue = updatableResourceName.getValue();
		}
    }

    /**
     * Creates the widgets 
     * 
     * @param parent parent composite of the widget group
     * @return the widget group
     */
    public Composite createContents(Composite parent) {
        Font font = parent.getFont();
        initializeDialogUnits(parent);
        // top level group
        groupComposite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        groupComposite.setLayout(layout);
        groupComposite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL
                | GridData.FILL_HORIZONTAL));
        groupComposite.setFont(font);

        final Button createLinkButton = new Button(groupComposite, SWT.CHECK);
        if (type == IResource.FILE)
            createLinkButton.setText(IDEWorkbenchMessages.CreateLinkedResourceGroup_linkFileButton);
        else
            createLinkButton.setText(IDEWorkbenchMessages.CreateLinkedResourceGroup_linkFolderButton);
        createLinkButton.setSelection(createLink);
        createLinkButton.setFont(font);
        SelectionListener selectionListener = new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                createLink = createLinkButton.getSelection();
                browseButton.setEnabled(createLink);
                variablesButton.setEnabled(createLink);
                linkTargetField.setEnabled(createLink);
                if (listener != null)
                    listener.handleEvent(new Event());
            }
        };
        createLinkButton.addSelectionListener(selectionListener);

        createLinkLocationGroup(groupComposite, createLink);
        return groupComposite;
    }

    /**
     * Creates the link target location widgets.
     *
     * @param locationGroup the parent composite
     * @param enabled sets the initial enabled state of the widgets
     */
    private void createLinkLocationGroup(Composite locationGroup,
            boolean enabled) {
        Font font = locationGroup.getFont();
        Button button = new Button(locationGroup, SWT.CHECK);
        int indent = button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;

        button.dispose();

        // linkTargetGroup is necessary to decouple layout from 
        // resolvedPathGroup layout
        Composite linkTargetGroup = new Composite(locationGroup, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 3;
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        linkTargetGroup.setLayout(layout);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        data.horizontalIndent = indent;
        linkTargetGroup.setLayoutData(data);
        linkTargetGroup.setFont(font);

        // link target location entry field
        linkTargetField = new Text(linkTargetGroup, SWT.BORDER);
        data = new GridData(GridData.FILL_HORIZONTAL);
        data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
        linkTargetField.setLayoutData(data);
        linkTargetField.setFont(font);
        linkTargetField.setEnabled(enabled);
        linkTargetField.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                linkTarget = linkTargetField.getText();
                resolveVariable();
                if(updatableResourceName!=null) {
                	String value = updatableResourceName.getValue();
					if(value==null || value.equals("") || value.equals(lastUpdatedValue)) { //$NON-NLS-1$
	                	IPath linkTargetPath = new Path(linkTarget);
	                	String lastSegment = linkTargetPath.lastSegment();
	                	if (lastSegment != null) {
	                		lastUpdatedValue = lastSegment;
	                		updatableResourceName.setValue(lastSegment);
	                	}
                	}
                }
                if (listener != null)
                    listener.handleEvent(new Event());
            }
        });
        // browse button
        browseButton = new Button(linkTargetGroup, SWT.PUSH);      
        browseButton.setFont(font);
        browseButton.setText(IDEWorkbenchMessages.CreateLinkedResourceGroup_browseButton);
        browseButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                handleLinkTargetBrowseButtonPressed();
            }
        });
        browseButton.setEnabled(enabled);
        setButtonLayoutData(browseButton);

        // variables button
        variablesButton = new Button(linkTargetGroup, SWT.PUSH);
        variablesButton.setFont(font);
        variablesButton.setText(IDEWorkbenchMessages.CreateLinkedResourceGroup_variablesButton);
        variablesButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                handleVariablesButtonPressed();
            }
        });
        variablesButton.setEnabled(enabled);
        setButtonLayoutData(variablesButton);
        
        Composite resolvedPathGroup = new Composite(locationGroup, SWT.NONE);
        layout = new GridLayout();
        layout.numColumns = 2;
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        resolvedPathGroup.setLayout(layout);
        data = new GridData(GridData.FILL_HORIZONTAL);
        data.horizontalIndent = indent;
        resolvedPathGroup.setLayoutData(data);
        resolvedPathGroup.setFont(font);

        resolvedPathLabelText = new Label(resolvedPathGroup, SWT.SINGLE);
        resolvedPathLabelText.setText(IDEWorkbenchMessages.CreateLinkedResourceGroup_resolvedPathLabel);
        resolvedPathLabelText.setVisible(false);
        resolvedPathLabelText.setFont(font);

        resolvedPathLabelData = new Label(resolvedPathGroup, SWT.SINGLE);
        data = new GridData(GridData.FILL_HORIZONTAL);
        resolvedPathLabelData.setLayoutData(data);
        resolvedPathLabelData.setVisible(false);
        resolvedPathLabelData.setFont(font);

        if (linkTarget != null)
            linkTargetField.setText(linkTarget);
    }

    /**
     * Returns a new status object with the given severity and message.
     * 
     * @return a new status object with the given severity and message.
     */
    private IStatus createStatus(int severity, String message) {
        return new Status(severity, IDEWorkbenchPlugin.getDefault()
                .getBundle().getSymbolicName(), severity, message, null);
    }

    /**
     * Disposes the group's widgets. 
     */
    public void dispose() {
        if (groupComposite != null && groupComposite.isDisposed() == false)
            groupComposite.dispose();
    }

    /**
     * Returns the link target location entered by the user. 
     *
     * @return the link target location entered by the user. null if the user
     * 	chose not to create a link.
     */
    public String getLinkTarget() {
        if (createLink)
            return linkTarget;

        return null;
    }

    /**
     * Opens a file or directory browser depending on the link type.
     */
    private void handleLinkTargetBrowseButtonPressed() {
        IFileStore store = null;
        String selection = null;

        if (linkTarget.length() > 0) { 
            store = IDEResourceInfoUtils.getFileStore(linkTarget);
            if (!store.fetchInfo().exists())
                store = null;
        }
        if (type == IResource.FILE) {
            FileDialog dialog = new FileDialog(linkTargetField.getShell());
            if (store != null) {
                if (store.fetchInfo().isDirectory())
                	dialog.setFilterPath(linkTarget);
                else
                    dialog.setFileName(linkTarget);
            }
            selection = dialog.open();
        } else {
            DirectoryDialog dialog = new DirectoryDialog(linkTargetField
                    .getShell());
            if (store != null) {
                IFileStore path = store;
                if (!store.fetchInfo().isDirectory())
                    path = store.getParent();
                if (path != null)
                    dialog.setFilterPath(store.toString());
            }
            dialog
                    .setMessage(IDEWorkbenchMessages.CreateLinkedResourceGroup_targetSelectionLabel);
            selection = dialog.open();
        }
        if (selection != null)
            linkTargetField.setText(selection);
    }

    /**
     * Opens a path variable selection dialog
     */
    private void handleVariablesButtonPressed() {
        int variableTypes = IResource.FOLDER;

        // allow selecting file and folder variables when creating a 
        // linked file
        if (type == IResource.FILE)
            variableTypes |= IResource.FILE;

        PathVariableSelectionDialog dialog = new PathVariableSelectionDialog(
                linkTargetField.getShell(), variableTypes);
        if (dialog.open() == IDialogConstants.OK_ID) {
            String[] variableNames = (String[]) dialog.getResult();
            if (variableNames != null && variableNames.length == 1)
                linkTargetField.setText(variableNames[0]);
        }
    }

    /**
     * Initializes the computation of horizontal and vertical dialog units
     * based on the size of current font.
     * <p>
     * This method must be called before <code>setButtonLayoutData</code> 
     * is called.
     * </p>
     *
     * @param control a control from which to obtain the current font
     */
    protected void initializeDialogUnits(Control control) {
        // Compute and store a font metric
        GC gc = new GC(control);
        gc.setFont(control.getFont());
        fontMetrics = gc.getFontMetrics();
        gc.dispose();
    }

    /**
     * Tries to resolve the value entered in the link target field as 
     * a variable, if the value is a relative path.
     * Displays the resolved value if the entered value is a variable.
     */
    private void resolveVariable() {
        IPathVariableManager pathVariableManager = ResourcesPlugin
                .getWorkspace().getPathVariableManager();
        IPath path = new Path(linkTarget);
        IPath resolvedPath = pathVariableManager.resolvePath(path);

        if (path.equals(resolvedPath)) {
            resolvedPathLabelText.setVisible(false);
            resolvedPathLabelData.setVisible(false);
        } else {
            resolvedPathLabelText.setVisible(true);
            resolvedPathLabelData.setVisible(true);
        }
        resolvedPathLabelData.setText(resolvedPath.toOSString());
    }

    /**
     * Sets the <code>GridData</code> on the specified button to
     * be one that is spaced for the current dialog page units. The
     * method <code>initializeDialogUnits</code> must be called once
     * before calling this method for the first time.
     *
     * @param button the button to set the <code>GridData</code>
     * @return the <code>GridData</code> set on the specified button
     */
    private GridData setButtonLayoutData(Button button) {
        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
        int widthHint = Dialog.convertHorizontalDLUsToPixels(fontMetrics,
                IDialogConstants.BUTTON_WIDTH);
        data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT,
                SWT.DEFAULT, true).x);
        button.setLayoutData(data);
        return data;
    }

    /**
     * Sets the value of the link target field
     * 
     * @param target the value of the link target field
     */
    public void setLinkTarget(String target) {
        linkTarget = target;
        if (linkTargetField != null && linkTargetField.isDisposed() == false)
            linkTargetField.setText(target);
    }

    /**
     * Validates the type of the given file against the link type specified
     * in the constructor.
     * 
     * @param linkTargetFile file to validate
     * @return IStatus indicating the validation result. IStatus.OK if the 
     * 	given file is valid.
     */
    private IStatus validateFileType(IFileInfo linkTargetFile) {
        if (type == IResource.FILE && linkTargetFile.isDirectory()) {
            return createStatus(IStatus.ERROR, IDEWorkbenchMessages.CreateLinkedResourceGroup_linkTargetNotFile);
        } else if (type == IResource.FOLDER
                && !linkTargetFile.isDirectory()) {
            return createStatus(IStatus.ERROR, IDEWorkbenchMessages.CreateLinkedResourceGroup_linkTargetNotFolder);
        }
        return Status.OK_STATUS;
    }

    /**
     * Validates this page's controls.
     * @param linkHandle The target to check
     *
     * @return IStatus indicating the validation result. IStatus.OK if the 
     * 	specified link target is valid given the linkHandle.
     */
    public IStatus validateLinkLocation(IResource linkHandle) {
        if (linkTargetField == null || linkTargetField.isDisposed())
            return createStatus(IStatus.OK, ""); //$NON-NLS-1$

        IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace();
        IPath path = new Path(linkTarget);

        if (createLink == false)
            return createStatus(IStatus.OK, ""); //$NON-NLS-1$
        
        if (path.isUNC()) {
            // print that path is not valid, but don't do core validation. See bug 90825.
        	return createStatus(IStatus.WARNING, IDEWorkbenchMessages.CreateLinkedResourceGroup_unableToValidateLinkTarget);
        }

        IStatus locationStatus = workspace.validateLinkLocation(linkHandle,
                path);
        if (locationStatus.getSeverity() == IStatus.ERROR)
            return locationStatus;

        // use the resolved link target name
        String resolvedLinkTarget = resolvedPathLabelData.getText();
        path = new Path(resolvedLinkTarget);
        IFileInfo linkTargetFile = IDEResourceInfoUtils.getFileInfo(resolvedLinkTarget);
        if (linkTargetFile != null && linkTargetFile.exists()) {
            IStatus fileTypeStatus = validateFileType(linkTargetFile);
            if (fileTypeStatus.isOK() == false)
                return fileTypeStatus;
        } else if (locationStatus.getSeverity() == IStatus.OK) {
            // locationStatus takes precedence over missing location warning.
            return createStatus(
                    IStatus.WARNING,
                    IDEWorkbenchMessages.CreateLinkedResourceGroup_linkTargetNonExistent);
        }
        return locationStatus;
    }
}
