/*
 * Copyright (C) 2007 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.
 */

/*
 * References:
 * org.eclipse.jdt.internal.ui.wizards.JavaProjectWizard
 * org.eclipse.jdt.internal.ui.wizards.JavaProjectWizardFirstPage
 */

package com.android.ide.eclipse.adt.internal.wizards.newproject;

import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AndroidConstants;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser.Activity;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
import com.android.ide.eclipse.adt.internal.wizards.newproject.NewTestProjectCreationPage.TestInfo;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
import com.android.sdkuilib.internal.widgets.SdkTargetSelector;

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.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.TextProcessor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
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.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;

import java.io.File;
import java.io.FileFilter;
import java.net.URI;
import java.util.ArrayList;
import java.util.regex.Pattern;

/**
 * NewAndroidProjectCreationPage is a project creation page that provides the
 * following fields:
 * <ul>
 * <li> Project name
 * <li> SDK Target
 * <li> Application name
 * <li> Package name
 * <li> Activity name
 * </ul>
 * Note: this class is public so that it can be accessed from unit tests.
 * It is however an internal class. Its API may change without notice.
 * It should semantically be considered as a private final class.
 * Do not derive from this class.
 */
public class NewProjectCreationPage extends WizardPage {

    // constants
    private static final String MAIN_PAGE_NAME = "newAndroidProjectPage"; //$NON-NLS-1$

    /** Initial value for all name fields (project, activity, application, package). Used
     * whenever a value is requested before controls are created. */
    private static final String INITIAL_NAME = "";  //$NON-NLS-1$
    /** Initial value for the Create New Project radio. */
    private static final boolean INITIAL_CREATE_NEW_PROJECT = true;
    /** Initial value for the Create Project From Sample. */
    private static final boolean INITIAL_CREATE_FROM_SAMPLE = false;
    /** Initial value for the Create Project From Existing Source. */
    private static final boolean INITIAL_CREATE_FROM_SOURCE = false;
    /** Initial value for the Use Default Location check box. */
    private static final boolean INITIAL_USE_DEFAULT_LOCATION = true;
    /** Initial value for the Create Activity check box. */
    private static final boolean INITIAL_CREATE_ACTIVITY = true;


    /** Pattern for characters accepted in a project name. Since this will be used as a
     * directory name, we're being a bit conservative on purpose. It cannot start with a space. */
    private static final Pattern sProjectNamePattern = Pattern.compile("^[\\w][\\w. -]*$");  //$NON-NLS-1$
    /** 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 final int MSG_NONE = 0;
    private final int MSG_WARNING = 1;
    private final int MSG_ERROR = 2;

    /** Structure with the externally visible information from this Main Project page. */
    private final MainInfo mInfo = new MainInfo();
    /** Structure with the externally visible information from the Test Project page.
     *  This is null if there's no such page, meaning the main project page is standalone. */
    private TestInfo mTestInfo;

    private String mUserPackageName = "";       //$NON-NLS-1$
    private String mUserActivityName = "";      //$NON-NLS-1$
    private boolean mUserCreateActivityCheck = INITIAL_CREATE_ACTIVITY;
    private String mSourceFolder = "";          //$NON-NLS-1$

    // widgets
    private Text mProjectNameField;
    private Text mPackageNameField;
    private Text mActivityNameField;
    private Text mApplicationNameField;
    private Button mCreateNewProjectRadio;
    private Button mCreateFromSampleRadio;
    private Button mUseDefaultLocation;
    private Label mLocationLabel;
    private Text mLocationPathField;
    private Button mBrowseButton;
    private Button mCreateActivityCheck;
    private Text mMinSdkVersionField;
    private SdkTargetSelector mSdkTargetSelector;
    private ITargetChangeListener mSdkTargetChangeListener;

    private boolean mInternalLocationPathUpdate;
    private boolean mInternalProjectNameUpdate;
    private boolean mInternalApplicationNameUpdate;
    private boolean mInternalCreateActivityUpdate;
    private boolean mInternalActivityNameUpdate;
    private boolean mProjectNameModifiedByUser;
    private boolean mApplicationNameModifiedByUser;
    private boolean mInternalMinSdkVersionUpdate;

    private final ArrayList<String> mSamplesPaths = new ArrayList<String>();
    private Combo mSamplesCombo;



    /**
     * Creates a new project creation wizard page.
     */
    public NewProjectCreationPage() {
        super(MAIN_PAGE_NAME);
        setPageComplete(false);
        setTitle("New Android Project");
        setDescription("Creates a new Android Project resource.");
    }

    // --- Getters used by NewProjectWizard ---


    /**
     * Structure that collects all externally visible information from this page.
     * This is used by the calling wizard to actually do the work or by other pages.
     * <p/>
     * This interface is provided so that the adt-test counterpart can override the returned
     * information.
     */
    public interface IMainInfo {
        public IPath getLocationPath();
        /**
         * Returns the current project location path as entered by the user, or its
         * anticipated initial value. Note that if the default has been returned the
         * path in a project description used to create a project should not be set.
         *
         * @return the project location path or its anticipated initial value.
         */
        /** Returns the value of the project name field with leading and trailing spaces removed. */
        public String getProjectName();
        /** Returns the value of the package name field with spaces trimmed. */
        public String getPackageName();
        /** Returns the value of the activity name field with spaces trimmed. */
        public String getActivityName();
        /** Returns the value of the min sdk version field with spaces trimmed. */
        public String getMinSdkVersion();
        /** Returns the value of the application name field with spaces trimmed. */
        public String getApplicationName();
        /** Returns the value of the "Create New Project" radio. */
        public boolean isNewProject();
        /** Returns the value of the "Create Activity" checkbox. */
        public boolean isCreateActivity();
        /** Returns the value of the Use Default Location field. */
        public boolean useDefaultLocation();
        /** Returns the internal source folder (for the "existing project" mode) or the default
         * "src" constant. */
        public String getSourceFolder();
        /** Returns the current sdk target or null if none has been selected yet. */
        public IAndroidTarget getSdkTarget();
    }


    /**
     * Structure that collects all externally visible information from this page.
     * This is used by the calling wizard to actually do the work or by other pages.
     */
    public class MainInfo implements IMainInfo {
        /**
         * Returns the current project location path as entered by the user, or its
         * anticipated initial value. Note that if the default has been returned the
         * path in a project description used to create a project should not be set.
         *
         * @return the project location path or its anticipated initial value.
         */
        public IPath getLocationPath() {
            return new Path(getProjectLocation());
        }

