/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.ide.eclipse.adt.internal.wizards.newproject;

import static com.android.SdkConstants.FN_PROJECT_PROGUARD_FILE;
import static com.android.SdkConstants.OS_SDK_TOOLS_LIB_FOLDER;
import static com.android.ide.eclipse.adt.AdtUtils.capitalize;
import static com.android.ide.eclipse.adt.internal.wizards.newproject.ApplicationInfoPage.ACTIVITY_NAME_SUFFIX;
import static com.android.utils.SdkUtils.stripWhitespace;

import com.android.SdkConstants;
import com.android.ide.common.xml.ManifestData;
import com.android.ide.common.xml.ManifestData.Activity;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.VersionCheck;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizardState.Mode;

import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.TextProcessor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkingSet;

import java.io.File;
import java.net.URI;
import java.util.Locale;

/**
 * Initial page shown when creating projects which asks for the project name,
 * the the location of the project, working sets, etc.
 */
public class ProjectNamePage extends WizardPage implements SelectionListener, ModifyListener {
    private final NewProjectWizardState mValues;
    /** Flag used when setting button/text state manually to ignore listener updates */
    private boolean mIgnore;
    /** Last user-browsed location, static so that it be remembered for the whole session */
    private static String sCustomLocationOsPath = "";  //$NON-NLS-1$
    private static boolean sAutoComputeCustomLocation = true;

    private Text mProjectNameText;
    private Text mLocationText;
    private Button mCreateSampleRadioButton;
    private Button mCreateNewButton;
    private Button mUseDefaultCheckBox;
    private Button mBrowseButton;
    private Label mLocationLabel;
    private WorkingSetGroup mWorkingSetGroup;
    /**
     * Whether we've made sure the Tools are up to date (enough that all the
     * resources required by the New Project wizard are present -- we don't
     * necessarily check for newer versions than that here; that's done by
     * {@link VersionCheck}, though that check doesn't <b>enforce</b> an update
     * since it needs to allow the user to proceed to access the SDK manager
     * etc.)
     */
    private boolean mCheckedSdkUptodate;

    /**
     * Create the wizard.
     * @param values current wizard state
     */
    ProjectNamePage(NewProjectWizardState values) {
        super("projectNamePage"); //$NON-NLS-1$
        mValues = values;

        setTitle("Create Android Project");
        setDescription("Select project name and type of project");
        mWorkingSetGroup = new WorkingSetGroup();
        setWorkingSets(new IWorkingSet[0]);
    }

    void init(IStructuredSelection selection, IWorkbenchPart activePart) {
        setWorkingSets(WorkingSetHelper.getSelectedWorkingSet(selection, activePart));
    }

