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

import static com.android.SdkConstants.DOT_XML;
import static com.android.SdkConstants.HORIZONTAL_SCROLL_VIEW;
import static com.android.SdkConstants.LINEAR_LAYOUT;
import static com.android.SdkConstants.RES_QUALIFIER_SEP;
import static com.android.SdkConstants.SCROLL_VIEW;
import static com.android.SdkConstants.VALUE_FILL_PARENT;
import static com.android.SdkConstants.VALUE_MATCH_PARENT;
import static com.android.ide.eclipse.adt.AdtConstants.WS_SEP_CHAR;
import static com.android.ide.eclipse.adt.internal.wizards.newxmlfile.ChooseConfigurationPage.RES_FOLDER_ABS;

import com.android.SdkConstants;
import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.ide.common.resources.configuration.ResourceQualifier;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper;
import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper.ProjectCombo;
import com.android.ide.eclipse.adt.internal.resources.ResourceNameValidator;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.internal.sdk.Sdk.TargetChangeListener;
import com.android.resources.ResourceFolderType;
import com.android.sdklib.IAndroidTarget;
import com.android.utils.Pair;
import com.android.utils.SdkUtils;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
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.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

/**
 * This is the first page of the {@link NewXmlFileWizard} which provides the ability to create
 * skeleton XML resources files for Android projects.
 * <p/>
 * This page is used to select the project, resource type and file name.
 */
class NewXmlFileCreationPage extends WizardPage {

    @Override
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        // Ensure the initial focus is in the Name field; you usually don't need
        // to edit the default text field (the project name)
        if (visible && mFileNameTextField != null) {
            mFileNameTextField.setFocus();
        }