        /** Returns the value of the project name field with leading and trailing spaces removed. */
        public String getProjectName() {
            return mProjectNameField == null ? INITIAL_NAME : mProjectNameField.getText().trim();
        }

        /** Returns the value of the package name field with spaces trimmed. */
        public String getPackageName() {
            return mPackageNameField == null ? INITIAL_NAME : mPackageNameField.getText().trim();
        }

        /** Returns the value of the activity name field with spaces trimmed. */
        public String getActivityName() {
            return mActivityNameField == null ? INITIAL_NAME : mActivityNameField.getText().trim();
        }

        /** Returns the value of the min sdk version field with spaces trimmed. */
        public String getMinSdkVersion() {
            return mMinSdkVersionField == null ? "" : mMinSdkVersionField.getText().trim();  //$NON-NLS-1$
        }

        /** Returns the value of the application name field with spaces trimmed. */
        public String getApplicationName() {
            // Return the name of the activity as default application name.
            return mApplicationNameField == null ? getActivityName()
                                                 : mApplicationNameField.getText().trim();

        }

        /** Returns the value of the "Create New Project" radio. */
        public boolean isNewProject() {
            return mCreateNewProjectRadio == null ? INITIAL_CREATE_NEW_PROJECT
                                                  : mCreateNewProjectRadio.getSelection();
        }

        /** Returns the value of the "Create from Existing Sample" radio. */
        public boolean isCreateFromSample() {
            return mCreateFromSampleRadio == null ? INITIAL_CREATE_FROM_SAMPLE
                                                  : mCreateFromSampleRadio.getSelection();
        }

        /** Returns the value of the "Create Activity" checkbox. */
        public boolean isCreateActivity() {
            return mCreateActivityCheck == null ? INITIAL_CREATE_ACTIVITY
                                                  : mCreateActivityCheck.getSelection();
        }

        /** Returns the value of the Use Default Location field. */
        public boolean useDefaultLocation() {
            return mUseDefaultLocation == null ? INITIAL_USE_DEFAULT_LOCATION
                                               : mUseDefaultLocation.getSelection();
        }

        /** Returns the internal source folder (for the "existing project" mode) or the default
         * "src" constant. */
        public String getSourceFolder() {
            if (isNewProject() || mSourceFolder == null || mSourceFolder.length() == 0) {
                return SdkConstants.FD_SOURCES;
            } else {
                return mSourceFolder;
            }
        }

        /** Returns the current sdk target or null if none has been selected yet. */
        public IAndroidTarget getSdkTarget() {
            return mSdkTargetSelector == null ? null : mSdkTargetSelector.getSelected();
        }
    }

    /**
     * Returns a {@link MainInfo} structure that collects all externally visible information
     * from this page, to be used by the calling wizard or by other pages.
     */
    public IMainInfo getMainInfo() {
        return mInfo;
    }

    /**
     * Grabs the {@link TestInfo} structure that collects externally visible fields from the
     * test project page. This may be null.
     */
    public void setTestInfo(TestInfo testInfo) {
        mTestInfo = testInfo;
    }