    /**
     * Create contents of the wizard.
     * @param parent the parent to add the page to
     */
    @Override
    public void createControl(Composite parent) {
        Composite container = new Composite(parent, SWT.NULL);
        container.setLayout(new GridLayout(3, false));

        Label nameLabel = new Label(container, SWT.NONE);
        nameLabel.setText("Project Name:");

        mProjectNameText = new Text(container, SWT.BORDER);
        mProjectNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
        mProjectNameText.addModifyListener(this);

        if (mValues.mode != Mode.TEST) {
            mCreateNewButton = new Button(container, SWT.RADIO);
            mCreateNewButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
            mCreateNewButton.setText("Create new project in workspace");
            mCreateNewButton.addSelectionListener(this);

            // TBD: Should we hide this completely, and make samples something you only invoke
            // from the "New Sample Project" wizard?
            mCreateSampleRadioButton = new Button(container, SWT.RADIO);
            mCreateSampleRadioButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false,
                    3, 1));
            mCreateSampleRadioButton.setText("Create project from existing sample");
            mCreateSampleRadioButton.addSelectionListener(this);
        }

        Label separator = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
        separator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1));

        mUseDefaultCheckBox = new Button(container, SWT.CHECK);
        mUseDefaultCheckBox.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
        mUseDefaultCheckBox.setText("Use default location");
        mUseDefaultCheckBox.addSelectionListener(this);

        mLocationLabel = new Label(container, SWT.NONE);
        mLocationLabel.setText("Location:");

        mLocationText = new Text(container, SWT.BORDER);
        mLocationText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        mLocationText.addModifyListener(this);

        mBrowseButton = new Button(container, SWT.NONE);
        mBrowseButton.setText("Browse...");
        mBrowseButton.addSelectionListener(this);

        Composite group = mWorkingSetGroup.createControl(container);
        group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 3, 1));

        setControl(container);
    }

    @Override
    public void setVisible(boolean visible) {
        super.setVisible(visible);

        if (visible) {
            try {
                mIgnore = true;
                if (mValues.projectName != null) {
                        mProjectNameText.setText(mValues.projectName);
                    mProjectNameText.setFocus();
                }
                if (mValues.mode == Mode.ANY || mValues.mode == Mode.TEST) {
                    if (mValues.useExisting) {
                        assert false; // This is now handled by the separate import wizard
                    } else if (mCreateNewButton != null) {
                        mCreateNewButton.setSelection(true);
                    }
                } else if (mValues.mode == Mode.SAMPLE) {
                    mCreateSampleRadioButton.setSelection(true);
                }
                if (mValues.projectLocation != null) {
                    mLocationText.setText(mValues.projectLocation.getPath());
                }
                mUseDefaultCheckBox.setSelection(mValues.useDefaultLocation);
                updateLocationState();
            } finally {
                mIgnore = false;
            }
        }

        validatePage();
    }

    @Override
    public void modifyText(ModifyEvent e) {
        if (mIgnore) {
            return;
        }

        Object source = e.getSource();

        if (source == mProjectNameText) {
            onProjectFieldModified();
            if (!mValues.useDefaultLocation && !mValues.projectLocationModifiedByUser) {
                updateLocationPathField(null);
            }
        } else if (source == mLocationText) {
            mValues.projectLocationModifiedByUser = true;
            if (!mValues.useDefaultLocation) {
                File f = new File(mLocationText.getText().trim());
                mValues.projectLocation = f;
                if (f.exists() && f.isDirectory() && !f.equals(mValues.projectLocation)) {
                    updateLocationPathField(mValues.projectLocation.getPath());
                }
            }
        }

        validatePage();
    }

    private void onProjectFieldModified() {
        mValues.projectName = mProjectNameText.getText().trim();
        mValues.projectNameModifiedByUser = true;

        if (!mValues.applicationNameModifiedByUser) {
            mValues.applicationName = capitalize(mValues.projectName);
            if (!mValues.testApplicationNameModified) {
                mValues.testApplicationName =
                        ApplicationInfoPage.suggestTestApplicationName(mValues.applicationName);
            }
        }
        if (!mValues.activityNameModifiedByUser) {
            String name = capitalize(mValues.projectName);
            mValues.activityName = stripWhitespace(name) + ACTIVITY_NAME_SUFFIX;
        }
        if (!mValues.testProjectModified) {
            mValues.testProjectName =
                    ApplicationInfoPage.suggestTestProjectName(mValues.projectName);
        }
        if (!mValues.projectLocationModifiedByUser) {
            updateLocationPathField(null);
        }
    }

    @Override
    public void widgetSelected(SelectionEvent e) {
        if (mIgnore) {
            return;
        }

        Object source = e.getSource();

        if (source == mCreateNewButton && mCreateNewButton != null
                && mCreateNewButton.getSelection()) {
            mValues.useExisting = false;
            if (mValues.mode == Mode.SAMPLE) {
                // Only reset the mode if we're toggling from sample back to create new
                // or create existing. We can only come to the sample state when we're in
                // ANY mode. (In particular, we don't want to switch to ANY if you're
                // in test mode.
                mValues.mode = Mode.ANY;
            }
            updateLocationState();
        } else if (source == mCreateSampleRadioButton && mCreateSampleRadioButton.getSelection()) {
            mValues.useExisting = true;
            mValues.useDefaultLocation = true;
            if (!mUseDefaultCheckBox.getSelection()) {
                try {
                    mIgnore = true;
                    mUseDefaultCheckBox.setSelection(true);
                } finally {
                    mIgnore = false;
                }
            }
            mValues.mode = Mode.SAMPLE;
            updateLocationState();
        } else if (source == mUseDefaultCheckBox) {
            mValues.useDefaultLocation = mUseDefaultCheckBox.getSelection();
            updateLocationState();
        } else if (source == mBrowseButton) {
            onOpenDirectoryBrowser();
        }

        validatePage();
    }

   /**
    * Enables or disable the location widgets depending on the user selection:
    * the location path is enabled when using the "existing source" mode (i.e. not new project)
    * or in new project mode with the "use default location" turned off.
    */
   private void updateLocationState() {
       boolean isNewProject = !mValues.useExisting;
       boolean isCreateFromSample = mValues.mode == Mode.SAMPLE;
       boolean useDefault = mValues.useDefaultLocation && !isCreateFromSample;
       boolean locationEnabled = (!isNewProject || !useDefault) && !isCreateFromSample;

       mUseDefaultCheckBox.setEnabled(isNewProject);
       mLocationLabel.setEnabled(locationEnabled);
       mLocationText.setEnabled(locationEnabled);
       mBrowseButton.setEnabled(locationEnabled);

       updateLocationPathField(null);
   }

    /**
     * Display a directory browser and update the location path field with the selected path
     */
    private void onOpenDirectoryBrowser() {

        String existingDir = mLocationText.getText().trim();

        // Disable the path if it doesn't exist
        if (existingDir.length() == 0) {
            existingDir = null;
        } else {
            File f = new File(existingDir);
            if (!f.exists()) {
                existingDir = null;
            }
        }

        DirectoryDialog directoryDialog = new DirectoryDialog(mLocationText.getShell());
        directoryDialog.setMessage("Browse for folder");
        directoryDialog.setFilterPath(existingDir);
        String dir = directoryDialog.open();

        if (dir != null) {
            updateLocationPathField(dir);
            validatePage();
        }
    }

    @Override
    public void widgetDefaultSelected(SelectionEvent e) {
    }

    /**
     * Returns the working sets to which the new project should be added.
     *
     * @return the selected working sets to which the new project should be added
     */
    private IWorkingSet[] getWorkingSets() {
        return mWorkingSetGroup.getSelectedWorkingSets();
    }

    /**
     * Sets the working sets to which the new project should be added.
     *
     * @param workingSets the initial selected working sets
     */
    private void setWorkingSets(IWorkingSet[] workingSets) {
        assert workingSets != null;
        mWorkingSetGroup.setWorkingSets(workingSets);
    }

    /**
     * Updates the location directory path field.
     * <br/>
     * When custom user selection is enabled, use the absDir argument if not null and also
     * save it internally. If absDir is null, restore the last saved absDir. This allows the
     * user selection to be remembered when the user switches from default to custom.
     * <br/>
     * When custom user selection is disabled, use the workspace default location with the
     * current project name. This does not change the internally cached absDir.
     *
     * @param absDir A new absolute directory path or null to use the default.
     */
    private void updateLocationPathField(String absDir) {
        boolean isNewProject = !mValues.useExisting || mValues.mode == Mode.SAMPLE;
        boolean useDefault = mValues.useDefaultLocation;
        boolean customLocation = !isNewProject || !useDefault;

        if (!mIgnore) {
            try {
                mIgnore = true;
                if (customLocation) {
                    if (absDir != null) {
                        // We get here if the user selected a directory with the "Browse" button.
                        // Disable auto-compute of the custom location unless the user selected
                        // the exact same path.
                        sAutoComputeCustomLocation = sAutoComputeCustomLocation &&
                                                     absDir.equals(sCustomLocationOsPath);
                        sCustomLocationOsPath = TextProcessor.process(absDir);
                    } else  if (sAutoComputeCustomLocation ||
                                (!isNewProject && !new File(sCustomLocationOsPath).isDirectory())) {
                        // As a default import location, just suggest the home directory; the user
                        // needs to point to a project to import.
                        // TODO: Open file chooser automatically?
                        sCustomLocationOsPath = System.getProperty("user.home"); //$NON-NLS-1$
                    }
                    if (!mLocationText.getText().equals(sCustomLocationOsPath)) {
                        mLocationText.setText(sCustomLocationOsPath);
                        mValues.projectLocation = new File(sCustomLocationOsPath);
                    }
                } else {
                    String value = Platform.getLocation().append(mValues.projectName).toString();
                    value = TextProcessor.process(value);
                    if (!mLocationText.getText().equals(value)) {
                        mLocationText.setText(value);
                        mValues.projectLocation = new File(value);
                    }
                }
            } finally {
                mIgnore = false;
            }
        }

        if (mValues.useExisting && mValues.projectLocation != null
                && mValues.projectLocation.exists() && mValues.mode != Mode.SAMPLE) {
            mValues.extractFromAndroidManifest(new Path(mValues.projectLocation.getPath()));
            if (!mValues.projectNameModifiedByUser && mValues.projectName != null) {
                try {
                    mIgnore = true;
                    mProjectNameText.setText(mValues.projectName);
                } finally {
                    mIgnore = false;
                }
            }
        }
    }

    private void validatePage() {
        IStatus status = null;

        // Validate project name -- unless we're creating a sample, in which case
        // the user will get a chance to pick the name on the Sample page
        if (mValues.mode != Mode.SAMPLE) {
            status = validateProjectName(mValues.projectName);
        }

        if (status == null || status.getSeverity() != IStatus.ERROR) {
            IStatus validLocation = validateLocation();
            if (validLocation != null) {
                status = validLocation;
            }
        }

        if (!mCheckedSdkUptodate) {
            // Ensure that we have a recent enough version of the Tools that the right templates
            // are available
            File file = new File(AdtPlugin.getOsSdkFolder(), OS_SDK_TOOLS_LIB_FOLDER
                    + File.separator + FN_PROJECT_PROGUARD_FILE);
            if (!file.exists()) {
                status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                        String.format("You do not have the latest version of the "
                        + "SDK Tools installed: Please update. (Missing %1$s)", file.getPath()));
            } else {
                mCheckedSdkUptodate = true;
            }
        }

        // -- update UI & enable finish if there's no error
        setPageComplete(status == null || status.getSeverity() != IStatus.ERROR);
        if (status != null) {
            setMessage(status.getMessage(),
                    status.getSeverity() == IStatus.ERROR
                        ? IMessageProvider.ERROR : IMessageProvider.WARNING);
        } else {
            setErrorMessage(null);
            setMessage(null);
        }
    }

    private IStatus validateLocation() {
        if (mValues.mode == Mode.SAMPLE) {
            // Samples are always created in the default directory
            return null;
        }

        // Validate location
        Path path = new Path(mValues.projectLocation.getPath());
        if (!mValues.useExisting) {
            if (!mValues.useDefaultLocation) {
                // If not using the default value validate the location.
                URI uri = URIUtil.toURI(path.toOSString());
                IWorkspace workspace = ResourcesPlugin.getWorkspace();
                IProject handle = workspace.getRoot().getProject(mValues.projectName);
                IStatus locationStatus = workspace.validateProjectLocationURI(handle, uri);
                if (!locationStatus.isOK()) {
                    return locationStatus;
                }
                // The location is valid as far as Eclipse is concerned (i.e. mostly not
                // an existing workspace project.) Check it either doesn't exist or is
                // a directory that is empty.
                File f = path.toFile();
                if (f.exists() && !f.isDirectory()) {
                    return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                            "A directory name must be specified.");
                } else if (f.isDirectory()) {
                    // However if the directory exists, we should put a
                    // warning if it is not empty. We don't put an error
                    // (we'll ask the user again for confirmation before
                    // using the directory.)
                    String[] l = f.list();
                    if (l != null && l.length != 0) {
                        return new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID,
                                "The selected output directory is not empty.");
                    }
                }
            } else {
                // Otherwise validate the path string is not empty
                if (mValues.projectLocation.getPath().length() == 0) {
                    return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                            "A directory name must be specified.");
                }
                File dest = path.toFile();
                if (dest.exists()) {
                    return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                            String.format(
                                    "There is already a file or directory named \"%1$s\" in the selected location.",
                            mValues.projectName));
                }
            }
        } else {
            // Must be an existing directory
            File f = path.toFile();
            if (!f.isDirectory()) {
                return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                        "An existing directory name must be specified.");
            }

            // Check there's an android manifest in the directory
            String osPath = path.append(SdkConstants.FN_ANDROID_MANIFEST_XML).toOSString();
            File manifestFile = new File(osPath);
            if (!manifestFile.isFile()) {
                return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                        String.format(
                                "Choose a valid Android code directory\n" +
                                "(%1$s not found in %2$s.)",
                                SdkConstants.FN_ANDROID_MANIFEST_XML, f.getName()));
            }

            // Parse it and check the important fields.
            ManifestData manifestData = AndroidManifestHelper.parseForData(osPath);
            if (manifestData == null) {
                return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                        String.format("File %1$s could not be parsed.", osPath));
            }
            String packageName = manifestData.getPackage();
            if (packageName == null || packageName.length() == 0) {
                return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                        String.format("No package name defined in %1$s.", osPath));
            }
            Activity[] activities = manifestData.getActivities();
            if (activities == null || activities.length == 0) {
                // This is acceptable now as long as no activity needs to be
                // created
                if (mValues.createActivity) {
                    return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                            String.format("No activity name defined in %1$s.", osPath));
                }
            }

            // If there's already a .project, tell the user to use import instead.
            if (path.append(".project").toFile().exists()) {  //$NON-NLS-1$
                return new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID,
                        "An Eclipse project already exists in this directory.\n" +
                        "Consider using File > Import > Existing Project instead.");
            }
        }

        return null;
    }

    public static IStatus validateProjectName(String projectName) {
        if (projectName == null || projectName.length() == 0) {
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    "Project name must be specified");
        } else {
            IWorkspace workspace = ResourcesPlugin.getWorkspace();
            IStatus nameStatus = workspace.validateName(projectName, IResource.PROJECT);
            if (!nameStatus.isOK()) {
                return nameStatus;
            } else {
                // Note: the case-sensitiveness of the project name matters and can cause a
                // conflict *later* when creating the project resource, so let's check it now.
                for (IProject existingProj : workspace.getRoot().getProjects()) {
                    if (projectName.equalsIgnoreCase(existingProj.getName())) {
                        return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                                "A project with that name already exists in the workspace");
                    }
                }
            }
        }

        return null;
    }

    @Override
    public IWizardPage getNextPage() {
        // Sync working set data to the value object, since the WorkingSetGroup
        // doesn't let us add listeners to do this lazily
        mValues.workingSets = getWorkingSets();

        return super.getNextPage();
    }
}
