/******************************************************************************* 
 * Copyright (c) 2000, 2003 IBM Corporation and others. 
 * All rights reserved. This program and the accompanying materials! 
 * are made available under the terms of the Common Public License v1.0 
 * which accompanies this distribution, and is available at 
 * http://www.eclipse.org/legal/cpl-v10.html 
 * 
 * Contributors: 
 *   IBM Corporation - initial API and implementation 
 *   Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog
 * 	 	font should be activated and used by other components.
 ************************************************************************/

package org.eclipse.ui.dialogs;

import java.io.File;

import org.eclipse.core.resources.IContainer;
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.jface.dialogs.IDialogConstants;
import org.eclipse.jface.wizard.WizardPage;
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.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.DirectoryDialog;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
import org.eclipse.ui.internal.ide.dialogs.PathVariableSelectionDialog;

/**
 * Standard resource link page for a wizard that creates a file or 
 * folder resource.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p>
 * @since 2.1
 */
public class WizardNewLinkPage extends WizardPage {
    private String initialLinkTarget;

    private int type;

    private boolean createLink = false;

    private IContainer container;

    // widgets
    private Text linkTargetField;

    private Button browseButton;

    private Button variablesButton;

    /**
     * Creates a new resource link wizard page. 
     *
     * @param pageName the name of the page
     * @param type specifies the type of resource to link to. 
     * 	<code>IResource.FILE</code> or <code>IResource.FOLDER</code>
     */
    public WizardNewLinkPage(String pageName, int type) {
        super(pageName);
        this.type = type;
        setPageComplete(true);
    }