        validatePage();
    }

    /**
     * Information on one type of resource that can be created (e.g. menu, pref, layout, etc.)
     */
    static class TypeInfo {
        private final String mUiName;
        private final ResourceFolderType mResFolderType;
        private final String mTooltip;
        private final Object mRootSeed;
        private ArrayList<String> mRoots = new ArrayList<String>();
        private final String mXmlns;
        private final String mDefaultAttrs;
        private final String mDefaultRoot;
        private final int mTargetApiLevel;

        public TypeInfo(String uiName,
                        String tooltip,
                        ResourceFolderType resFolderType,
                        Object rootSeed,
                        String defaultRoot,
                        String xmlns,
                        String defaultAttrs,
                        int targetApiLevel) {
            mUiName = uiName;
            mResFolderType = resFolderType;
            mTooltip = tooltip;
            mRootSeed = rootSeed;
            mDefaultRoot = defaultRoot;
            mXmlns = xmlns;
            mDefaultAttrs = defaultAttrs;
            mTargetApiLevel = targetApiLevel;
        }

        /** Returns the UI name for the resource type. Unique. Never null. */
        String getUiName() {
            return mUiName;
        }

        /** Returns the tooltip for the resource type. Can be null. */
        String getTooltip() {
            return mTooltip;
        }

        /**
         * Returns the name of the {@link ResourceFolderType}.
         * Never null but not necessarily unique,
         * e.g. two types use  {@link ResourceFolderType#XML}.
         */
        String getResFolderName() {
            return mResFolderType.getName();
        }

        /**
         * Returns the matching {@link ResourceFolderType}.
         * Never null but not necessarily unique,
         * e.g. two types use  {@link ResourceFolderType#XML}.
         */
        ResourceFolderType getResFolderType() {
            return mResFolderType;
        }

        /**
         * Returns the seed used to fill the root element values.
         * The seed might be either a String, a String array, an {@link ElementDescriptor},
         * a {@link DocumentDescriptor} or null.
         */
        Object getRootSeed() {
            return mRootSeed;
        }

        /**
         * Returns the default root element that should be selected by default. Can be
         * null.
         *
         * @param project the associated project, or null if not known
         */
        String getDefaultRoot(IProject project) {
            return mDefaultRoot;
        }

        /**
         * Returns the list of all possible root elements for the resource type.
         * This can be an empty ArrayList but not null.
         * <p/>
         * TODO: the root list SHOULD depend on the currently selected project, to include
         * custom classes.
         */
        ArrayList<String> getRoots() {
            return mRoots;
        }

        /**
         * If the generated resource XML file requires an "android" XMLNS, this should be set
         * to {@link SdkConstants#NS_RESOURCES}. When it is null, no XMLNS is generated.
         */
        String getXmlns() {
            return mXmlns;
        }

        /**
         * When not null, this represent extra attributes that must be specified in the
         * root element of the generated XML file. When null, no extra attributes are inserted.
         *
         * @param project the project to get the attributes for
         * @param root the selected root element string, never null
         */
        String getDefaultAttrs(IProject project, String root) {
            return mDefaultAttrs;
        }

        /**
         * When not null, represents an extra string that should be written inside
         * the element when constructed
         *
         * @param project the project to get the child content for
         * @param root the chosen root element
         * @return a string to be written inside the root element, or null if nothing
         */
        String getChild(IProject project, String root) {
            return null;
        }

        /**
         * The minimum API level required by the current SDK target to support this feature.
         *
         * @return the minimum API level
         */
        public int getTargetApiLevel() {
            return mTargetApiLevel;
        }
    }

    /**
     * TypeInfo, information for each "type" of file that can be created.
     */
    private static final TypeInfo[] sTypes = {
        new TypeInfo(
                "Layout",                                                   // UI name
                "An XML file that describes a screen layout.",              // tooltip
                ResourceFolderType.LAYOUT,                                  // folder type
                AndroidTargetData.DESCRIPTOR_LAYOUT,                        // root seed
                LINEAR_LAYOUT,                                              // default root
                SdkConstants.NS_RESOURCES,                                  // xmlns
                "",                                                         // not used, see below
                1                                                           // target API level
                ) {

                @Override
                String getDefaultRoot(IProject project) {
                    // TODO: Use GridLayout by default for new SDKs
                    // (when we've ironed out all the usability issues)
                    //Sdk currentSdk = Sdk.getCurrent();
                    //if (project != null && currentSdk != null) {
                    //    IAndroidTarget target = currentSdk.getTarget(project);
                    //    // fill_parent was renamed match_parent in API level 8
                    //    if (target != null && target.getVersion().getApiLevel() >= 13) {
                    //        return GRID_LAYOUT;
                    //    }
                    //}

                    return LINEAR_LAYOUT;
                };

                // The default attributes must be determined dynamically since whether
                // we use match_parent or fill_parent depends on the API level of the
                // project
                @Override
                String getDefaultAttrs(IProject project, String root) {
                    Sdk currentSdk = Sdk.getCurrent();
                    String fill = VALUE_FILL_PARENT;
                    if (currentSdk != null) {
                        IAndroidTarget target = currentSdk.getTarget(project);
                        // fill_parent was renamed match_parent in API level 8
                        if (target != null && target.getVersion().getApiLevel() >= 8) {
                            fill = VALUE_MATCH_PARENT;
                        }
                    }

                    // Only set "vertical" orientation of LinearLayouts by default;
                    // for GridLayouts for example we want to rely on the real default
                    // of the layout
                    String size = String.format(
                            "android:layout_width=\"%1$s\"\n"        //$NON-NLS-1$
                            + "android:layout_height=\"%2$s\"",        //$NON-NLS-1$
                            fill, fill);
                    if (LINEAR_LAYOUT.equals(root)) {
                        return "android:orientation=\"vertical\"\n" + size; //$NON-NLS-1$
                    } else {
                        return size;
                    }
                }

                @Override
                String getChild(IProject project, String root) {
                    // Create vertical linear layouts inside new scroll views
                    if (SCROLL_VIEW.equals(root) || HORIZONTAL_SCROLL_VIEW.equals(root)) {
                        return "    <LinearLayout "         //$NON-NLS-1$
                            + getDefaultAttrs(project, root).replace('\n', ' ')
                            + " android:orientation=\"vertical\"" //$NON-NLS-1$
                            + "></LinearLayout>\n";         //$NON-NLS-1$
                    }
                    return null;
                }
        },
        new TypeInfo("Values",                                              // UI name
                "An XML file with simple values: colors, strings, dimensions, etc.", // tooltip
                ResourceFolderType.VALUES,                                  // folder type
                SdkConstants.TAG_RESOURCES,                                 // root seed
                null,                                                       // default root
                null,                                                       // xmlns
                null,                                                       // default attributes
                1                                                           // target API level
                ),
        new TypeInfo("Drawable",                                            // UI name
                "An XML file that describes a drawable.",                   // tooltip
                ResourceFolderType.DRAWABLE,                                // folder type
                AndroidTargetData.DESCRIPTOR_DRAWABLE,                      // root seed
                null,                                                       // default root
                SdkConstants.NS_RESOURCES,                                  // xmlns
                null,                                                       // default attributes
                1                                                           // target API level
                ),
        new TypeInfo("Menu",                                                // UI name
                "An XML file that describes an menu.",                      // tooltip
                ResourceFolderType.MENU,                                    // folder type
                SdkConstants.TAG_MENU,                                      // root seed
                null,                                                       // default root
                SdkConstants.NS_RESOURCES,                                  // xmlns
                null,                                                       // default attributes
                1                                                           // target API level
                ),
        new TypeInfo("Color List",                                          // UI name
                "An XML file that describes a color state list.",           // tooltip
                ResourceFolderType.COLOR,                                   // folder type
                AndroidTargetData.DESCRIPTOR_COLOR,                         // root seed
                "selector",  //$NON-NLS-1$                                  // default root
                SdkConstants.NS_RESOURCES,                                  // xmlns
                null,                                                       // default attributes
                1                                                           // target API level
                ),
        new TypeInfo("Property Animation",                                  // UI name
                "An XML file that describes a property animation",          // tooltip
                ResourceFolderType.ANIMATOR,                                // folder type
                AndroidTargetData.DESCRIPTOR_ANIMATOR,                      // root seed
                "set", //$NON-NLS-1$                                        // default root
                SdkConstants.NS_RESOURCES,                                  // xmlns
                null,                                                       // default attributes
                11                                                          // target API level
                ),
        new TypeInfo("Tween Animation",                                     // UI name
                "An XML file that describes a tween animation.",            // tooltip
                ResourceFolderType.ANIM,                                    // folder type
                AndroidTargetData.DESCRIPTOR_ANIM,                          // root seed
                "set", //$NON-NLS-1$                                        // default root
                null,                                                       // xmlns
                null,                                                       // default attributes
                1                                                           // target API level
                ),
        new TypeInfo("AppWidget Provider",                                  // UI name
                "An XML file that describes a widget provider.",            // tooltip
                ResourceFolderType.XML,                                     // folder type
                AndroidTargetData.DESCRIPTOR_APPWIDGET_PROVIDER,            // root seed
                null,                                                       // default root
                SdkConstants.NS_RESOURCES,                                  // xmlns
                null,                                                       // default attributes
                3                                                           // target API level
                ),
        new TypeInfo("Preference",                                          // UI name
                "An XML file that describes preferences.",                  // tooltip
                ResourceFolderType.XML,                                     // folder type
                AndroidTargetData.DESCRIPTOR_PREFERENCES,                   // root seed
                SdkConstants.CLASS_NAME_PREFERENCE_SCREEN,                  // default root
                SdkConstants.NS_RESOURCES,                                  // xmlns
                null,                                                       // default attributes
                1                                                           // target API level
                ),
        new TypeInfo("Searchable",                                          // UI name
                "An XML file that describes a searchable.",                 // tooltip
                ResourceFolderType.XML,                                     // folder type
                AndroidTargetData.DESCRIPTOR_SEARCHABLE,                    // root seed
                null,                                                       // default root
                SdkConstants.NS_RESOURCES,                                  // xmlns
                null,                                                       // default attributes
                1                                                           // target API level
                ),
        // Still missing: Interpolator, Raw and Mipmap. Raw should probably never be in
        // this menu since it's not often used for creating XML files.
    };

    private NewXmlFileWizard.Values mValues;
    private ProjectCombo mProjectButton;
    private Text mFileNameTextField;
    private Combo mTypeCombo;
    private IStructuredSelection mInitialSelection;
    private ResourceFolderType mInitialFolderType;
    private boolean mInternalTypeUpdate;
    private TargetChangeListener mSdkTargetChangeListener;
    private Table mRootTable;
    private TableViewer mRootTableViewer;

    // --- UI creation ---

    /**
     * Constructs a new {@link NewXmlFileCreationPage}.
     * <p/>
     * Called by {@link NewXmlFileWizard#createMainPage}.
     */
    protected NewXmlFileCreationPage(String pageName, NewXmlFileWizard.Values values) {
        super(pageName);
        mValues = values;
        setPageComplete(false);
    }

    public void setInitialSelection(IStructuredSelection initialSelection) {
        mInitialSelection = initialSelection;
    }

    public void setInitialFolderType(ResourceFolderType initialType) {
        mInitialFolderType = initialType;
    }

    /**
     * Called by the parent Wizard to create the UI for this Wizard Page.
     *
     * {@inheritDoc}
     *
     * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
     */
    @Override
    @SuppressWarnings("unused") // SWT constructors have side effects, they aren't unused
    public void createControl(Composite parent) {
        // This UI is maintained with WindowBuilder.

        Composite composite = new Composite(parent, SWT.NULL);
        composite.setLayout(new GridLayout(2, false /*makeColumnsEqualWidth*/));
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));

        // label before type radios
        Label typeLabel = new Label(composite, SWT.NONE);
        typeLabel.setText("Resource Type:");

        mTypeCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
        mTypeCombo.setToolTipText("What type of resource would you like to create?");
        mTypeCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        if (mInitialFolderType != null) {
            mTypeCombo.setEnabled(false);
        }
        mTypeCombo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                TypeInfo type = getSelectedType();
                if (type != null) {
                    onSelectType(type);
                }
            }
        });

        // separator
        Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
        GridData gd2 = new GridData(GridData.GRAB_HORIZONTAL);
        gd2.horizontalAlignment = SWT.FILL;
        gd2.horizontalSpan = 2;
        separator.setLayoutData(gd2);

        // Project: [button]
        String tooltip = "The Android Project where the new resource file will be created.";
        Label projectLabel = new Label(composite, SWT.NONE);
        projectLabel.setText("Project:");
        projectLabel.setToolTipText(tooltip);

        ProjectChooserHelper helper =
                new ProjectChooserHelper(getShell(), null /* filter */);

        mProjectButton = new ProjectCombo(helper, composite, mValues.project);
        mProjectButton.setToolTipText(tooltip);
        mProjectButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        mProjectButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                IProject project = mProjectButton.getSelectedProject();
                if (project != mValues.project) {
                    changeProject(project);
                }
            };
        });

        // Filename: [text]
        Label fileLabel = new Label(composite, SWT.NONE);
        fileLabel.setText("File:");
        fileLabel.setToolTipText("The name of the resource file to create.");

        mFileNameTextField = new Text(composite, SWT.BORDER);
        mFileNameTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        mFileNameTextField.setToolTipText(tooltip);
        mFileNameTextField.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                mValues.name = mFileNameTextField.getText();
                validatePage();
            }
        });

        // separator
        Label rootSeparator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
        GridData gd = new GridData(GridData.GRAB_HORIZONTAL);
        gd.horizontalAlignment = SWT.FILL;
        gd.horizontalSpan = 2;
        rootSeparator.setLayoutData(gd);

        // Root Element:
        // [TableViewer]
        Label rootLabel = new Label(composite, SWT.NONE);
        rootLabel.setText("Root Element:");
        new Label(composite, SWT.NONE);

        mRootTableViewer = new TableViewer(composite, SWT.BORDER | SWT.FULL_SELECTION);
        mRootTable = mRootTableViewer.getTable();
        GridData tableGridData = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
        tableGridData.heightHint = 200;
        mRootTable.setLayoutData(tableGridData);

        setControl(composite);

        // Update state the first time
        setErrorMessage(null);
        setMessage(null);

        initializeFromSelection(mInitialSelection);
        updateAvailableTypes();
        initializeFromFixedType();
        initializeRootValues();
        installTargetChangeListener();

        initialSelectType();
        validatePage();
    }

    private void initialSelectType() {
        TypeInfo[] types = (TypeInfo[]) mTypeCombo.getData();
        int typeIndex = getTypeComboIndex(mValues.type);
        if (typeIndex == -1) {
            typeIndex = 0;
        } else {
            assert mValues.type == types[typeIndex];
        }
        mTypeCombo.select(typeIndex);
        onSelectType(types[typeIndex]);
        updateRootCombo(types[typeIndex]);
    }

    private void installTargetChangeListener() {
        mSdkTargetChangeListener = new TargetChangeListener() {
            @Override
            public IProject getProject() {
                return mValues.project;
            }

            @Override
            public void reload() {
                if (mValues.project != null) {
                    changeProject(mValues.project);
                }
            }
        };

        AdtPlugin.getDefault().addTargetListener(mSdkTargetChangeListener);
    }

    @Override
    public void dispose() {

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

        super.dispose();
    }

    /**
     * Returns the selected root element string, if any.
     *
     * @return The selected root element string or null.
     */
    public String getRootElement() {
        int index = mRootTable.getSelectionIndex();
        if (index >= 0) {
            Object[] roots = (Object[]) mRootTableViewer.getInput();
            return roots[index].toString();
        }
        return null;
    }

    /**
     * Called by {@link NewXmlFileWizard} to initialize the page with the selection
     * received by the wizard -- typically the current user workbench selection.
     * <p/>
     * Things we expect to find out from the selection:
     * <ul>
     * <li>The project name, valid if it's an android nature.</li>
     * <li>The current folder, valid if it's a folder under /res</li>
     * <li>An existing filename, in which case the user will be asked whether to override it.</li>
     * </ul>
     * <p/>
     * The selection can also be set to a {@link Pair} of {@link IProject} and a workspace
     * resource path (where the resource path does not have to exist yet, such as res/anim/).
     *
     * @param selection The selection when the wizard was initiated.
     */
    private boolean initializeFromSelection(IStructuredSelection selection) {
        if (selection == null) {
            return false;
        }

        // Find the best match in the element list. In case there are multiple selected elements
        // select the one that provides the most information and assign them a score,
        // e.g. project=1 + folder=2 + file=4.
        IProject targetProject = null;
        String targetWsFolderPath = null;
        String targetFileName = null;
        int targetScore = 0;
        for (Object element : selection.toList()) {
            if (element instanceof IAdaptable) {
                IResource res = (IResource) ((IAdaptable) element).getAdapter(IResource.class);
                IProject project = res != null ? res.getProject() : null;

                // Is this an Android project?
                try {
                    if (project == null || !project.hasNature(AdtConstants.NATURE_DEFAULT)) {
                        continue;
                    }
                } catch (CoreException e) {
                    // checking the nature failed, ignore this resource
                    continue;
                }

                int score = 1; // we have a valid project at least

                IPath wsFolderPath = null;
                String fileName = null;
                assert res != null; // Eclipse incorrectly thinks res could be null, so tell it no
                if (res.getType() == IResource.FOLDER) {
                    wsFolderPath = res.getProjectRelativePath();
                } else if (res.getType() == IResource.FILE) {
                    if (SdkUtils.endsWithIgnoreCase(res.getName(), DOT_XML)) {
                        fileName = res.getName();
                    }
                    wsFolderPath = res.getParent().getProjectRelativePath();
                }

                // Disregard this folder selection if it doesn't point to /res/something
                if (wsFolderPath != null &&
                        wsFolderPath.segmentCount() > 1 &&
                        SdkConstants.FD_RESOURCES.equals(wsFolderPath.segment(0))) {
                    score += 2;
                } else {
                    wsFolderPath = null;
                    fileName = null;
                }

                score += fileName != null ? 4 : 0;

                if (score > targetScore) {
                    targetScore = score;
                    targetProject = project;
                    targetWsFolderPath = wsFolderPath != null ? wsFolderPath.toString() : null;
                    targetFileName = fileName;
                }
            } else if (element instanceof Pair<?,?>) {
                // Pair of Project/String
                @SuppressWarnings("unchecked")
                Pair<IProject,String> pair = (Pair<IProject,String>)element;
                targetScore = 1;
                targetProject = pair.getFirst();
                targetWsFolderPath = pair.getSecond();
                targetFileName = "";
            }
        }

        if (targetProject == null) {
            // Try to figure out the project from the active editor
            IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
            if (window != null) {
                IWorkbenchPage page = window.getActivePage();
                if (page != null) {
                    IEditorPart activeEditor = page.getActiveEditor();
                    if (activeEditor instanceof AndroidXmlEditor) {
                        Object input = ((AndroidXmlEditor) activeEditor).getEditorInput();
                        if (input instanceof FileEditorInput) {
                            FileEditorInput fileInput = (FileEditorInput) input;
                            targetScore = 1;
                            IFile file = fileInput.getFile();
                            targetProject = file.getProject();
                            IPath path = file.getParent().getProjectRelativePath();
                            targetWsFolderPath = path != null ? path.toString() : null;
                        }
                    }
                }
            }
        }

        if (targetProject == null) {
            // If we didn't find a default project based on the selection, check how many
            // open Android projects we can find in the current workspace. If there's only
            // one, we'll just select it by default.
            IJavaProject[] projects = AdtUtils.getOpenAndroidProjects();
            if (projects != null && projects.length == 1) {
                targetScore = 1;
                targetProject = projects[0].getProject();
            }
        }

        // Now set the UI accordingly
        if (targetScore > 0) {
            mValues.project = targetProject;
            mValues.folderPath = targetWsFolderPath;
            mProjectButton.setSelectedProject(targetProject);
            mFileNameTextField.setText(targetFileName != null ? targetFileName : ""); //$NON-NLS-1$

            // If the current selection context corresponds to a specific file type,
            // select it.
            if (targetWsFolderPath != null) {
                int pos = targetWsFolderPath.lastIndexOf(WS_SEP_CHAR);
                if (pos >= 0) {
                    targetWsFolderPath = targetWsFolderPath.substring(pos + 1);
                }
                String[] folderSegments = targetWsFolderPath.split(RES_QUALIFIER_SEP);
                if (folderSegments.length > 0) {
                    mValues.configuration = FolderConfiguration.getConfig(folderSegments);
                    String folderName = folderSegments[0];
                    selectTypeFromFolder(folderName);
                }
            }
        }

        return true;
    }

    private void initializeFromFixedType() {
        if (mInitialFolderType != null) {
            for (TypeInfo type : sTypes) {
                if (type.getResFolderType() == mInitialFolderType) {
                    mValues.type = type;
                    updateFolderPath(type);
                    break;
                }
            }
        }
    }

    /**
     * Given a folder name, such as "drawable", select the corresponding type in
     * the dropdown.
     */
    void selectTypeFromFolder(String folderName) {
        List<TypeInfo> matches = new ArrayList<TypeInfo>();
        boolean selected = false;

        TypeInfo selectedType = getSelectedType();
        for (TypeInfo type : sTypes) {
            if (type.getResFolderName().equals(folderName)) {
                matches.add(type);
                selected |= type == selectedType;
            }
        }

        if (matches.size() == 1) {
            // If there's only one match, select it if it's not already selected
            if (!selected) {
                selectType(matches.get(0));
            }
        } else if (matches.size() > 1) {
            // There are multiple type candidates for this folder. This can happen
            // for /res/xml for example. Check to see if one of them is currently
            // selected. If yes, leave the selection unchanged. If not, deselect all type.
            if (!selected) {
                selectType(null);
            }
        } else {
            // Nothing valid was selected.
            selectType(null);
        }
    }

    /**
     * Initialize the root values of the type infos based on the current framework values.
     */
    private void initializeRootValues() {
        IProject project = mValues.project;
        for (TypeInfo type : sTypes) {
            // Clear all the roots for this type
            ArrayList<String> roots = type.getRoots();
            if (roots.size() > 0) {
                roots.clear();
            }

            // depending of the type of the seed, initialize the root in different ways
            Object rootSeed = type.getRootSeed();

            if (rootSeed instanceof String) {
                // The seed is a single string, Add it as-is.
                roots.add((String) rootSeed);
            } else if (rootSeed instanceof String[]) {
                // The seed is an array of strings. Add them as-is.
                for (String value : (String[]) rootSeed) {
                    roots.add(value);
                }
            } else if (rootSeed instanceof Integer && project != null) {
                // The seed is a descriptor reference defined in AndroidTargetData.DESCRIPTOR_*
                // In this case add all the children element descriptors defined, recursively,
                // and avoid infinite recursion by keeping track of what has already been added.

                // Note: if project is null, the root list will be empty since it has been
                // cleared above.

                // get the AndroidTargetData from the project
                IAndroidTarget target = null;
                AndroidTargetData data = null;

                target = Sdk.getCurrent().getTarget(project);
                if (target == null) {
                    // A project should have a target. The target can be missing if the project
                    // is an old project for which a target hasn't been affected or if the
                    // target no longer exists in this SDK. Simply log the error and dismiss.

                    AdtPlugin.log(IStatus.INFO,
                            "NewXmlFile wizard: no platform target for project %s",  //$NON-NLS-1$
                            project.getName());
                    continue;
                } else {
                    data = Sdk.getCurrent().getTargetData(target);

                    if (data == null) {
                        // We should have both a target and its data.
                        // However if the wizard is invoked whilst the platform is still being
                        // loaded we can end up in a weird case where we have a target but it
                        // doesn't have any data yet.
                        // Lets log a warning and silently ignore this root.

                        AdtPlugin.log(IStatus.INFO,
                              "NewXmlFile wizard: no data for target %s, project %s",  //$NON-NLS-1$
                              target.getName(), project.getName());
                        continue;
                    }
                }

                IDescriptorProvider provider = data.getDescriptorProvider((Integer)rootSeed);
                ElementDescriptor descriptor = provider.getDescriptor();
                if (descriptor != null) {
                    HashSet<ElementDescriptor> visited = new HashSet<ElementDescriptor>();
                    initRootElementDescriptor(roots, descriptor, visited);
                }

                // Sort alphabetically.
                Collections.sort(roots);
            }
        }
    }

    /**
     * Helper method to recursively insert all XML names for the given {@link ElementDescriptor}
     * into the roots array list. Keeps track of visited nodes to avoid infinite recursion.
     * Also avoids inserting the top {@link DocumentDescriptor} which is generally synthetic
     * and not a valid root element.
     */
    private void initRootElementDescriptor(ArrayList<String> roots,
            ElementDescriptor desc, HashSet<ElementDescriptor> visited) {
        if (!(desc instanceof DocumentDescriptor)) {
            String xmlName = desc.getXmlName();
            if (xmlName != null && xmlName.length() > 0) {
                roots.add(xmlName);
            }
        }

        visited.add(desc);

        for (ElementDescriptor child : desc.getChildren()) {
            if (!visited.contains(child)) {
                initRootElementDescriptor(roots, child, visited);
            }
        }
    }

    /**
     * Changes mProject to the given new project and update the UI accordingly.
     * <p/>
     * Note that this does not check if the new project is the same as the current one
     * on purpose, which allows a project to be updated when its target has changed or
     * when targets are loaded in the background.
     */
    private void changeProject(IProject newProject) {
        mValues.project = newProject;

        // enable types based on new API level
        updateAvailableTypes();
        initialSelectType();

        // update the folder name based on API level
        updateFolderPath(mValues.type);

        // update the Type with the new descriptors.
        initializeRootValues();

        // update the combo
        updateRootCombo(mValues.type);

        validatePage();
    }

    private void onSelectType(TypeInfo type) {
        // Do nothing if this is an internal modification or if the widget has been
        // deselected.
        if (mInternalTypeUpdate) {
            return;
        }

        mValues.type = type;

        if (type == null) {
            return;
        }

        // update the combo
        updateRootCombo(type);

        // update the folder path
        updateFolderPath(type);

        validatePage();
    }

    /** Updates the selected type in the type dropdown control */
    private void setSelectedType(TypeInfo type) {
        TypeInfo[] types = (TypeInfo[]) mTypeCombo.getData();
        if (types != null) {
            for (int i = 0, n = types.length; i < n; i++) {
                if (types[i] == type) {
                    mTypeCombo.select(i);
                    break;
                }
            }
        }
    }

    /** Returns the selected type in the type dropdown control */
    private TypeInfo getSelectedType() {
        int index = mTypeCombo.getSelectionIndex();
        if (index != -1) {
            TypeInfo[] types = (TypeInfo[]) mTypeCombo.getData();
            return types[index];
        }

        return null;
    }

    /** Returns the selected index in the type dropdown control */
    private int getTypeComboIndex(TypeInfo type) {
        TypeInfo[] types = (TypeInfo[]) mTypeCombo.getData();
        for (int i = 0, n = types.length; i < n; i++) {
            if (type == types[i]) {
                return i;
            }
        }

        return -1;
    }

    /** Updates the folder path to reflect the given type */
    private void updateFolderPath(TypeInfo type) {
        String wsFolderPath = mValues.folderPath;
        String newPath = null;
        FolderConfiguration config = mValues.configuration;
        ResourceQualifier qual = config.getInvalidQualifier();
        if (qual == null) {
            // The configuration is valid. Reformat the folder path using the canonical
            // value from the configuration.
            newPath = RES_FOLDER_ABS + config.getFolderName(type.getResFolderType());
        } else {
            // The configuration is invalid. We still update the path but this time
            // do it manually on the string.
            if (wsFolderPath.startsWith(RES_FOLDER_ABS)) {
                wsFolderPath = wsFolderPath.replaceFirst(
                        "^(" + RES_FOLDER_ABS +")[^-]*(.*)",         //$NON-NLS-1$ //$NON-NLS-2$
                        "\\1" + type.getResFolderName() + "\\2");    //$NON-NLS-1$ //$NON-NLS-2$
            } else {
                newPath = RES_FOLDER_ABS + config.getFolderName(type.getResFolderType());
            }
        }

        if (newPath != null && !newPath.equals(wsFolderPath)) {
            mValues.folderPath = newPath;
        }
    }

    /**
     * Helper method that fills the values of the "root element" combo box based
     * on the currently selected type radio button. Also disables the combo is there's
     * only one choice. Always select the first root element for the given type.
     *
     * @param type The currently selected {@link TypeInfo}, or null
     */
    private void updateRootCombo(TypeInfo type) {
        IBaseLabelProvider labelProvider = new ColumnLabelProvider() {
            @Override
            public Image getImage(Object element) {
                return IconFactory.getInstance().getIcon(element.toString());
            }
        };
        mRootTableViewer.setContentProvider(new ArrayContentProvider());
        mRootTableViewer.setLabelProvider(labelProvider);

        if (type != null) {
            // get the list of roots. The list can be empty but not null.
            ArrayList<String> roots = type.getRoots();
            mRootTableViewer.setInput(roots.toArray());

            int index = 0; // default is to select the first one
            String defaultRoot = type.getDefaultRoot(mValues.project);
            if (defaultRoot != null) {
                index = roots.indexOf(defaultRoot);
            }
            mRootTable.select(index < 0 ? 0 : index);
            mRootTable.showSelection();
        }
    }

    /**
     * Helper method to select the current type in the type dropdown
     *
     * @param type The TypeInfo matching the radio button to selected or null to deselect them all.
     */
    private void selectType(TypeInfo type) {
        mInternalTypeUpdate = true;
        mValues.type = type;
        if (type == null) {
            if (mTypeCombo.getSelectionIndex() != -1) {
                mTypeCombo.deselect(mTypeCombo.getSelectionIndex());
            }
        } else {
            setSelectedType(type);
        }
        updateRootCombo(type);
        mInternalTypeUpdate = false;
    }

    /**
     * Add the available types in the type combobox, based on whether they are available
     * for the current SDK.
     * <p/>
     * A type is available either if:
     * - if mProject is null, API level 1 is considered valid
     * - if mProject is !null, the project->target->API must be >= to the type's API level.
     */
    private void updateAvailableTypes() {
        IProject project = mValues.project;
        IAndroidTarget target = project != null ? Sdk.getCurrent().getTarget(project) : null;
        int currentApiLevel = 1;
        if (target != null) {
            currentApiLevel = target.getVersion().getApiLevel();
        }

        List<String> items = new ArrayList<String>(sTypes.length);
        List<TypeInfo> types = new ArrayList<TypeInfo>(sTypes.length);
        for (int i = 0, n = sTypes.length; i < n; i++) {
            TypeInfo type = sTypes[i];
            if (type.getTargetApiLevel() <= currentApiLevel) {
                items.add(type.getUiName());
                types.add(type);
            }
        }
        mTypeCombo.setItems(items.toArray(new String[items.size()]));
        mTypeCombo.setData(types.toArray(new TypeInfo[types.size()]));
    }

    /**
     * Validates the fields, displays errors and warnings.
     * Enables the finish button if there are no errors.
     */
    private void validatePage() {
        String error = null;
        String warning = null;

        // -- validate type
        TypeInfo type = mValues.type;
        if (error == null) {
            if (type == null) {
                error = "One of the types must be selected (e.g. layout, values, etc.)";
            }
        }

        // -- validate project
        if (mValues.project == null) {
            error = "Please select an Android project.";
        }

        // -- validate type API level
        if (error == null) {
            IAndroidTarget target = Sdk.getCurrent().getTarget(mValues.project);
            int currentApiLevel = 1;
            if (target != null) {
                currentApiLevel = target.getVersion().getApiLevel();
            }

            assert type != null;
            if (type.getTargetApiLevel() > currentApiLevel) {
                error = "The API level of the selected type (e.g. AppWidget, etc.) is not " +
                        "compatible with the API level of the project.";
            }
        }

        // -- validate filename
        if (error == null) {
            String fileName = mValues.getFileName();
            assert type != null;
            ResourceFolderType folderType = type.getResFolderType();
            error = ResourceNameValidator.create(true, folderType).isValid(fileName);
        }

        // -- validate destination file doesn't exist
        if (error == null) {
            IFile file = mValues.getDestinationFile();
            if (file != null && file.exists()) {
                warning = "The destination file already exists";
            }
        }

        // -- update UI & enable finish if there's no error
        setPageComplete(error == null);
        if (error != null) {
            setMessage(error, IMessageProvider.ERROR);
        } else if (warning != null) {
            setMessage(warning, IMessageProvider.WARNING);
        } else {
            setErrorMessage(null);
            setMessage(null);
        }
    }

    /**
     * Returns the {@link TypeInfo} for the given {@link ResourceFolderType}, or null if
     * not found
     *
     * @param folderType the {@link ResourceFolderType} to look for
     * @return the corresponding {@link TypeInfo}
     */
    static TypeInfo getTypeInfo(ResourceFolderType folderType) {
        for (TypeInfo typeInfo : sTypes) {
            if (typeInfo.getResFolderType() == folderType) {
                return typeInfo;
            }
        }

        return null;
    }
}
