/*
 * Copyright (C) 2012 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.templates;


import static com.android.SdkConstants.ATTR_ID;
import static com.android.ide.eclipse.adt.AdtUtils.extractClassName;
import static com.android.ide.eclipse.adt.internal.wizards.templates.NewTemplatePage.WIZARD_PAGE_WIDTH;

import com.android.annotations.Nullable;
import com.android.sdklib.SdkVersionInfo;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.internal.wizards.newproject.ApplicationInfoPage;
import com.android.ide.eclipse.adt.internal.wizards.newproject.ProjectNamePage;
import com.android.sdklib.AndroidVersion;
import com.android.sdklib.IAndroidTarget;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

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.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
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.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * First wizard page in the "New Project From Template" wizard
 */
public class NewProjectPage extends WizardPage
        implements ModifyListener, SelectionListener, FocusListener {
    private static final int FIELD_WIDTH = 300;
    private static final String SAMPLE_PACKAGE_PREFIX = "com.example."; //$NON-NLS-1$
    /** Suffix added by default to activity names */
    static final String ACTIVITY_NAME_SUFFIX = "Activity";              //$NON-NLS-1$
    /** Prefix added to default layout names */
    static final String LAYOUT_NAME_PREFIX = "activity_";               //$NON-NLS-1$
    private static final int INITIAL_MIN_SDK = 8;

    private final NewProjectWizardState mValues;
    private Map<String, Integer> mMinNameToApi;
    private Parameter mThemeParameter;
    private Combo mThemeCombo;

    private Text mProjectText;
    private Text mPackageText;
    private Text mApplicationText;
    private Combo mMinSdkCombo;
    private Combo mTargetSdkCombo;
    private Combo mBuildSdkCombo;
    private Label mHelpIcon;
    private Label mTipLabel;

    private boolean mIgnore;
    private ControlDecoration mApplicationDec;
    private ControlDecoration mProjectDec;
    private ControlDecoration mPackageDec;
    private ControlDecoration mBuildTargetDec;
    private ControlDecoration mMinSdkDec;
    private ControlDecoration mTargetSdkDec;
    private ControlDecoration mThemeDec;

    NewProjectPage(NewProjectWizardState values) {
        super("newAndroidApp"); //$NON-NLS-1$
        mValues = values;
        setTitle("New Android Application");
        setDescription("Creates a new Android Application");
    }

    @SuppressWarnings("unused") // SWT constructors have side effects and aren't unused
    @Override
    public void createControl(Composite parent) {
        Composite container = new Composite(parent, SWT.NULL);
        setControl(container);
        GridLayout gl_container = new GridLayout(4, false);
        gl_container.horizontalSpacing = 10;
        container.setLayout(gl_container);

        Label applicationLabel = new Label(container, SWT.NONE);
        applicationLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1));
        applicationLabel.setText("Application Name:");

        mApplicationText = new Text(container, SWT.BORDER);
        GridData gdApplicationText = new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1);
        gdApplicationText.widthHint = FIELD_WIDTH;
        mApplicationText.setLayoutData(gdApplicationText);
        mApplicationText.addModifyListener(this);
        mApplicationText.addFocusListener(this);
        mApplicationDec = createFieldDecoration(mApplicationText,
                "The application name is shown in the Play Store, as well as in the " +
                "Manage Application list in Settings.");

        Label projectLabel = new Label(container, SWT.NONE);
        projectLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1));
        projectLabel.setText("Project Name:");
        mProjectText = new Text(container, SWT.BORDER);
        GridData gdProjectText = new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1);
        gdProjectText.widthHint = FIELD_WIDTH;
        mProjectText.setLayoutData(gdProjectText);
        mProjectText.addModifyListener(this);
        mProjectText.addFocusListener(this);
        mProjectDec = createFieldDecoration(mProjectText,
                "The project name is only used by Eclipse, but must be unique within the " +
                "workspace. This can typically be the same as the application name.");

        Label packageLabel = new Label(container, SWT.NONE);
        packageLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1));
        packageLabel.setText("Package Name:");

        mPackageText = new Text(container, SWT.BORDER);
        GridData gdPackageText = new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1);
        gdPackageText.widthHint = FIELD_WIDTH;
        mPackageText.setLayoutData(gdPackageText);
        mPackageText.addModifyListener(this);
        mPackageText.addFocusListener(this);
        mPackageDec = createFieldDecoration(mPackageText,
                "The package name must be a unique identifier for your application.\n" +
                "It is typically not shown to users, but it *must* stay the same " +
                "for the lifetime of your application; it is how multiple versions " +
                "of the same application are considered the \"same app\".\nThis is " +
                "typically the reverse domain name of your organization plus one or " +
                "more application identifiers, and it must be a valid Java package " +
                "name.");
        new Label(container, SWT.NONE);

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

        // Min SDK

        Label minSdkLabel = new Label(container, SWT.NONE);
        minSdkLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1));
        minSdkLabel.setText("Minimum Required SDK:");

        mMinSdkCombo = new Combo(container, SWT.READ_ONLY);
        GridData gdMinSdkCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
        gdMinSdkCombo.widthHint = FIELD_WIDTH;
        mMinSdkCombo.setLayoutData(gdMinSdkCombo);

        // Pick most recent platform
        IAndroidTarget[] targets = getCompilationTargets();
        mMinNameToApi = Maps.newHashMap();
        List<String> targetLabels = new ArrayList<String>(targets.length);
        for (IAndroidTarget target : targets) {
            String targetLabel;
            if (target.isPlatform()
                    && target.getVersion().getApiLevel() <= AdtUtils.getHighestKnownApiLevel()) {
                targetLabel = AdtUtils.getAndroidName(target.getVersion().getApiLevel());
            } else {
                targetLabel = AdtUtils.getTargetLabel(target);
            }
            targetLabels.add(targetLabel);
            mMinNameToApi.put(targetLabel, target.getVersion().getApiLevel());
        }

        List<String> codeNames = Lists.newArrayList();
        int buildTargetIndex = -1;
        for (int i = 0, n = targets.length; i < n; i++) {
            IAndroidTarget target = targets[i];
            AndroidVersion version = target.getVersion();
            int apiLevel = version.getApiLevel();
            if (version.isPreview()) {
                String codeName = version.getCodename();
                String targetLabel = codeName + " Preview";
                codeNames.add(targetLabel);
                mMinNameToApi.put(targetLabel, apiLevel);
            } else if (target.isPlatform()
                    && (mValues.target == null ||
                        apiLevel > mValues.target.getVersion().getApiLevel())) {
                mValues.target = target;
                buildTargetIndex = i;
            }
        }
        List<String> labels = new ArrayList<String>(24);
        for (String label : AdtUtils.getKnownVersions()) {
            labels.add(label);
        }
        assert labels.size() >= 15; // *Known* versions to ADT, not installed/available versions
        for (String codeName : codeNames) {
            labels.add(codeName);
        }
        String[] versions = labels.toArray(new String[labels.size()]);
        mMinSdkCombo.setItems(versions);
        if (mValues.target != null && mValues.target.getVersion().isPreview()) {
            mValues.minSdk = mValues.target.getVersion().getCodename();
            mMinSdkCombo.setText(mValues.minSdk);
            mValues.iconState.minSdk = mValues.target.getVersion().getApiLevel();
            mValues.minSdkLevel = mValues.iconState.minSdk;
        } else {
            mMinSdkCombo.select(INITIAL_MIN_SDK - 1);
            mValues.minSdk = Integer.toString(INITIAL_MIN_SDK);
            mValues.minSdkLevel = INITIAL_MIN_SDK;
            mValues.iconState.minSdk = INITIAL_MIN_SDK;
        }
        mMinSdkCombo.addSelectionListener(this);
        mMinSdkCombo.addFocusListener(this);
        mMinSdkDec = createFieldDecoration(mMinSdkCombo,
                "Choose the lowest version of Android that your application will support. Lower " +
                "API levels target more devices, but means fewer features are available. By " +
                "targeting API 8 and later, you reach approximately 95% of the market.");
        new Label(container, SWT.NONE);

        // Target SDK
        Label targetSdkLabel = new Label(container, SWT.NONE);
        targetSdkLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1));
        targetSdkLabel.setText("Target SDK:");

        mTargetSdkCombo = new Combo(container, SWT.READ_ONLY);
        GridData gdTargetSdkCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
        gdTargetSdkCombo.widthHint = FIELD_WIDTH;
        mTargetSdkCombo.setLayoutData(gdTargetSdkCombo);

        mTargetSdkCombo.setItems(versions);
        mTargetSdkCombo.select(mValues.targetSdkLevel - 1);

        mTargetSdkCombo.addSelectionListener(this);
        mTargetSdkCombo.addFocusListener(this);
        mTargetSdkDec = createFieldDecoration(mTargetSdkCombo,
                "Choose the highest API level that the application is known to work with. " +
                "This attribute informs the system that you have tested against the target " +
                "version and the system should not enable any compatibility behaviors to " +
                "maintain your app's forward-compatibility with the target version. " +
                "The application is still able to run on older versions " +
                "(down to minSdkVersion). Your application may look dated if you are not " +
                "targeting the current version.");
        new Label(container, SWT.NONE);

        // Build Version

        Label buildSdkLabel = new Label(container, SWT.NONE);
        buildSdkLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1));
        buildSdkLabel.setText("Compile With:");

        mBuildSdkCombo = new Combo(container, SWT.READ_ONLY);
        GridData gdBuildSdkCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
        gdBuildSdkCombo.widthHint = FIELD_WIDTH;
        mBuildSdkCombo.setLayoutData(gdBuildSdkCombo);
        mBuildSdkCombo.setData(targets);
        mBuildSdkCombo.setItems(targetLabels.toArray(new String[targetLabels.size()]));
        if (buildTargetIndex != -1) {
            mBuildSdkCombo.select(buildTargetIndex);
        }

        mBuildSdkCombo.addSelectionListener(this);
        mBuildSdkCombo.addFocusListener(this);
        mBuildTargetDec = createFieldDecoration(mBuildSdkCombo,
                "Choose a target API to compile your code against, from your installed SDKs. " +
                "This is typically the most recent version, or the first version that supports " +
                "all the APIs you want to directly access without reflection.");
        new Label(container, SWT.NONE);

        TemplateMetadata metadata = mValues.template.getTemplate();
        if (metadata != null) {
            mThemeParameter = metadata.getParameter("baseTheme"); //$NON-NLS-1$
            if (mThemeParameter != null && mThemeParameter.element != null) {
                Label themeLabel = new Label(container, SWT.NONE);
                themeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 2, 1));
                themeLabel.setText("Theme:");

                mThemeCombo = NewTemplatePage.createOptionCombo(mThemeParameter, container,
                        mValues.parameters, this, this);
                GridData gdThemeCombo = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
                gdThemeCombo.widthHint = FIELD_WIDTH;
                mThemeCombo.setLayoutData(gdThemeCombo);
                new Label(container, SWT.NONE);

                mThemeDec = createFieldDecoration(mThemeCombo,
                        "Choose the base theme to use for the application");
            }
        }

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

        Label label = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
        label.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 4, 1));

        mHelpIcon = new Label(container, SWT.NONE);
        mHelpIcon.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1));
        Image icon = IconFactory.getInstance().getIcon("quickfix");
        mHelpIcon.setImage(icon);
        mHelpIcon.setVisible(false);

        mTipLabel = new Label(container, SWT.WRAP);
        mTipLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));

        // Reserve space for 4 lines
        mTipLabel.setText("\n\n\n\n"); //$NON-NLS-1$

        // Reserve enough width to accommodate the various wizard pages up front
        // (since they are created lazily, and we don't want the wizard to dynamically
        // resize itself for small size adjustments as each successive page is slightly
        // larger)
        Label dummy = new Label(container, SWT.NONE);
        GridData data = new GridData();
        data.horizontalSpan = 4;
        data.widthHint = WIZARD_PAGE_WIDTH;
        dummy.setLayoutData(data);
    }

    /**
     * Updates the theme selection such that it's valid for the current build
     * and min sdk targets. Also runs {@link #validatePage} in case no valid entry was found.
     * Does nothing if called on a template that does not supply a theme.
     */
    void updateTheme() {
        if (mThemeParameter != null) {
            // Pick the highest theme version that works for the current SDK level
            Parameter parameter = NewTemplatePage.getParameter(mThemeCombo);
            assert parameter == mThemeParameter;
            if (parameter != null) {
                String[] optionIds = (String[]) mThemeCombo.getData(ATTR_ID);
                for (int index = optionIds.length - 1; index >= 0; index--) {
                    IStatus status = NewTemplatePage.validateCombo(null, mThemeParameter,
                            index, mValues.minSdkLevel, mValues.getBuildApi());
                    if (status == null || status.isOK()) {
                        String optionId = optionIds[index];
                        parameter.value = optionId;
                        parameter.edited = optionId != null && !optionId.toString().isEmpty();
                        mValues.parameters.put(parameter.id, optionId);
                        try {
                            mIgnore = true;
                            mThemeCombo.select(index);
                        } finally {
                            mIgnore = false;
                        }
                        break;
                    }
                }
            }

            validatePage();
        }
    }

    private IAndroidTarget[] getCompilationTargets() {
        Sdk current = Sdk.getCurrent();
        if (current == null) {
            return new IAndroidTarget[0];
        }
        IAndroidTarget[] targets = current.getTargets();
        List<IAndroidTarget> list = new ArrayList<IAndroidTarget>();

        for (IAndroidTarget target : targets) {
            if (target.isPlatform() == false &&
                    (target.getOptionalLibraries() == null ||
                            target.getOptionalLibraries().length == 0)) {
                continue;
            }
            list.add(target);
        }

        return list.toArray(new IAndroidTarget[list.size()]);
    }

    private ControlDecoration createFieldDecoration(Control control, String description) {
        ControlDecoration dec = new ControlDecoration(control, SWT.LEFT);
        dec.setMarginWidth(2);
        FieldDecoration errorFieldIndicator = FieldDecorationRegistry.getDefault().
           getFieldDecoration(FieldDecorationRegistry.DEC_INFORMATION);
        dec.setImage(errorFieldIndicator.getImage());
        dec.setDescriptionText(description);
        control.setToolTipText(description);

        return dec;
    }

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

        // DURING DEVELOPMENT ONLY
        //if (assertionsEnabled()) {
        //    String uniqueProjectName = AdtUtils.getUniqueProjectName("Test", "");
        //    mProjectText.setText(uniqueProjectName);
        //    mPackageText.setText("test.pkg");
        //}

        validatePage();
    }

    // ---- Implements ModifyListener ----

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

        Object source = e.getSource();
        if (source == mProjectText) {
            mValues.projectName = mProjectText.getText();
            updateProjectLocation(mValues.projectName);
            mValues.projectModified = true;

            try {
                mIgnore = true;
                if (!mValues.applicationModified) {
                    mValues.applicationName = mValues.projectName;
                    mApplicationText.setText(mValues.projectName);
                }
                updateActivityNames(mValues.projectName);
            } finally {
                mIgnore = false;
            }
            suggestPackage(mValues.projectName);
        } else if (source == mPackageText) {
            mValues.packageName = mPackageText.getText();
            mValues.packageModified = true;
        } else if (source == mApplicationText) {
            mValues.applicationName = mApplicationText.getText();
            mValues.applicationModified = true;

            try {
                mIgnore = true;
                if (!mValues.projectModified) {
                    mValues.projectName = appNameToProjectName(mValues.applicationName);
                    mProjectText.setText(mValues.projectName);
                    updateProjectLocation(mValues.projectName);
                }
                updateActivityNames(mValues.applicationName);
            } finally {
                mIgnore = false;
            }
            suggestPackage(mValues.applicationName);
        }

        validatePage();
    }

    private String appNameToProjectName(String appName) {
        // Strip out whitespace (and capitalize subsequent words where spaces were removed
        boolean upcaseNext = false;
        StringBuilder sb = new StringBuilder(appName.length());
        for (int i = 0, n = appName.length(); i < n; i++) {
            char c = appName.charAt(i);
            if (c == ' ') {
                upcaseNext = true;
            } else if (upcaseNext) {
                sb.append(Character.toUpperCase(c));
                upcaseNext = false;
            } else {
                sb.append(c);
            }
        }

        appName = sb.toString().trim();

        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        IStatus nameStatus = workspace.validateName(appName, IResource.PROJECT);
        if (nameStatus.isOK()) {
            return appName;
        }

        sb = new StringBuilder(appName.length());
        for (int i = 0, n = appName.length(); i < n; i++) {
            char c = appName.charAt(i);
            if (Character.isLetterOrDigit(c) || c == '.' || c == '-') {
                sb.append(c);
            }
        }

        return sb.toString().trim();
    }

    /** If the project should be created in the workspace, then update the project location
     * based on the project name. */
    private void updateProjectLocation(String projectName) {
        if (projectName == null) {
            projectName = "";
        }

        if (mValues.useDefaultLocation) {
            IPath workspace = Platform.getLocation();
            String projectLocation = workspace.append(projectName).toOSString();
            mValues.projectLocation = projectLocation;
        }
    }

    private void updateActivityNames(String name) {
        try {
            mIgnore = true;
            if (!mValues.activityNameModified) {
                mValues.activityName = extractClassName(name) + ACTIVITY_NAME_SUFFIX;
            }
            if (!mValues.activityTitleModified) {
                mValues.activityTitle = name;
            }
        } finally {
            mIgnore = false;
        }
    }

    // ---- Implements SelectionListener ----

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

        Object source = e.getSource();
        if (source == mMinSdkCombo) {
            mValues.minSdk = getSelectedMinSdk();
            Integer minSdk = mMinNameToApi.get(mValues.minSdk);
            if (minSdk == null) {
                try {
                    minSdk = Integer.parseInt(mValues.minSdk);
                } catch (NumberFormatException nufe) {
                    // If not a number, then the string is a codename, so treat it
                    // as a preview version.
                    minSdk = SdkVersionInfo.HIGHEST_KNOWN_API + 1;
                }
            }
            mValues.iconState.minSdk = minSdk.intValue();
            mValues.minSdkLevel = minSdk.intValue();

            // If higher than build target, adjust build target
            if (mValues.minSdkLevel > mValues.getBuildApi()) {
                // Try to find a build target with an adequate build API
                IAndroidTarget[] targets = (IAndroidTarget[]) mBuildSdkCombo.getData();
                IAndroidTarget best = null;
                int bestApi = Integer.MAX_VALUE;
                int bestTargetIndex = -1;
                for (int i = 0; i < targets.length; i++) {
                    IAndroidTarget target = targets[i];
                    if (!target.isPlatform()) {
                        continue;
                    }
                    int api = target.getVersion().getApiLevel();
                    if (api >= mValues.minSdkLevel && api < bestApi) {
                        best = target;
                        bestApi = api;
                        bestTargetIndex = i;
                    }
                }

                if (best != null) {
                    assert bestTargetIndex != -1;
                    mValues.target = best;
                    try {
                        mIgnore = true;
                        mBuildSdkCombo.select(bestTargetIndex);
                    } finally {
                        mIgnore = false;
                    }
                }
            }

            // If higher than targetSdkVersion, adjust targetSdkVersion
            if (mValues.minSdkLevel > mValues.targetSdkLevel) {
                mValues.targetSdkLevel = mValues.minSdkLevel;
                try {
                    mIgnore = true;
                    setSelectedTargetSdk(mValues.targetSdkLevel);
                } finally {
                    mIgnore = false;
                }
            }
        } else if (source == mBuildSdkCombo) {
            mValues.target = getSelectedBuildTarget();

            // If lower than min sdk target, adjust min sdk target
            if (mValues.target.getVersion().isPreview()) {
                mValues.minSdk = mValues.target.getVersion().getCodename();
                try {
                    mIgnore = true;
                    mMinSdkCombo.setText(mValues.minSdk);
                } finally {
                    mIgnore = false;
                }
            } else {
                String minSdk = mValues.minSdk;
                int buildApiLevel = mValues.target.getVersion().getApiLevel();
                if (minSdk != null && !minSdk.isEmpty()
                        && Character.isDigit(minSdk.charAt(0))
                        && buildApiLevel < Integer.parseInt(minSdk)) {
                    mValues.minSdk = Integer.toString(buildApiLevel);
                    try {
                        mIgnore = true;
                        setSelectedMinSdk(buildApiLevel);
                    } finally {
                        mIgnore = false;
                    }
                }
            }
        } else if (source == mTargetSdkCombo) {
            mValues.targetSdkLevel = getSelectedTargetSdk();
        }

        validatePage();
    }

    private String getSelectedMinSdk() {
        // If you're using a preview build, such as android-JellyBean, you have
        // to use the codename, e.g. JellyBean, as the minimum SDK as well.
        IAndroidTarget buildTarget = getSelectedBuildTarget();
        if (buildTarget != null && buildTarget.getVersion().isPreview()) {
            return buildTarget.getVersion().getCodename();
        }

        // +1: First API level (at index 0) is 1
        return Integer.toString(mMinSdkCombo.getSelectionIndex() + 1);
    }

    private int getSelectedTargetSdk() {
        // +1: First API level (at index 0) is 1
        return mTargetSdkCombo.getSelectionIndex() + 1;
    }

    private void setSelectedMinSdk(int api) {
        mMinSdkCombo.select(api - 1); // -1: First API level (at index 0) is 1
    }

    private void setSelectedTargetSdk(int api) {
        mTargetSdkCombo.select(api - 1); // -1: First API level (at index 0) is 1
    }

    @Nullable
    private IAndroidTarget getSelectedBuildTarget() {
        IAndroidTarget[] targets = (IAndroidTarget[]) mBuildSdkCombo.getData();
        int index = mBuildSdkCombo.getSelectionIndex();
        if (index >= 0 && index < targets.length) {
            return targets[index];
        } else {
            return null;
        }
    }

    private void suggestPackage(String original) {
        if (!mValues.packageModified) {
            // Create default package name
            StringBuilder sb = new StringBuilder();
            sb.append(SAMPLE_PACKAGE_PREFIX);
            appendPackage(sb, original);

            String pkg = sb.toString();
            if (pkg.endsWith(".")) { //$NON-NLS-1$
                pkg = pkg.substring(0, pkg.length() - 1);
            }
            mValues.packageName = pkg;
            try {
                mIgnore = true;
                mPackageText.setText(mValues.packageName);
            } finally {
                mIgnore = false;
            }
        }
    }

    private static void appendPackage(StringBuilder sb, String string) {
        for (int i = 0, n = string.length(); i < n; i++) {
            char c = string.charAt(i);
            if (i == 0 && Character.isJavaIdentifierStart(c)
                    || i != 0 && Character.isJavaIdentifierPart(c)) {
                sb.append(Character.toLowerCase(c));
            } else if ((c == '.')
                    && (sb.length() > 0 && sb.charAt(sb.length() - 1) != '.')) {
                sb.append('.');
            } else if (c == '-') {
                sb.append('_');
            }
        }
    }

    @Override
    public void widgetDefaultSelected(SelectionEvent e) {
    }

    // ---- Implements FocusListener ----

    @Override
    public void focusGained(FocusEvent e) {
        Object source = e.getSource();
        String tip = "";
        if (source == mApplicationText) {
            tip = mApplicationDec.getDescriptionText();
        } else if (source == mProjectText) {
            tip = mProjectDec.getDescriptionText();
        } else if (source == mBuildSdkCombo) {
            tip = mBuildTargetDec.getDescriptionText();
        } else if (source == mMinSdkCombo) {
            tip = mMinSdkDec.getDescriptionText();
        } else if (source == mPackageText) {
            tip = mPackageDec.getDescriptionText();
            if (mPackageText.getText().startsWith(SAMPLE_PACKAGE_PREFIX)) {
                int length = SAMPLE_PACKAGE_PREFIX.length();
                if (mPackageText.getText().length() > length
                        && SAMPLE_PACKAGE_PREFIX.endsWith(".")) { //$NON-NLS-1$
                    length--;
                }
                mPackageText.setSelection(0, length);
            }
        } else if (source == mTargetSdkCombo) {
            tip = mTargetSdkDec.getDescriptionText();
        } else if (source == mThemeCombo) {
            tip = mThemeDec.getDescriptionText();
        }
        mTipLabel.setText(tip);
        mHelpIcon.setVisible(tip.length() > 0);
    }

    @Override
    public void focusLost(FocusEvent e) {
        mTipLabel.setText("");
        mHelpIcon.setVisible(false);
    }

    // Validation

    private void validatePage() {
        IStatus status = mValues.template.validateTemplate(mValues.minSdkLevel,
                mValues.getBuildApi());
        if (status != null && !status.isOK()) {
            updateDecorator(mApplicationDec, null, true);
            updateDecorator(mPackageDec, null, true);
            updateDecorator(mProjectDec, null, true);
            updateDecorator(mThemeDec, null, true);
            /* These never get marked with errors:
            updateDecorator(mBuildTargetDec, null, true);
            updateDecorator(mMinSdkDec, null, true);
            updateDecorator(mTargetSdkDec, null, true);
            */
        } else {
            IStatus appStatus = validateAppName();
            if (appStatus != null && (status == null
                    || appStatus.getSeverity() > status.getSeverity())) {
                status = appStatus;
            }

            IStatus projectStatus = validateProjectName();
            if (projectStatus != null && (status == null
                    || projectStatus.getSeverity() > status.getSeverity())) {
                status = projectStatus;
            }

            IStatus packageStatus = validatePackageName();
            if (packageStatus != null && (status == null
                    || packageStatus.getSeverity() > status.getSeverity())) {
                status = packageStatus;
            }

            IStatus locationStatus = ProjectContentsPage.validateLocationInWorkspace(mValues);
            if (locationStatus != null && (status == null
                    || locationStatus.getSeverity() > status.getSeverity())) {
                status = locationStatus;
            }

            if (status == null || status.getSeverity() != IStatus.ERROR) {
                if (mValues.target == null) {
                    status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID,
                            "Select an Android build target version");
                }
            }

            if (status == null || status.getSeverity() != IStatus.ERROR) {
                if (mValues.minSdk == null || mValues.minSdk.isEmpty()) {
                    status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID,
                            "Select a minimum SDK version");
                } else {
                    AndroidVersion version = mValues.target.getVersion();
                    if (version.isPreview()) {
                        if (version.getCodename().equals(mValues.minSdk) == false) {
                            status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                            "Preview platforms require the min SDK version to match their codenames.");
                       }
                    } else if (mValues.target.getVersion().compareTo(
                            mValues.minSdkLevel,
                            version.isPreview() ? mValues.minSdk : null) < 0) {
                        status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID,
                            "The minimum SDK version is higher than the build target version");
                    }
                    if (status == null || status.getSeverity() != IStatus.ERROR) {
                        if (mValues.targetSdkLevel < mValues.minSdkLevel) {
                            status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                                "The target SDK version should be at least as high as the minimum SDK version");
                        }
                    }
                }
            }

            IStatus themeStatus = validateTheme();
            if (themeStatus != null && (status == null
                    || themeStatus.getSeverity() > status.getSeverity())) {
                status = themeStatus;
            }
        }

        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 validateAppName() {
        String appName = mValues.applicationName;
        IStatus status = null;
        if (appName == null || appName.isEmpty()) {
            status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    "Enter an application name (shown in launcher)");
        } else if (Character.isLowerCase(mValues.applicationName.charAt(0))) {
            status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID,
                    "The application name for most apps begins with an uppercase letter");
        }

        updateDecorator(mApplicationDec, status, true);

        return status;
    }

    private IStatus validateProjectName() {
        IStatus status = ProjectNamePage.validateProjectName(mValues.projectName);
        updateDecorator(mProjectDec, status, true);

        return status;
    }

    private IStatus validatePackageName() {
        IStatus status;
        if (mValues.packageName == null || mValues.packageName.startsWith(SAMPLE_PACKAGE_PREFIX)) {
            if (mValues.packageName != null
                    && !mValues.packageName.equals(SAMPLE_PACKAGE_PREFIX)) {
                status = ApplicationInfoPage.validatePackage(mValues.packageName);
                if (status == null || status.isOK()) {
                    status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID,
                        String.format("The prefix '%1$s' is meant as a placeholder and should " +
                                      "not be used", SAMPLE_PACKAGE_PREFIX));
                }
            } else {
                status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                        "Package name must be specified.");
            }
        } else {
            status = ApplicationInfoPage.validatePackage(mValues.packageName);
        }

        updateDecorator(mPackageDec, status, true);

        return status;
    }

    private IStatus validateTheme() {
        IStatus status = null;

        if (mThemeParameter != null) {
            status = NewTemplatePage.validateCombo(null, mThemeParameter,
                    mThemeCombo.getSelectionIndex(),  mValues.minSdkLevel,
                    mValues.getBuildApi());

            updateDecorator(mThemeDec, status, true);
        }

        return status;
    }

    private void updateDecorator(ControlDecoration decorator, IStatus status, boolean hasInfo) {
        if (hasInfo) {
            int severity = status != null ? status.getSeverity() : IStatus.OK;
            setDecoratorType(decorator, severity);
        } else {
            if (status == null || status.isOK()) {
                decorator.hide();
            } else {
                decorator.show();
            }
        }
    }

    private void setDecoratorType(ControlDecoration decorator, int severity) {
        String id;
        if (severity == IStatus.ERROR) {
            id = FieldDecorationRegistry.DEC_ERROR;
        } else if (severity == IStatus.WARNING) {
            id = FieldDecorationRegistry.DEC_WARNING;
        } else {
            id = FieldDecorationRegistry.DEC_INFORMATION;
        }
        FieldDecoration errorFieldIndicator = FieldDecorationRegistry.getDefault().
                getFieldDecoration(id);
        decorator.setImage(errorFieldIndicator.getImage());
    }
}