    /**
     * Overrides @DialogPage.setVisible(boolean) to put the focus in the project name when
     * the dialog is made visible.
     */
    @Override
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        if (visible) {
            mProjectNameField.setFocus();
            validatePageComplete();
        }
    }

    // --- UI creation ---

    /**
     * Creates the top level control for this dialog page under the given parent
     * composite.
     *
     * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
     */
    public void createControl(Composite parent) {
        Composite composite = new Composite(parent, SWT.NULL);
        composite.setFont(parent.getFont());

        initializeDialogUnits(parent);

        composite.setLayout(new GridLayout());
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));

        createProjectNameGroup(composite);
        createLocationGroup(composite);
        createTargetGroup(composite);
        createPropertiesGroup(composite);

        // Update state the first time
        enableLocationWidgets();
        loadSamplesForTarget(null /*target*/);

        // Show description the first time
        setErrorMessage(null);
        setMessage(null);
        setControl(composite);

        // Validate. This will complain about the first empty field.
        validatePageComplete();
    }

    @Override
    public void dispose() {

        if (mSdkTargetChangeListener != null) {
            AdtPlugin.getDefault().removeTargetListener(mSdkTargetChangeListener);
            mSdkTargetChangeListener = null;
        }

        super.dispose();
    }

    /**
     * Creates the group for the project name:
     * [label: "Project Name"] [text field]
     *
     * @param parent the parent composite
     */
    private final void createProjectNameGroup(Composite parent) {
        Composite group = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        group.setLayout(layout);
        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        // new project label
        Label label = new Label(group, SWT.NONE);
        label.setText("Project name:");
        label.setFont(parent.getFont());
        label.setToolTipText("Name of the Eclipse project to create. It cannot be empty.");

        // new project name entry field
        mProjectNameField = new Text(group, SWT.BORDER);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        mProjectNameField.setToolTipText("Name of the Eclipse project to create. It cannot be empty.");
        mProjectNameField.setLayoutData(data);
        mProjectNameField.setFont(parent.getFont());
        mProjectNameField.addListener(SWT.Modify, new Listener() {
            public void handleEvent(Event event) {
                if (!mInternalProjectNameUpdate) {
                    mProjectNameModifiedByUser = true;
                }
                updateLocationPathField(null);
            }
        });
    }


    /**
     * Creates the group for the Project options:
     * [radio] Create new project
     * [radio] Create project from existing sources
     * [check] Use default location
     * Location [text field] [browse button]
     *
     * @param parent the parent composite
     */
    private final void createLocationGroup(Composite parent) {
        Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
        // Layout has 4 columns of non-equal size
        group.setLayout(new GridLayout());
        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        group.setFont(parent.getFont());
        group.setText("Contents");

        mCreateNewProjectRadio = new Button(group, SWT.RADIO);
        mCreateNewProjectRadio.setText("Create new project in workspace");
        mCreateNewProjectRadio.setSelection(INITIAL_CREATE_NEW_PROJECT);

        Button existing_project_radio = new Button(group, SWT.RADIO);
        existing_project_radio.setText("Create project from existing source");
        existing_project_radio.setSelection(INITIAL_CREATE_FROM_SOURCE);

        mUseDefaultLocation = new Button(group, SWT.CHECK);
        mUseDefaultLocation.setText("Use default location");
        mUseDefaultLocation.setSelection(INITIAL_USE_DEFAULT_LOCATION);

        SelectionListener location_listener = new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                super.widgetSelected(e);
                enableLocationWidgets();
                extractNamesFromAndroidManifest();
                validatePageComplete();
            }
        };

        mCreateNewProjectRadio.addSelectionListener(location_listener);
        existing_project_radio.addSelectionListener(location_listener);
        mUseDefaultLocation.addSelectionListener(location_listener);

        Composite location_group = new Composite(group, SWT.NONE);
        location_group.setLayout(new GridLayout(3, /* num columns */
                false /* columns of not equal size */));
        location_group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        location_group.setFont(parent.getFont());

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

        mLocationPathField = new Text(location_group, SWT.BORDER);
        GridData data = new GridData(GridData.FILL, /* horizontal alignment */
                GridData.BEGINNING, /* vertical alignment */
                true,  /* grabExcessHorizontalSpace */
                false, /* grabExcessVerticalSpace */
                1,     /* horizontalSpan */
                1);    /* verticalSpan */
        mLocationPathField.setLayoutData(data);
        mLocationPathField.setFont(parent.getFont());
        mLocationPathField.addListener(SWT.Modify, new Listener() {
           public void handleEvent(Event event) {
               onLocationPathFieldModified();
            }
        });

        mBrowseButton = new Button(location_group, SWT.PUSH);
        mBrowseButton.setText("Browse...");
        setButtonLayoutData(mBrowseButton);
        mBrowseButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                onOpenDirectoryBrowser();
            }
        });

        mCreateFromSampleRadio = new Button(group, SWT.RADIO);
        mCreateFromSampleRadio.setText("Create project from existing sample");
        mCreateFromSampleRadio.setSelection(INITIAL_CREATE_FROM_SAMPLE);
        mCreateFromSampleRadio.addSelectionListener(location_listener);

        Composite samples_group = new Composite(group, SWT.NONE);
        samples_group.setLayout(new GridLayout(2, /* num columns */
                false /* columns of not equal size */));
        samples_group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        samples_group.setFont(parent.getFont());

        new Label(samples_group, SWT.NONE).setText("Samples:");

        mSamplesCombo = new Combo(samples_group, SWT.DROP_DOWN | SWT.READ_ONLY);
        mSamplesCombo.setEnabled(false);
        mSamplesCombo.select(0);
        mSamplesCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        mSamplesCombo.setToolTipText("Select a sample");

        mSamplesCombo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                onSampleSelected();
            }
        });

    }

    /**
     * Creates the target group.
     * It only contains an SdkTargetSelector.
     */
    private void createTargetGroup(Composite parent) {
        Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
        // Layout has 1 column
        group.setLayout(new GridLayout());
        group.setLayoutData(new GridData(GridData.FILL_BOTH));
        group.setFont(parent.getFont());
        group.setText("Build Target");

        // The selector is created without targets. They are added below in the change listener.
        mSdkTargetSelector = new SdkTargetSelector(group, null);

        mSdkTargetChangeListener = new ITargetChangeListener() {
            public void onProjectTargetChange(IProject changedProject) {
                // Ignore
            }

            public void onTargetsLoaded() {
                // Update the sdk target selector with the new targets

                // get the targets from the sdk
                IAndroidTarget[] targets = null;
                if (Sdk.getCurrent() != null) {
                    targets = Sdk.getCurrent().getTargets();
                }
                mSdkTargetSelector.setTargets(targets);

                // If there's only one target, select it
                if (targets != null && targets.length == 1) {
                    mSdkTargetSelector.setSelection(targets[0]);
                }
            }
        };

        AdtPlugin.getDefault().addTargetListener(mSdkTargetChangeListener);

        // Invoke it once to initialize the targets
        mSdkTargetChangeListener.onTargetsLoaded();

        mSdkTargetSelector.setSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                onSdkTargetModified();
                updateLocationPathField(null);
                validatePageComplete();
            }
        });
    }

    /**
     * Creates the group for the project properties:
     * - Package name [text field]
     * - Activity name [text field]
     * - Application name [text field]
     *
     * @param parent the parent composite
     */
    private final void createPropertiesGroup(Composite parent) {
        // package specification group
        Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        group.setLayout(layout);
        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        group.setFont(parent.getFont());
        group.setText("Properties");

        // new application label
        Label label = new Label(group, SWT.NONE);
        label.setText("Application name:");
        label.setFont(parent.getFont());
        label.setToolTipText("Name of the Application. This is a free string. It can be empty.");

        // new application name entry field
        mApplicationNameField = new Text(group, SWT.BORDER);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        mApplicationNameField.setToolTipText("Name of the Application. This is a free string. It can be empty.");
        mApplicationNameField.setLayoutData(data);
        mApplicationNameField.setFont(parent.getFont());
        mApplicationNameField.addListener(SWT.Modify, new Listener() {
           public void handleEvent(Event event) {
               if (!mInternalApplicationNameUpdate) {
                   mApplicationNameModifiedByUser = true;
               }
           }
        });

        // new package label
        label = new Label(group, SWT.NONE);
        label.setText("Package name:");
        label.setFont(parent.getFont());
        label.setToolTipText("Namespace of the Package to create. This must be a Java namespace with at least two components.");

        // new package name entry field
        mPackageNameField = new Text(group, SWT.BORDER);
        data = new GridData(GridData.FILL_HORIZONTAL);
        mPackageNameField.setToolTipText("Namespace of the Package to create. This must be a Java namespace with at least two components.");
        mPackageNameField.setLayoutData(data);
        mPackageNameField.setFont(parent.getFont());
        mPackageNameField.addListener(SWT.Modify, new Listener() {
            public void handleEvent(Event event) {
                onPackageNameFieldModified();
            }
        });

        // new activity label
        mCreateActivityCheck = new Button(group, SWT.CHECK);
        mCreateActivityCheck.setText("Create Activity:");
        mCreateActivityCheck.setToolTipText("Specifies if you want to create a default Activity.");
        mCreateActivityCheck.setFont(parent.getFont());
        mCreateActivityCheck.setSelection(INITIAL_CREATE_ACTIVITY);
        mCreateActivityCheck.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event event) {
                onCreateActivityCheckModified();
                enableLocationWidgets();
            }
        });

        // new activity name entry field
        mActivityNameField = new Text(group, SWT.BORDER);
        data = new GridData(GridData.FILL_HORIZONTAL);
        mActivityNameField.setToolTipText("Name of the Activity class to create. Must be a valid Java identifier.");
        mActivityNameField.setLayoutData(data);
        mActivityNameField.setFont(parent.getFont());
        mActivityNameField.addListener(SWT.Modify, new Listener() {
            public void handleEvent(Event event) {
                onActivityNameFieldModified();
            }
        });

        // min sdk version label
        label = new Label(group, SWT.NONE);
        label.setText("Min SDK Version:");
        label.setFont(parent.getFont());
        label.setToolTipText("The minimum SDK version number that the application requires. Must be an integer > 0. It can be empty.");

        // min sdk version entry field
        mMinSdkVersionField = new Text(group, SWT.BORDER);
        data = new GridData(GridData.FILL_HORIZONTAL);
        label.setToolTipText("The minimum SDK version number that the application requires. Must be an integer > 0. It can be empty.");
        mMinSdkVersionField.setLayoutData(data);
        mMinSdkVersionField.setFont(parent.getFont());
        mMinSdkVersionField.addListener(SWT.Modify, new Listener() {
            public void handleEvent(Event event) {
                onMinSdkVersionFieldModified();
                validatePageComplete();
            }
        });
    }


    //--- Internal getters & setters ------------------

    /** Returns the location path field value with spaces trimmed. */
    private String getLocationPathFieldValue() {
        return mLocationPathField == null ? "" : mLocationPathField.getText().trim();  //$NON-NLS-1$
    }

    /** Returns the current selected sample path,
     * or an empty string if there's no valid selection. */
    private String getSelectedSamplePath() {
        int selIndex = mSamplesCombo.getSelectionIndex();
        if (selIndex >= 0 && selIndex < mSamplesPaths.size()) {
            return mSamplesPaths.get(selIndex);
        }
        return "";
    }

    /** Returns the current project location, depending on the Use Default Location check box
     * or the Create From Sample check box. */
    private String getProjectLocation() {
        if (mInfo.isCreateFromSample()) {
            return getSelectedSamplePath();
        } else if (mInfo.isNewProject() && mInfo.useDefaultLocation()) {
            return Platform.getLocation().toString();
        } else {
            return getLocationPathFieldValue();
        }
    }

    /**
     * Creates a project resource handle for the current project name field
     * value.
     * <p>
     * This method does not create the project resource; this is the
     * responsibility of <code>IProject::create</code> invoked by the new
     * project resource wizard.
     * </p>
     *
     * @return the new project resource handle
     */
    private IProject getProjectHandle() {
        return ResourcesPlugin.getWorkspace().getRoot().getProject(mInfo.getProjectName());
    }

    // --- UI Callbacks ----

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

        String existing_dir = getLocationPathFieldValue();

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

        DirectoryDialog dd = new DirectoryDialog(mLocationPathField.getShell());
        dd.setMessage("Browse for folder");
        dd.setFilterPath(existing_dir);
        String abs_dir = dd.open();

        if (abs_dir != null) {
            updateLocationPathField(abs_dir);
            extractNamesFromAndroidManifest();
            validatePageComplete();
        }
    }

    /**
     * A sample was selected. Update the location field, manifest and validate.
     */
    private void onSampleSelected() {
        // Note that getProjectLocation() is automatically updated to use the currently
        // selected sample. We just need to refresh the manifest data & validate.
        extractNamesFromAndroidManifest();
        validatePageComplete();
    }

    /**
     * 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 enableLocationWidgets() {
        boolean is_new_project = mInfo.isNewProject();
        boolean is_create_from_sample = mInfo.isCreateFromSample();
        boolean use_default = mInfo.useDefaultLocation() && !is_create_from_sample;
        boolean location_enabled = (!is_new_project || !use_default) && !is_create_from_sample;
        boolean create_activity = mInfo.isCreateActivity();

        mUseDefaultLocation.setEnabled(is_new_project);

        mLocationLabel.setEnabled(location_enabled);
        mLocationPathField.setEnabled(location_enabled);
        mBrowseButton.setEnabled(location_enabled);

        mSamplesCombo.setEnabled(is_create_from_sample && mSamplesPaths.size() > 0);

        mPackageNameField.setEnabled(is_new_project);
        mCreateActivityCheck.setEnabled(is_new_project);
        mActivityNameField.setEnabled(is_new_project & create_activity);

        updateLocationPathField(null);
        updatePackageAndActivityFields();
    }

    /**
     * Updates the location directory path field.
     * <br/>
     * When custom user selection is enabled, use the abs_dir argument if not null and also
     * save it internally. If abs_dir is null, restore the last saved abs_dir. 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 abs_dir.
     *
     * @param abs_dir A new absolute directory path or null to use the default.
     */
    private void updateLocationPathField(String abs_dir) {

        // We don't touch the location path if using the "Create From Sample" mode
        if (mInfo.isCreateFromSample()) {
            return;
        }

        boolean is_new_project = mInfo.isNewProject();
        boolean use_default = mInfo.useDefaultLocation();
        boolean custom_location = !is_new_project || !use_default;

        if (!mInternalLocationPathUpdate) {
            mInternalLocationPathUpdate = true;
            if (custom_location) {
                if (abs_dir != 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 &&
                                                 abs_dir.equals(sCustomLocationOsPath);
                    sCustomLocationOsPath = TextProcessor.process(abs_dir);
                } else  if (sAutoComputeCustomLocation ||
                            (!is_new_project && !new File(sCustomLocationOsPath).isDirectory())) {
                    // By default select the samples directory of the current target
                    IAndroidTarget target = mInfo.getSdkTarget();
                    if (target != null) {
                        sCustomLocationOsPath = target.getPath(IAndroidTarget.SAMPLES);
                    }

                    // If we don't have a target, select the base directory of the
                    // "universal sdk". If we don't even have that, use a root drive.
                    if (sCustomLocationOsPath == null || sCustomLocationOsPath.length() == 0) {
                        if (Sdk.getCurrent() != null) {
                            sCustomLocationOsPath = Sdk.getCurrent().getSdkLocation();
                        } else {
                            sCustomLocationOsPath = File.listRoots()[0].getAbsolutePath();
                        }
                    }
                }
                if (!mLocationPathField.getText().equals(sCustomLocationOsPath)) {
                    mLocationPathField.setText(sCustomLocationOsPath);
                }
            } else {
                String value = Platform.getLocation().append(mInfo.getProjectName()).toString();
                value = TextProcessor.process(value);
                if (!mLocationPathField.getText().equals(value)) {
                    mLocationPathField.setText(value);
                }
            }
            validatePageComplete();
            mInternalLocationPathUpdate = false;
        }
    }

    /**
     * The location path field is either modified internally (from updateLocationPathField)
     * or manually by the user when the custom_location mode is not set.
     *
     * Ignore the internal modification. When modified by the user, memorize the choice and
     * validate the page.
     */
    private void onLocationPathFieldModified() {
        if (!mInternalLocationPathUpdate) {
            // When the updates doesn't come from updateLocationPathField, it must be the user
            // editing the field manually, in which case we want to save the value internally
            // and we disable auto-compute of the custom location (to avoid overriding the user
            // value)
            String newPath = getLocationPathFieldValue();
            sAutoComputeCustomLocation = sAutoComputeCustomLocation &&
                                         newPath.equals(sCustomLocationOsPath);
            sCustomLocationOsPath = newPath;
            extractNamesFromAndroidManifest();
            validatePageComplete();
        }
    }

    /**
     * The package name field is either modified internally (from extractNamesFromAndroidManifest)
     * or manually by the user when the custom_location mode is not set.
     *
     * Ignore the internal modification. When modified by the user, memorize the choice and
     * validate the page.
     */
    private void onPackageNameFieldModified() {
        if (mInfo.isNewProject()) {
            mUserPackageName = mInfo.getPackageName();
            validatePageComplete();
        }
    }

    /**
     * The create activity checkbox is either modified internally (from
     * extractNamesFromAndroidManifest)  or manually by the user.
     *
     * Ignore the internal modification. When modified by the user, memorize the choice and
     * validate the page.
     */
    private void onCreateActivityCheckModified() {
        if (mInfo.isNewProject() && !mInternalCreateActivityUpdate) {
            mUserCreateActivityCheck = mInfo.isCreateActivity();
        }
        validatePageComplete();
    }

    /**
     * The activity name field is either modified internally (from extractNamesFromAndroidManifest)
     * or manually by the user when the custom_location mode is not set.
     *
     * Ignore the internal modification. When modified by the user, memorize the choice and
     * validate the page.
     */
    private void onActivityNameFieldModified() {
        if (mInfo.isNewProject() && !mInternalActivityNameUpdate) {
            mUserActivityName = mInfo.getActivityName();
            validatePageComplete();
        }
    }

    /**
     * Called when the min sdk version field has been modified.
     *
     * Ignore the internal modifications. When modified by the user, try to match
     * a target with the same API level.
     */
    private void onMinSdkVersionFieldModified() {
        if (mInternalMinSdkVersionUpdate) {
            return;
        }

        String minSdkVersion = mInfo.getMinSdkVersion();

        // Before changing, compare with the currently selected one, if any.
        // There can be multiple targets with the same sdk api version, so don't change
        // it if it's already at the right version.
        IAndroidTarget curr_target = mInfo.getSdkTarget();
        if (curr_target != null && curr_target.getVersion().equals(minSdkVersion)) {
            return;
        }

        for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
            if (target.getVersion().equals(minSdkVersion)) {
                mSdkTargetSelector.setSelection(target);
                break;
            }
        }
    }

    /**
     * Called when an SDK target is modified.
     *
     * Also changes the minSdkVersion field to reflect the sdk api level that has
     * just been selected.
     */
    private void onSdkTargetModified() {
        IAndroidTarget target = mInfo.getSdkTarget();

        if (target != null) {
            mInternalMinSdkVersionUpdate = true;
            mMinSdkVersionField.setText(target.getVersion().getApiString());
            mInternalMinSdkVersionUpdate = false;
        }

        loadSamplesForTarget(target);
        enableLocationWidgets();
        onSampleSelected();
    }

    /**
     * Called when the radio buttons are changed between the "create new project" and the
     * "use existing source" mode. This reverts the fields to whatever the user manually
     * entered before.
     */
    private void updatePackageAndActivityFields() {
        if (mInfo.isNewProject()) {
            if (mUserPackageName.length() > 0 &&
                    !mPackageNameField.getText().equals(mUserPackageName)) {
                mPackageNameField.setText(mUserPackageName);
            }

            if (mUserActivityName.length() > 0 &&
                    !mActivityNameField.getText().equals(mUserActivityName)) {
                mInternalActivityNameUpdate = true;
                mActivityNameField.setText(mUserActivityName);
                mInternalActivityNameUpdate = false;
            }

            if (mUserCreateActivityCheck != mCreateActivityCheck.getSelection()) {
                mInternalCreateActivityUpdate = true;
                mCreateActivityCheck.setSelection(mUserCreateActivityCheck);
                mInternalCreateActivityUpdate = false;
            }
        }
    }

    /**
     * Extract names from an android manifest.
     * This is done only if the user selected the "use existing source" and a manifest xml file
     * can actually be found in the custom user directory.
     */
    private void extractNamesFromAndroidManifest() {
        if (mInfo.isNewProject()) {
            return;
        }

        String projectLocation = getProjectLocation();
        File f = new File(projectLocation);
        if (!f.isDirectory()) {
            return;
        }

        Path path = new Path(f.getPath());
        String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();

        AndroidManifestParser manifestData = AndroidManifestParser.parseForData(osPath);
        if (manifestData == null) {
            return;
        }

        String packageName = null;
        Activity activity = null;
        String activityName = null;
        String minSdkVersion = null;
        try {
            packageName = manifestData.getPackage();
            minSdkVersion = manifestData.getApiLevelRequirement();

            // try to get the first launcher activity. If none, just take the first activity.
            activity = manifestData.getLauncherActivity();
            if (activity == null) {
                Activity[] activities = manifestData.getActivities();
                if (activities != null && activities.length > 0) {
                    activity = activities[0];
                }
            }
        } catch (Exception e) {
            // ignore exceptions
        }

        if (packageName != null && packageName.length() > 0) {
            mPackageNameField.setText(packageName);
        }

        if (activity != null) {
            activityName = AndroidManifestParser.extractActivityName(activity.getName(),
                    packageName);
        }

        if (activityName != null && activityName.length() > 0) {
            mInternalActivityNameUpdate = true;
            mInternalCreateActivityUpdate = true;
            mActivityNameField.setText(activityName);
            mCreateActivityCheck.setSelection(true);
            mInternalCreateActivityUpdate = false;
            mInternalActivityNameUpdate = false;

            // If project name and application names are empty, use the activity
            // name as a default. If the activity name has dots, it's a part of a
            // package specification and only the last identifier must be used.
            if (activityName.indexOf('.') != -1) {
                String[] ids = activityName.split(AndroidConstants.RE_DOT);
                activityName = ids[ids.length - 1];
            }
            if (mProjectNameField.getText().length() == 0 || !mProjectNameModifiedByUser) {
                mInternalProjectNameUpdate = true;
                mProjectNameModifiedByUser = false;
                mProjectNameField.setText(activityName);
                mInternalProjectNameUpdate = false;
            }
            if (mApplicationNameField.getText().length() == 0 || !mApplicationNameModifiedByUser) {
                mInternalApplicationNameUpdate = true;
                mApplicationNameModifiedByUser = false;
                mApplicationNameField.setText(activityName);
                mInternalApplicationNameUpdate = false;
            }
        } else {
            mInternalActivityNameUpdate = true;
            mInternalCreateActivityUpdate = true;
            mActivityNameField.setText("");  //$NON-NLS-1$
            mCreateActivityCheck.setSelection(false);
            mInternalCreateActivityUpdate = false;
            mInternalActivityNameUpdate = false;

            // There is no activity name to use to fill in the project and application
            // name. However if there's a package name, we can use this as a base.
            if (packageName != null && packageName.length() > 0) {
                // Package name is a java identifier, so it's most suitable for
                // an application name.

                if (mApplicationNameField.getText().length() == 0 ||
                        !mApplicationNameModifiedByUser) {
                    mInternalApplicationNameUpdate = true;
                    mApplicationNameField.setText(packageName);
                    mInternalApplicationNameUpdate = false;
                }

                // For the project name, remove any dots
                packageName = packageName.replace('.', '_');
                if (mProjectNameField.getText().length() == 0 || !mProjectNameModifiedByUser) {
                    mInternalProjectNameUpdate = true;
                    mProjectNameField.setText(packageName);
                    mInternalProjectNameUpdate = false;
                }

            }
        }

        // Select the target matching the manifest's sdk or build properties, if any
        IAndroidTarget foundTarget = null;
        IAndroidTarget currentTarget = mInfo.getSdkTarget();

        ProjectProperties p = ProjectProperties.create(projectLocation, null);
        if (p != null) {
            // Check the {build|default}.properties files if present
            p.merge(PropertyType.BUILD).merge(PropertyType.DEFAULT);
            String v = p.getProperty(ProjectProperties.PROPERTY_TARGET);
            IAndroidTarget target = Sdk.getCurrent().getTargetFromHashString(v);
            // We can change the current target if:
            // - we found a new target
            // - there is no current target
            // - there is a current target but the new target is not <= to the current one.
            if (target != null &&
                    (currentTarget == null || !target.isCompatibleBaseFor(currentTarget))) {
                foundTarget = target;
            }
        }

        if (foundTarget == null && minSdkVersion != null) {
            // Otherwise try to match the requested sdk version
            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
                if (target != null &&
                        target.getVersion().equals(minSdkVersion) &&
                        (currentTarget == null || !target.isCompatibleBaseFor(currentTarget))) {
                    foundTarget = target;
                    break;
                }
            }
        }

        if (foundTarget == null) {
            // Or last attemp, try to match a sample project location
            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
                if (target != null &&
                        projectLocation.startsWith(target.getLocation()) &&
                        (currentTarget == null || !target.isCompatibleBaseFor(currentTarget))) {
                    foundTarget = target;
                    break;
                }
            }
        }

        if (foundTarget != null) {
            mSdkTargetSelector.setSelection(foundTarget);
        } else {
            mInternalMinSdkVersionUpdate = true;
            if (minSdkVersion != null) {
                mMinSdkVersionField.setText(minSdkVersion);
            }
            mInternalMinSdkVersionUpdate = false;
        }
    }

    /**
     * Updates the list of all samples for the given target SDK.
     * The list is stored in mSamplesPaths as absolute directory paths.
     * The combo is recreated to match this.
     */
    private void loadSamplesForTarget(IAndroidTarget target) {

        // Keep the name of the old selection (if there were any samples)
        String oldChoice = null;
        if (mSamplesPaths.size() > 0) {
            int selIndex = mSamplesCombo.getSelectionIndex();
            if (selIndex > -1) {
                oldChoice = mSamplesCombo.getItem(selIndex);
            }
        }

        // Clear all current content
        mSamplesCombo.removeAll();
        mSamplesPaths.clear();

        if (target != null) {
            // Get the sample root path and recompute the list of samples
            String samplesRootPath = target.getPath(IAndroidTarget.SAMPLES);

            File samplesDir = new File(samplesRootPath);
            findSamplesManifests(samplesDir, mSamplesPaths);

            if (mSamplesPaths.size() == 0) {
                // Odd, this target has no samples. Could happen with an addon.
                mSamplesCombo.add("This target has no samples. Please select another target.");
                mSamplesCombo.select(0);
                return;
            }

            // Recompute the description of each sample (the relative path
            // to the sample root). Also try to find the old selection.
            int selIndex = 0;
            int i = 0;
            int n = samplesRootPath.length();
            for (String path : mSamplesPaths) {
                if (path.length() > n) {
                    path = path.substring(n);
                    if (path.charAt(0) == File.separatorChar) {
                        path = path.substring(1);
                    }
                    if (path.endsWith(File.separator)) {
                        path = path.substring(0, path.length() - 1);
                    }
                    path = path.replaceAll(Pattern.quote(File.separator), " > ");
                }

                if (oldChoice != null && oldChoice.equals(path)) {
                    selIndex = i;
                }

                mSamplesCombo.add(path);
                i++;
            }

            mSamplesCombo.select(selIndex);

        } else {
            mSamplesCombo.add("Please select a target.");
            mSamplesCombo.select(0);
        }
    }

    /**
     * Recursively find potential sample directories under the given directory.
     * Actually lists any directory that contains an android manifest.
     * Paths found are added the samplesPaths list.
     */
    private void findSamplesManifests(File samplesDir, ArrayList<String> samplesPaths) {
        if (!samplesDir.isDirectory()) {
            return;
        }

        for (File f : samplesDir.listFiles()) {
            if (f.isDirectory()) {
                // Assume this is a sample if it contains an android manifest.
                File manifestFile = new File(f, SdkConstants.FN_ANDROID_MANIFEST_XML);
                if (manifestFile.isFile()) {
                    samplesPaths.add(f.getPath());
                }

                // Recurse in the project, to find embedded tests sub-projects
                // We can however skip this recursion for known android sub-dirs that
                // can't have projects, namely for sources, assets and resources.
                String leaf = f.getName();
                if (!SdkConstants.FD_SOURCES.equals(leaf) &&
                        !SdkConstants.FD_ASSETS.equals(leaf) &&
                        !SdkConstants.FD_RES.equals(leaf)) {
                    findSamplesManifests(f, samplesPaths);
                }
            }
        }
    }

    /**
     * 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() {
        IWorkspace workspace = ResourcesPlugin.getWorkspace();

        int status = validateProjectField(workspace);
        if ((status & MSG_ERROR) == 0) {
            status |= validateSdkTarget();
        }
        if ((status & MSG_ERROR) == 0) {
            status |= validateLocationPath(workspace);
        }
        if ((status & MSG_ERROR) == 0) {
            status |= validatePackageField();
        }
        if ((status & MSG_ERROR) == 0) {
            status |= validateActivityField();
        }
        if ((status & MSG_ERROR) == 0) {
            status |= validateMinSdkVersionField();
        }
        if ((status & MSG_ERROR) == 0) {
            status |= validateSourceFolder();
        }
        if (status == MSG_NONE)  {
            setStatus(null, MSG_NONE);
        }

        // Return false if there's an error so that the finish button be disabled.
        return (status & MSG_ERROR) == 0;
    }

    /**
     * Validates the page and updates the Next/Finish buttons
     */
    private void validatePageComplete() {
        setPageComplete(validatePage());
    }

    /**
     * Validates the project name field.
     *
     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
     */
    private int validateProjectField(IWorkspace workspace) {
        // Validate project field
        String projectName = mInfo.getProjectName();
        if (projectName.length() == 0) {
            return setStatus("Project name must be specified", MSG_ERROR);
        }

        // Limit the project name to shell-agnostic characters since it will be used to
        // generate the final package
        if (!sProjectNamePattern.matcher(projectName).matches()) {
            return setStatus("The project name must start with an alphanumeric characters, followed by one or more alphanumerics, digits, dots, dashes, underscores or spaces.",
                    MSG_ERROR);
        }

        IStatus nameStatus = workspace.validateName(projectName, IResource.PROJECT);
        if (!nameStatus.isOK()) {
            return setStatus(nameStatus.getMessage(), MSG_ERROR);
        }

        if (getProjectHandle().exists()) {
            return setStatus("A project with that name already exists in the workspace",
                    MSG_ERROR);
        }

        if (mTestInfo != null &&
                mTestInfo.getCreateTestProject() &&
                projectName.equals(mTestInfo.getProjectName())) {
            return setStatus("The main project name and the test project name must be different.",
                    MSG_WARNING);
        }

        return MSG_NONE;
    }

    /**
     * Validates the location path field.
     *
     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
     */
    private int validateLocationPath(IWorkspace workspace) {
        Path path = new Path(getProjectLocation());
        if (mInfo.isNewProject()) {
            if (!mInfo.useDefaultLocation()) {
                // If not using the default value validate the location.
                URI uri = URIUtil.toURI(path.toOSString());
                IStatus locationStatus = workspace.validateProjectLocationURI(getProjectHandle(),
                        uri);
                if (!locationStatus.isOK()) {
                    return setStatus(locationStatus.getMessage(), MSG_ERROR);
                } else {
                    // 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 setStatus("A directory name must be specified.", MSG_ERROR);
                    } 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.length != 0) {
                            return setStatus("The selected output directory is not empty.",
                                    MSG_WARNING);
                        }
                    }
                }
            } else {
                // Otherwise validate the path string is not empty
                if (getProjectLocation().length() == 0) {
                    return setStatus("A directory name must be specified.", MSG_ERROR);
                }

                File dest = path.append(mInfo.getProjectName()).toFile();
                if (dest.exists()) {
                    return setStatus(String.format("There is already a file or directory named \"%1$s\" in the selected location.",
                            mInfo.getProjectName()), MSG_ERROR);
                }
            }
        } else {
            // Must be an existing directory
            File f = path.toFile();
            if (!f.isDirectory()) {
                return setStatus("An existing directory name must be specified.", MSG_ERROR);
            }

            // Check there's an android manifest in the directory
            String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();
            File manifestFile = new File(osPath);
            if (!manifestFile.isFile()) {
                return setStatus(
                        String.format("File %1$s not found in %2$s.",
                                AndroidConstants.FN_ANDROID_MANIFEST, f.getName()),
                                MSG_ERROR);
            }

            // Parse it and check the important fields.
            AndroidManifestParser manifestData = AndroidManifestParser.parseForData(osPath);
            if (manifestData == null) {
                return setStatus(
                        String.format("File %1$s could not be parsed.", osPath),
                        MSG_ERROR);
            }

            String packageName = manifestData.getPackage();
            if (packageName == null || packageName.length() == 0) {
                return setStatus(
                        String.format("No package name defined in %1$s.", osPath),
                        MSG_ERROR);
            }

            Activity[] activities = manifestData.getActivities();
            if (activities == null || activities.length == 0) {
                // This is acceptable now as long as no activity needs to be created
                if (mInfo.isCreateActivity()) {
                    return setStatus(
                            String.format("No activity name defined in %1$s.", osPath),
                            MSG_ERROR);
                }
            }

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

        return MSG_NONE;
    }

    /**
     * Validates the sdk target choice.
     *
     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
     */
    private int validateSdkTarget() {
        if (mInfo.getSdkTarget() == null) {
            return setStatus("An SDK Target must be specified.", MSG_ERROR);
        }
        return MSG_NONE;
    }

    /**
     * Validates the sdk target choice.
     *
     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
     */
    private int validateMinSdkVersionField() {

        // If the min sdk version is empty, it is always accepted.
        if (mInfo.getMinSdkVersion().length() == 0) {
            return MSG_NONE;
        }

        if (mInfo.getSdkTarget() != null &&
                mInfo.getSdkTarget().getVersion().equals(mInfo.getMinSdkVersion()) == false) {
            return setStatus("The API level for the selected SDK target does not match the Min SDK version.",
                    mInfo.getSdkTarget().getVersion().isPreview() ? MSG_ERROR : MSG_WARNING);
        }

        return MSG_NONE;
    }

    /**
     * Validates the activity name field.
     *
     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
     */
    private int validateActivityField() {
        // Disregard if not creating an activity
        if (!mInfo.isCreateActivity()) {
            return MSG_NONE;
        }

        // Validate activity field
        String activityFieldContents = mInfo.getActivityName();
        if (activityFieldContents.length() == 0) {
            return setStatus("Activity name must be specified.", MSG_ERROR);
        }

        // The activity field can actually contain part of a sub-package name
        // or it can start with a dot "." to indicates it comes from the parent package name.
        String packageName = "";  //$NON-NLS-1$
        int pos = activityFieldContents.lastIndexOf('.');
        if (pos >= 0) {
            packageName = activityFieldContents.substring(0, pos);
            if (packageName.startsWith(".")) { //$NON-NLS-1$
                packageName = packageName.substring(1);
            }

            activityFieldContents = activityFieldContents.substring(pos + 1);
        }

        // the activity field can contain a simple java identifier, or a
        // package name or one that starts with a dot. So if it starts with a dot,
        // ignore this dot -- the rest must look like a package name.
        if (activityFieldContents.charAt(0) == '.') {
            activityFieldContents = activityFieldContents.substring(1);
        }

        // Check it's a valid activity string
        int result = MSG_NONE;
        IStatus status = JavaConventions.validateTypeVariableName(activityFieldContents,
                                                            "1.5", "1.5"); //$NON-NLS-1$ $NON-NLS-2$
        if (!status.isOK()) {
            result = setStatus(status.getMessage(),
                        status.getSeverity() == IStatus.ERROR ? MSG_ERROR : MSG_WARNING);
        }

        // Check it's a valid package string
        if (result != MSG_ERROR && packageName.length() > 0) {
            status = JavaConventions.validatePackageName(packageName,
                                                            "1.5", "1.5"); //$NON-NLS-1$ $NON-NLS-2$
            if (!status.isOK()) {
                result = setStatus(status.getMessage() + " (in the activity name)",
                            status.getSeverity() == IStatus.ERROR ? MSG_ERROR : MSG_WARNING);
            }
        }


        return result;
    }

    /**
     * Validates the package name field.
     *
     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
     */
    private int validatePackageField() {
        // Validate package field
        String packageFieldContents = mInfo.getPackageName();
        if (packageFieldContents.length() == 0) {
            return setStatus("Package name must be specified.", MSG_ERROR);
        }

        // Check it's a valid package string
        int result = MSG_NONE;
        IStatus status = JavaConventions.validatePackageName(packageFieldContents, "1.5", "1.5"); //$NON-NLS-1$ $NON-NLS-2$
        if (!status.isOK()) {
            result = setStatus(status.getMessage(),
                        status.getSeverity() == IStatus.ERROR ? MSG_ERROR : MSG_WARNING);
        }

        // The Android Activity Manager does not accept packages names with only one
        // identifier. Check the package name has at least one dot in them (the previous rule
        // validated that if such a dot exist, it's not the first nor last characters of the
        // string.)
        if (result != MSG_ERROR && packageFieldContents.indexOf('.') == -1) {
            return setStatus("Package name must have at least two identifiers.", MSG_ERROR);
        }

        return result;
    }

    /**
     * Validates that an existing project actually has a source folder.
     *
     * For project in "use existing source" mode, this tries to find the source folder.
     * A source folder should be just under the project directory and it should have all
     * the directories composing the package+activity name.
     *
     * As a side effect, it memorizes the source folder in mSourceFolder.
     *
     * TODO: support multiple source folders for multiple activities.
     *
     * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE.
     */
    private int validateSourceFolder() {
        // This check does nothing when creating a new project.
        // This check is also useless when no activity is present or created.
        if (mInfo.isNewProject() || !mInfo.isCreateActivity()) {
            return MSG_NONE;
        }

        String osTarget = mInfo.getActivityName();

        if (osTarget.indexOf('.') == -1) {
            osTarget = mInfo.getPackageName() + File.separator + osTarget;
        } else if (osTarget.indexOf('.') == 0) {
            osTarget = mInfo.getPackageName() + osTarget;
        }
        osTarget = osTarget.replace('.', File.separatorChar) + AndroidConstants.DOT_JAVA;

        String projectPath = getProjectLocation();
        File projectDir = new File(projectPath);
        File[] all_dirs = projectDir.listFiles(new FileFilter() {
            public boolean accept(File pathname) {
                return pathname.isDirectory();
            }
        });
        for (File f : all_dirs) {
            Path path = new Path(f.getAbsolutePath());
            File java_activity = path.append(osTarget).toFile();
            if (java_activity.isFile()) {
                mSourceFolder = f.getName();
                return MSG_NONE;
            }
        }

        if (all_dirs.length > 0) {
            return setStatus(
                    String.format("%1$s can not be found under %2$s.", osTarget, projectPath),
                    MSG_ERROR);
        } else {
            return setStatus(
                    String.format("No source folders can be found in %1$s.", projectPath),
                    MSG_ERROR);
        }
    }

    /**
     * Sets the error message for the wizard with the given message icon.
     *
     * @param message The wizard message type, one of MSG_ERROR or MSG_WARNING.
     * @return As a convenience, always returns messageType so that the caller can return
     *         immediately.
     */
    private int setStatus(String message, int messageType) {
        if (message == null) {
            setErrorMessage(null);
            setMessage(null);
        } else if (!message.equals(getMessage())) {
            setMessage(message, messageType == MSG_WARNING ? WizardPage.WARNING : WizardPage.ERROR);
        }
        return messageType;
    }

}
