/*
 * 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.wizards.newproject;

import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import com.android.ide.eclipse.common.project.AndroidManifestParser.Activity;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.project.ProjectProperties;
import com.android.sdklib.project.ProjectProperties.PropertyType;
import com.android.sdkuilib.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.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.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
    /** 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; False means Create From Existing would be
     * the default.*/
    private static final boolean INITIAL_CREATE_NEW_PROJECT = true;
    /** 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;
    
    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 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;
    protected boolean mInternalProjectNameUpdate;
    protected boolean mInternalApplicationNameUpdate;
    private boolean mInternalCreateActivityUpdate;
    private boolean mInternalActivityNameUpdate;
    protected boolean mProjectNameModifiedByUser;
    protected boolean mApplicationNameModifiedByUser;
    private boolean mInternalMinSdkVersionUpdate;
    private boolean mMinSdkVersionModifiedByUser;


    /**
     * Creates a new project creation wizard page.
     *
     * @param pageName the name of this page
     */
    public NewProjectCreationPage(String pageName) {
        super(pageName);
        setPageComplete(false);
    }

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

    /**
     * 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();
    }

    /** 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 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();
    }

    /**
     * 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();
        }
    }

    // --- 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();

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

        // Validate. This will complain about the first empty field.
        setPageComplete(validatePage());
    }
    
    @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_BOTH));
        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_NEW_PROJECT);

        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();
                setPageComplete(validatePage());
            }
        };

        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(4, /* num columns */
                false /* columns of not equal size */));
        location_group.setLayoutData(new GridData(GridData.FILL_BOTH));
        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 */
                2,     /* 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) {
                openDirectoryBrowser();
            }
        });
    }

    /**
     * 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("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);
                setPageComplete(validatePage());
            }
        });
    }

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

        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();
            setPageComplete(validatePage());
        }
    }

    /**
     * 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();
                setPageComplete(validatePage());
            }
        });
    }


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

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

    /** Returns the current project location, depending on the Use Default Location check box. */
    public String getProjectLocation() {
        if (isNewProject() && 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(getProjectName());
    }

    // --- UI Callbacks ----

    /**
     * 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 = isNewProject();
        boolean use_default = useDefaultLocation();
        boolean location_enabled = !is_new_project || !use_default;
        boolean create_activity = isCreateActivity();
        
        mUseDefaultLocation.setEnabled(is_new_project);

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

        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) {
        boolean is_new_project = isNewProject();
        boolean use_default = 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 = 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(getProjectName()).toString();
                value = TextProcessor.process(value);
                if (!mLocationPathField.getText().equals(value)) {
                    mLocationPathField.setText(value);
                }
            }
            setPageComplete(validatePage());
            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();
            setPageComplete(validatePage());
        }
    }

    /**
     * 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 (isNewProject()) {
            mUserPackageName = getPackageName();
            setPageComplete(validatePage());
        }
    }

    /**
     * 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 (isNewProject() && !mInternalCreateActivityUpdate) {
            mUserCreateActivityCheck = isCreateActivity();
        }
        setPageComplete(validatePage());
    }

    /**
     * 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 (isNewProject() && !mInternalActivityNameUpdate) {
            mUserActivityName = getActivityName();
            setPageComplete(validatePage());
        }
    }

    /**
     * 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;
        }

        try {
            int version = Integer.parseInt(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 = getSdkTarget();
            if (curr_target != null && curr_target.getApiVersionNumber() == version) {
                return;
            }
            
            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
                if (target.getApiVersionNumber() == version) {
                    mSdkTargetSelector.setSelection(target);
                    break;
                }
            }
        } catch (NumberFormatException e) {
            // ignore
        }

        mMinSdkVersionModifiedByUser = true;
    }
    
    /**
     * Called when an SDK target is modified.
     * 
     * If the minSdkVersion field hasn't been modified by the user yet, we change it
     * to reflect the sdk api level that has just been selected.
     */
    private void onSdkTargetModified() {
        IAndroidTarget target = getSdkTarget();
        
        if (target != null && !mMinSdkVersionModifiedByUser) {
            mInternalMinSdkVersionUpdate = true;
            mMinSdkVersionField.setText(Integer.toString(target.getApiVersionNumber()));
            mInternalMinSdkVersionUpdate = false;
        }
    }

    /**
     * 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 (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 (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;
        int minSdkVersion = AndroidManifestParser.INVALID_MIN_SDK;
        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;
                mProjectNameField.setText(activityName);
                mInternalProjectNameUpdate = false;
            }
            if (mApplicationNameField.getText().length() == 0 ||
                    !mApplicationNameModifiedByUser) {
                mInternalApplicationNameUpdate = true;
                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
        boolean foundTarget = false;
        
        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);
            if (target != null) {
                mSdkTargetSelector.setSelection(target);
                foundTarget = true;
            }
        }

        if (!foundTarget && minSdkVersion != AndroidManifestParser.INVALID_MIN_SDK) {
            try {
                for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
                    if (target.getApiVersionNumber() == minSdkVersion) {
                        mSdkTargetSelector.setSelection(target);
                        foundTarget = true;
                        break;
                    }
                }
            } catch(NumberFormatException e) {
                // ignore
            }
        }
        
        if (!foundTarget) {
            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
                if (projectLocation.startsWith(target.getLocation())) {
                    mSdkTargetSelector.setSelection(target);
                    foundTarget = true;
                    break;
                }
            }
        }

        if (!foundTarget) {
            mInternalMinSdkVersionUpdate = true;
            mMinSdkVersionField.setText(
                    minSdkVersion == AndroidManifestParser.INVALID_MIN_SDK ? "" :
                        Integer.toString(minSdkVersion)); //$NON-NLS-1$
            mInternalMinSdkVersionUpdate = false;
        }
    }

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

        int status = validateProjectField(workspace);
        if ((status & MSG_ERROR) == 0) {
            status |= validateLocationPath(workspace);
        }
        if ((status & MSG_ERROR) == 0) {
            status |= validateSdkTarget();
        }
        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 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 projectFieldContents = getProjectName();
        if (projectFieldContents.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(projectFieldContents).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(projectFieldContents, 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);
        }

        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 (isNewProject()) {
            if (!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(getProjectName()).toFile();
                if (dest.exists()) {
                    return setStatus(String.format("There is already a file or directory named \"%1$s\" in the selected location.",
                            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 (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 (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 (getMinSdkVersion().length() == 0) {
            return MSG_NONE;
        }

        int version = AndroidManifestParser.INVALID_MIN_SDK;
        try {
            // If not empty, it must be a valid integer > 0
            version = Integer.parseInt(getMinSdkVersion());
        } catch (NumberFormatException e) {
            // ignore
        }
        
        if (version < 1) {
            return setStatus("Min SDK Version must be an integer > 0.", MSG_ERROR);
        }
                
        if (getSdkTarget() != null && getSdkTarget().getApiVersionNumber() != version) {
            return setStatus("The API level for the selected SDK target does not match the Min SDK version.",
                    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 (!isCreateActivity()) {
            return MSG_NONE;
        }

        // Validate activity field
        String activityFieldContents = 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 = "";
        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 = 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 (isNewProject() || !isCreateActivity()) {
            return MSG_NONE;
        }

        String osTarget = getActivityName();
        
        if (osTarget.indexOf('.') == -1) {
            osTarget = getPackageName() + File.separator + osTarget;
        } else if (osTarget.indexOf('.') == 0) {
            osTarget = 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;
    }

}