    /* (non-Javadoc)
     * Method declared on IDialogPage.
     */
    public void createControl(Composite parent) {
        Font font = parent.getFont();
        initializeDialogUnits(parent);
        // top level group
        Composite topLevel = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 3;
        topLevel.setLayout(layout);
        topLevel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL
                | GridData.HORIZONTAL_ALIGN_FILL));
        topLevel.setFont(font);
        WorkbenchHelp.setHelp(topLevel, IIDEHelpContextIds.NEW_LINK_WIZARD_PAGE);

        final Button createLinkButton = new Button(topLevel, SWT.CHECK);
        if (type == IResource.FILE)
            createLinkButton.setText(IDEWorkbenchMessages
                    .getString("WizardNewLinkPage.linkFileButton")); //$NON-NLS-1$
        else
            createLinkButton.setText(IDEWorkbenchMessages
                    .getString("WizardNewLinkPage.linkFolderButton")); //$NON-NLS-1$
        createLinkButton.setSelection(createLink);
        GridData data = new GridData();
        data.horizontalSpan = 3;
        createLinkButton.setLayoutData(data);
        createLinkButton.setFont(font);
        SelectionListener listener = new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                createLink = createLinkButton.getSelection();
                browseButton.setEnabled(createLink);
                variablesButton.setEnabled(createLink);
                linkTargetField.setEnabled(createLink);
                setPageComplete(validatePage());
            }
        };
        createLinkButton.addSelectionListener(listener);

        createLinkLocationGroup(topLevel, createLink);
        validatePage();

        setErrorMessage(null);
        setMessage(null);
        setControl(topLevel);
    }

    /**
     * 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();
        Label fill = new Label(locationGroup, SWT.NONE);
        GridData data = new GridData();
        Button button = new Button(locationGroup, SWT.CHECK);
        data.widthHint = button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
        button.dispose();
        fill.setLayoutData(data);

        // link target location entry field
        linkTargetField = new Text(locationGroup, SWT.BORDER);
        data = new GridData(GridData.FILL_HORIZONTAL);
        linkTargetField.setLayoutData(data);
        linkTargetField.setFont(font);
        linkTargetField.setEnabled(enabled);
        linkTargetField.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                setPageComplete(validatePage());
            }
        });
        if (initialLinkTarget != null) {
            linkTargetField.setText(initialLinkTarget);
        }

        // browse button
        browseButton = new Button(locationGroup, SWT.PUSH);
        setButtonLayoutData(browseButton);
        browseButton.setFont(font);
        browseButton.setText(IDEWorkbenchMessages
                .getString("WizardNewLinkPage.browseButton")); //$NON-NLS-1$
        browseButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                handleLinkTargetBrowseButtonPressed();
            }
        });
        browseButton.setEnabled(enabled);

        fill = new Label(locationGroup, SWT.NONE);
        data = new GridData();
        data.horizontalSpan = 2;
        fill.setLayoutData(data);

        // variables button
        variablesButton = new Button(locationGroup, SWT.PUSH);
        setButtonLayoutData(variablesButton);
        variablesButton.setFont(font);
        variablesButton.setText(IDEWorkbenchMessages
                .getString("WizardNewLinkPage.variablesButton")); //$NON-NLS-1$
        variablesButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                handleVariablesButtonPressed();
            }
        });
        variablesButton.setEnabled(enabled);
    }

    /**
     * Returns the link target location entered by the user. 
     *
     * @return the link target location entered by the user. null if the user
     * 	choose not to create a link.
     */
    public String getLinkTarget() {
        if (createLink && linkTargetField != null
                && linkTargetField.isDisposed() == false) {
            return linkTargetField.getText();
        }
        return null;
    }

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

        if ("".equals(linkTargetName) == false) { //$NON-NLS-1$
            file = new File(linkTargetName);
            if (file.exists() == false) {
                file = null;
            }
        }
        if (type == IResource.FILE) {
            FileDialog dialog = new FileDialog(getShell());
            if (file != null) {
                if (file.isFile()) {
                    dialog.setFileName(linkTargetName);
                } else {
                    dialog.setFilterPath(linkTargetName);
                }
            }
            selection = dialog.open();
        } else {
            DirectoryDialog dialog = new DirectoryDialog(getShell());
            if (file != null) {
                if (file.isFile()) {
                    linkTargetName = file.getParent();
                }
                if (linkTargetName != null) {
                    dialog.setFilterPath(linkTargetName);
                }
            }
            dialog.setMessage(IDEWorkbenchMessages
                    .getString("WizardNewLinkPage.targetSelectionLabel")); //$NON-NLS-1$
            selection = dialog.open();
        }
        if (selection != null) {
            linkTargetField.setText(selection);
        }
    }

    /**
     * Opens a path variable selection dialog
     */
    private void handleVariablesButtonPressed() {
        PathVariableSelectionDialog dialog = new PathVariableSelectionDialog(
                getShell(), type);

        if (dialog.open() == IDialogConstants.OK_ID) {
            String[] variableNames = (String[]) dialog.getResult();

            if (variableNames != null) {
                IPathVariableManager pathVariableManager = ResourcesPlugin
                        .getWorkspace().getPathVariableManager();
                IPath path = pathVariableManager.getValue(variableNames[0]);

                if (path != null) {
                    linkTargetField.setText(path.toOSString());
                }
            }
        }
    }

    /**
     * Sets the container to use for link validation.
     * This should be the parent of the new resource that is being 
     * linked.
     *
     * @param container the container to use for link validation.
     */
    public void setContainer(IContainer container) {
        this.container = container;
    }

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

    /**
     * Validates the type of the given file against the link type specified
     * during page creation.
     * 
     * @param linkTargetFile file to validate
     * @return boolean <code>true</code> if the link target type is valid
     * 	and <code>false</code> otherwise.
     */
    private boolean validateFileType(File linkTargetFile) {
        boolean valid = true;

        if (type == IResource.FILE && linkTargetFile.isFile() == false) {
            setErrorMessage(IDEWorkbenchMessages
                    .getString("WizardNewLinkPage.linkTargetNotFile")); //$NON-NLS-1$
            valid = false;
        } else if (type == IResource.FOLDER
                && linkTargetFile.isDirectory() == false) {
            setErrorMessage(IDEWorkbenchMessages
                    .getString("WizardNewLinkPage.linkTargetNotFolder")); //$NON-NLS-1$
            valid = false;
        }
        return valid;
    }

    /**
     * Validates the name of the link target
     *
     * @param linkTargetName link target name to validate
     * @return boolean <code>true</code> if the link target name is valid
     * 	and <code>false</code> otherwise.
     */
    private boolean validateLinkTargetName(String linkTargetName) {
        boolean valid = true;

        if ("".equals(linkTargetName)) {//$NON-NLS-1$
            setErrorMessage(IDEWorkbenchMessages
                    .getString("WizardNewLinkPage.linkTargetEmpty")); //$NON-NLS-1$
            valid = false;
        } else {
            IPath path = new Path("");//$NON-NLS-1$
            if (path.isValidPath(linkTargetName) == false) {
                setErrorMessage(IDEWorkbenchMessages
                        .getString("WizardNewLinkPage.linkTargetInvalid")); //$NON-NLS-1$
                valid = false;
            }
        }
        return valid;
    }

    /**
     * Returns whether this page's controls currently all contain valid 
     * values.
     *
     * @return <code>true</code> if all controls are valid, and
     *   <code>false</code> if at least one is invalid
     */
    private boolean validatePage() {
        boolean valid = true;
        IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace();

        if (createLink) {
            String linkTargetName = linkTargetField.getText();

            valid = validateLinkTargetName(linkTargetName);
            if (valid) {
                File linkTargetFile = new Path(linkTargetName).toFile();
                if (linkTargetFile.exists() == false) {
                    setErrorMessage(IDEWorkbenchMessages
                            .getString("WizardNewLinkPage.linkTargetNonExistent")); //$NON-NLS-1$
                    valid = false;
                } else {
                    IStatus locationStatus = workspace.validateLinkLocation(
                            container, new Path(linkTargetName));

                    if (locationStatus.isOK() == false) {
                        setErrorMessage(IDEWorkbenchMessages
                                .getString("WizardNewLinkPage.linkTargetLocationInvalid")); //$NON-NLS-1$
                        valid = false;
                    } else {
                        valid = validateFileType(linkTargetFile);
                    }
                }
            }
        }
        // Avoid draw flicker by clearing error message
        // if all is valid.
        if (valid) {
            setMessage(null);
            setErrorMessage(null);
        }
        return valid;
    }
}