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

import com.android.SdkConstants;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
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.NewProjectWizardState.Mode;
import com.android.sdklib.IAndroidTarget;

import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.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.Label;
import org.eclipse.swt.widgets.Text;

import java.io.File;
import java.io.FileFilter;
import java.net.URI;

/** Page where you choose the application name, activity name, and optional test project info */
public class ApplicationInfoPage extends WizardPage implements SelectionListener, ModifyListener,
        ITargetChangeListener {
    private static final String JDK_15 = "1.5"; //$NON-NLS-1$
    private final static String DUMMY_PACKAGE = "your.package.namespace";

    /** Suffix added by default to activity names */
    static final String ACTIVITY_NAME_SUFFIX = "Activity"; //$NON-NLS-1$

    private final NewProjectWizardState mValues;

    private Text mApplicationText;
    private Text mPackageText;
    private Text mActivityText;
    private Button mCreateActivityCheckbox;
    private Combo mSdkCombo;

    private boolean mIgnore;
    private Button mCreateTestCheckbox;
    private Text mTestProjectNameText;
    private Text mTestApplicationText;
    private Text mTestPackageText;
    private Label mTestProjectNameLabel;
    private Label mTestApplicationLabel;
    private Label mTestPackageLabel;

    /**
     * Create the wizard.
     */
    ApplicationInfoPage(NewProjectWizardState values) {
        super("appInfo"); //$NON-NLS-1$
        mValues = values;

        setTitle("Application Info");
        setDescription("Configure the new Android Project");
        AdtPlugin.getDefault().addTargetListener(this);
    }

    /**
     * Create contents of the wizard.
     */
    @Override
    @SuppressWarnings("unused") // Eclipse marks SWT constructors with side effects as unused
    public void createControl(Composite parent) {
        Composite container = new Composite(parent, SWT.NULL);
        container.setLayout(new GridLayout(2, false));

        Label applicationLabel = new Label(container, SWT.NONE);
        applicationLabel.setText("Application Name:");

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

        Label packageLabel = new Label(container, SWT.NONE);
        packageLabel.setText("Package Name:");

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

        if (mValues.mode != Mode.TEST) {
            mCreateActivityCheckbox = new Button(container, SWT.CHECK);
            mCreateActivityCheckbox.setText("Create Activity:");
            mCreateActivityCheckbox.addSelectionListener(this);

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

        Label minSdkLabel = new Label(container, SWT.NONE);
        minSdkLabel.setText("Minimum SDK:");

        mSdkCombo = new Combo(container, SWT.NONE);
        GridData gdSdkCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
        gdSdkCombo.widthHint = 200;
        mSdkCombo.setLayoutData(gdSdkCombo);
        mSdkCombo.addSelectionListener(this);
        mSdkCombo.addModifyListener(this);

        onSdkLoaded();

        setControl(container);
        new Label(container, SWT.NONE);
        new Label(container, SWT.NONE);

        mCreateTestCheckbox = new Button(container, SWT.CHECK);
        mCreateTestCheckbox.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
        mCreateTestCheckbox.setText("Create a Test Project");
        mCreateTestCheckbox.addSelectionListener(this);

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

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

        mTestApplicationLabel = new Label(container, SWT.NONE);
        mTestApplicationLabel.setText("Test Application:");

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

        mTestPackageLabel = new Label(container, SWT.NONE);
        mTestPackageLabel.setText("Test Package:");

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

    /** Controls whether the options for creating a paired test project should be shown */
    private void showTestOptions(boolean visible) {
        if (mValues.mode == Mode.SAMPLE) {
            visible = false;
        }

        mCreateTestCheckbox.setVisible(visible);
        mTestProjectNameLabel.setVisible(visible);
        mTestProjectNameText.setVisible(visible);
        mTestApplicationLabel.setVisible(visible);
        mTestApplicationText.setVisible(visible);
        mTestPackageLabel.setVisible(visible);
        mTestPackageText.setVisible(visible);
    }

    /** Controls whether the options for creating a paired test project should be enabled */
    private void enableTestOptions(boolean enabled) {
        mTestProjectNameLabel.setEnabled(enabled);
        mTestProjectNameText.setEnabled(enabled);
        mTestApplicationLabel.setEnabled(enabled);
        mTestApplicationText.setEnabled(enabled);
        mTestPackageLabel.setEnabled(enabled);
        mTestPackageText.setEnabled(enabled);
    }

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

        if (visible) {
            try {
                mIgnore = true;
                if (mValues.applicationName != null) {
                    mApplicationText.setText(mValues.applicationName);
                }
                if (mValues.packageName != null) {
                    mPackageText.setText(mValues.packageName);
                } else {
                    mPackageText.setText(DUMMY_PACKAGE);
                }

                if (mValues.mode != Mode.TEST) {
                    mCreateActivityCheckbox.setSelection(mValues.createActivity);
                    mActivityText.setEnabled(mValues.createActivity);
                    if (mValues.activityName != null) {
                        mActivityText.setText(mValues.activityName);
                    }
                }
                if (mValues.minSdk != null && mValues.minSdk.length() > 0) {
                    mSdkCombo.setText(mValues.minSdk);
                }

                showTestOptions(mValues.mode == Mode.ANY);
                enableTestOptions(mCreateTestCheckbox.getSelection());

                if (mValues.testProjectName != null) {
                    mTestProjectNameText.setText(mValues.testProjectName);
                }
                if (mValues.testApplicationName != null) {
                    mTestApplicationText.setText(mValues.testApplicationName);
                }
                if (mValues.testProjectName != null) {
                    mTestPackageText.setText(mValues.testProjectName);
                }
            } finally {
                mIgnore = false;
            }
        }

        // Start focus with the package name, since the other fields are typically assigned
        // reasonable defaults
        mPackageText.setFocus();
        mPackageText.selectAll();

        validatePage();
    }

    protected void setSdkTargets(IAndroidTarget[] targets, IAndroidTarget target) {
        if (targets == null) {
            targets = new IAndroidTarget[0];
        }
        int selectionIndex = -1;
        String[] items = new String[targets.length];
        for (int i = 0, n = targets.length; i < n; i++) {
            items[i] = targetLabel(targets[i]);
            if (targets[i] == target) {
                selectionIndex = i;
            }
        }
        try {
            mIgnore = true;
            mSdkCombo.setItems(items);
            mSdkCombo.setData(targets);
            if (selectionIndex != -1) {
                mSdkCombo.select(selectionIndex);
            }
        } finally {
            mIgnore = false;
        }
    }

    private String targetLabel(IAndroidTarget target) {
        // In the minimum SDK chooser, show the targets with api number and description,
        // such as "11 (Android 3.0)"
        return String.format("%1$s (%2$s)", target.getVersion().getApiString(),
                target.getFullName());
    }

    @Override
    public void dispose() {
        AdtPlugin.getDefault().removeTargetListener(this);
        super.dispose();
    }

    @Override
    public boolean isPageComplete() {
        // This page is only needed when creating new projects
        if (mValues.useExisting || mValues.mode != Mode.ANY) {
            return true;
        }

        // Ensure that we reach this page
        if (mValues.packageName == null) {
            return false;
        }

        return super.isPageComplete();
    }

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

        Object source = e.getSource();
        if (source == mSdkCombo) {
            mValues.minSdk = mSdkCombo.getText().trim();
            IAndroidTarget[] targets = (IAndroidTarget[]) mSdkCombo.getData();
            // An editable combo will treat item selection the same way as a user edit,
            // so we need to see if the string looks like a labeled version
            int index = mSdkCombo.getSelectionIndex();
            if (index != -1) {
                if (index >= 0 && index < targets.length) {
                    IAndroidTarget target = targets[index];
                    if (targetLabel(target).equals(mValues.minSdk)) {
                        mValues.minSdk = target.getVersion().getApiString();
                    }
                }
            }

            // Ensure that we never pick up the (Android x.y) suffix shown in combobox
            // for readability
            int separator = mValues.minSdk.indexOf(' ');
            if (separator != -1) {
                mValues.minSdk = mValues.minSdk.substring(0, separator);
            }
            mValues.minSdkModifiedByUser = true;
            mValues.updateSdkTargetToMatchMinSdkVersion();
        } else if (source == mApplicationText) {
            mValues.applicationName = mApplicationText.getText().trim();
            mValues.applicationNameModifiedByUser = true;

            if (!mValues.testApplicationNameModified) {
                mValues.testApplicationName = suggestTestApplicationName(mValues.applicationName);
                try {
                    mIgnore = true;
                    mTestApplicationText.setText(mValues.testApplicationName);
                } finally {
                    mIgnore = false;
                }
            }

        } else if (source == mPackageText) {
            mValues.packageName = mPackageText.getText().trim();
            mValues.packageNameModifiedByUser = true;

            if (!mValues.testPackageModified) {
                mValues.testPackageName = suggestTestPackage(mValues.packageName);
                try {
                    mIgnore = true;
                    mTestPackageText.setText(mValues.testPackageName);
                } finally {
                    mIgnore = false;
                }
            }
        } else if (source == mActivityText) {
            mValues.activityName = mActivityText.getText().trim();
            mValues.activityNameModifiedByUser = true;
        } else if (source == mTestApplicationText) {
            mValues.testApplicationName = mTestApplicationText.getText().trim();
            mValues.testApplicationNameModified = true;
        } else if (source == mTestPackageText) {
            mValues.testPackageName = mTestPackageText.getText().trim();
            mValues.testPackageModified = true;
        } else if (source == mTestProjectNameText) {
            mValues.testProjectName = mTestProjectNameText.getText().trim();
            mValues.testProjectModified = true;
        }

        validatePage();
    }

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

        Object source = e.getSource();

        if (source == mCreateActivityCheckbox) {
            mValues.createActivity = mCreateActivityCheckbox.getSelection();
            mActivityText.setEnabled(mValues.createActivity);
        } else if (source == mSdkCombo) {
            int index = mSdkCombo.getSelectionIndex();
            IAndroidTarget[] targets = (IAndroidTarget[]) mSdkCombo.getData();
            if (index != -1) {
                if (index >= 0 && index < targets.length) {
                    IAndroidTarget target = targets[index];
                    // Even though we are showing the logical version name, we place the
                    // actual api number as the minimum SDK
                    mValues.minSdk = target.getVersion().getApiString();
                }
            } else {
                String text = mSdkCombo.getText();
                boolean found = false;
                for (IAndroidTarget target : targets) {
                    if (targetLabel(target).equals(text)) {
                        mValues.minSdk = target.getVersion().getApiString();
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    mValues.minSdk = text;
                }
            }
        } else if (source == mCreateTestCheckbox) {
            mValues.createPairProject = mCreateTestCheckbox.getSelection();
            enableTestOptions(mValues.createPairProject);
            if (mValues.createPairProject) {
                if (mValues.testProjectName == null || mValues.testProjectName.length() == 0) {
                    mValues.testProjectName = suggestTestProjectName(mValues.projectName);
                }
                if (mValues.testApplicationName == null ||
                        mValues.testApplicationName.length() == 0) {
                    mValues.testApplicationName =
                            suggestTestApplicationName(mValues.applicationName);
                }
                if (mValues.testPackageName == null || mValues.testPackageName.length() == 0) {
                    mValues.testPackageName = suggestTestPackage(mValues.packageName);
                }

                try {
                    mIgnore = true;
                    mTestProjectNameText.setText(mValues.testProjectName);
                    mTestApplicationText.setText(mValues.testApplicationName);
                    mTestPackageText.setText(mValues.testPackageName);
                } finally {
                    mIgnore = false;
                }
            }
        }

        validatePage();
    }

    @Override
    public void widgetDefaultSelected(SelectionEvent e) {
    }

    private void validatePage() {
        IStatus status = validatePackage(mValues.packageName);
        if (status == null || status.getSeverity() != IStatus.ERROR) {
            IStatus validActivity = validateActivity();
            if (validActivity != null) {
                status = validActivity;
            }
        }
        if (status == null || status.getSeverity() != IStatus.ERROR) {
            IStatus validMinSdk = validateMinSdk();
            if (validMinSdk != null) {
                status = validMinSdk;
            }
        }

        if (status == null || status.getSeverity() != IStatus.ERROR) {
            IStatus validSourceFolder = validateSourceFolder();
            if (validSourceFolder != null) {
                status = validSourceFolder;
            }
        }

        // If creating a test project to go along with the main project, also validate
        // the additional test project parameters
        if (status == null || status.getSeverity() != IStatus.ERROR) {
            if (mValues.createPairProject) {
                IStatus validTestProject = ProjectNamePage.validateProjectName(
                        mValues.testProjectName);
                if (validTestProject != null) {
                    status = validTestProject;
                }

                if (status == null || status.getSeverity() != IStatus.ERROR) {
                    IStatus validTestLocation = validateTestProjectLocation();
                    if (validTestLocation != null) {
                        status = validTestLocation;
                    }
                }

                if (status == null || status.getSeverity() != IStatus.ERROR) {
                    IStatus validTestPackage = validatePackage(mValues.testPackageName);
                    if (validTestPackage != null) {
                        status = new Status(validTestPackage.getSeverity(),
                                AdtPlugin.PLUGIN_ID,
                                validTestPackage.getMessage() + " (in test package)");
                    }
                }

                if (status == null || status.getSeverity() != IStatus.ERROR) {
                    if (mValues.projectName.equals(mValues.testProjectName)) {
                        status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                             "The main project name and the test project name must be different.");
                    }
                }
            }
        }

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

    private IStatus validateTestProjectLocation() {
        assert mValues.createPairProject;

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

        return null;
    }

    private IStatus validateSourceFolder() {
        // This check does nothing when creating a new project.
        // This check is also useless when no activity is present or created.
        mValues.sourceFolder = SdkConstants.FD_SOURCES;
        if (!mValues.useExisting || !mValues.createActivity) {
            return null;
        }

        String osTarget = mValues.activityName;
        if (osTarget.indexOf('.') == -1) {
            osTarget = mValues.packageName + File.separator + osTarget;
        } else if (osTarget.indexOf('.') == 0) {
            osTarget = mValues.packageName + osTarget;
        }
        osTarget = osTarget.replace('.', File.separatorChar) + SdkConstants.DOT_JAVA;

        File projectDir = mValues.projectLocation;
        File[] allDirs = projectDir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.isDirectory();
            }
        });
        if (allDirs != null) {
            boolean found = false;
            for (File f : allDirs) {
                Path path = new Path(f.getAbsolutePath());
                File java_activity = path.append(osTarget).toFile();
                if (java_activity.isFile()) {
                    mValues.sourceFolder = f.getName();
                    found = true;
                    break;
                }
            }

            if (!found) {
                String projectPath = projectDir.getPath();
                if (allDirs.length > 0) {
                    return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                            String.format("%1$s can not be found under %2$s.", osTarget,
                            projectPath));
                } else {
                    return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                            String.format("No source folders can be found in %1$s.",
                            projectPath));
                }
            }
        }

        return null;
    }

    private IStatus validateMinSdk() {
        // Validate min SDK field
        // If the min sdk version is empty, it is always accepted.
        if (mValues.minSdk == null || mValues.minSdk.length() == 0) {
            return null;
        }

        IAndroidTarget target = mValues.target;
        if (target == null) {
            return null;
        }

        // If the current target is a preview, explicitly indicate minSdkVersion
        // must be set to this target name.
        if (target.getVersion().isPreview() && !target.getVersion().equals(mValues.minSdk)) {
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    String.format(
                            "The SDK target is a preview. Min SDK Version must be set to '%s'.",
                            target.getVersion().getCodename()));
        }

        if (!target.getVersion().equals(mValues.minSdk)) {
            return new Status(target.getVersion().isPreview() ? IStatus.ERROR : IStatus.WARNING,
                    AdtPlugin.PLUGIN_ID,
                    "The API level for the selected SDK target does not match the Min SDK Version."
                    );
        }

        return null;
    }

    public static IStatus validatePackage(String packageFieldContents) {
        // Validate package
        if (packageFieldContents == null || packageFieldContents.length() == 0) {
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    "Package name must be specified.");
        } else if (packageFieldContents.equals(DUMMY_PACKAGE)) {
            // The dummy package name is just a placeholder package (which isn't even valid
            // because it contains the reserved Java keyword "package") but we want to
            // make the error message say that a proper package should be entered rather than
            // what's wrong with this specific package. (And the reason we provide a dummy
            // package rather than a blank line is to make it more clear to beginners what
            // we're looking for.
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    "Package name must be specified.");
        }
        // Check it's a valid package string
        IStatus status = JavaConventions.validatePackageName(packageFieldContents, JDK_15,
                JDK_15);
        if (!status.isOK()) {
            return status;
        }

        // 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 (packageFieldContents.indexOf('.') == -1) {
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    "Package name must have at least two identifiers.");
        }

        return null;
    }

    public static IStatus validateClass(String className) {
        if (className == null || className.length() == 0) {
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    "Class name must be specified.");
        }
        if (className.indexOf('.') != -1) {
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    "Enter just a class name, not a full package name");
        }
        return JavaConventions.validateJavaTypeName(className, JDK_15, JDK_15);
    }

    private IStatus validateActivity() {
        // Validate activity (if creating an activity)
        if (!mValues.createActivity) {
            return null;
        }

        return validateActivity(mValues.activityName);
    }

    /**
     * Validates the given activity name
     *
     * @param activityFieldContents the activity name to validate
     * @return a status for whether the activity name is valid
     */
    public static IStatus validateActivity(String activityFieldContents) {
        // Validate activity field
        if (activityFieldContents == null || activityFieldContents.length() == 0) {
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    "Activity name must be specified.");
        } else if (ACTIVITY_NAME_SUFFIX.equals(activityFieldContents)) {
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, "Enter a valid activity name");
        } else if (activityFieldContents.contains("..")) { //$NON-NLS-1$
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    "Package segments in activity name cannot be empty (..)");
        }
        // 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.length() > 0 && activityFieldContents.charAt(0) == '.') {
            activityFieldContents = activityFieldContents.substring(1);
        }

        // Check it's a valid activity string
        IStatus status = JavaConventions.validateTypeVariableName(activityFieldContents, JDK_15,
                JDK_15);
        if (!status.isOK()) {
            return status;
        }

        // Check it's a valid package string
        if (packageName.length() > 0) {
            status = JavaConventions.validatePackageName(packageName, JDK_15, JDK_15);
            if (!status.isOK()) {
                return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                        status.getMessage() + " (in the activity name)");
            }
        }

        return null;
    }

    // ---- Implement ITargetChangeListener ----

    @Override
    public void onSdkLoaded() {
        if (mSdkCombo == null) {
            return;
        }

        // 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();
        }
        setSdkTargets(targets, mValues.target);
    }

    @Override
    public void onProjectTargetChange(IProject changedProject) {
        // Ignore
    }

    @Override
    public void onTargetLoaded(IAndroidTarget target) {
        // Ignore
    }

    public static String suggestTestApplicationName(String applicationName) {
        if (applicationName == null) {
            applicationName = ""; //$NON-NLS-1$
        }
        if (applicationName.indexOf(' ') != -1) {
            return applicationName + " Test"; //$NON-NLS-1$
        } else {
            return applicationName + "Test"; //$NON-NLS-1$
        }
    }

    public static String suggestTestProjectName(String projectName) {
        if (projectName == null) {
            projectName = ""; //$NON-NLS-1$
        }
        if (projectName.length() > 0 && Character.isUpperCase(projectName.charAt(0))) {
            return projectName + "Test"; //$NON-NLS-1$
        } else {
            return projectName + "-test"; //$NON-NLS-1$
        }
    }


    public static String suggestTestPackage(String packagePath) {
        if (packagePath == null) {
            packagePath = ""; //$NON-NLS-1$
        }
        return packagePath + ".test"; //$NON-NLS-1$
    }
}
