/**
   * 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>The current folder, valid if it's a folder under /res
   *   <li>An existing filename, in which case the user will be asked whether to override it.
   * </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;
  }
  /**
   * Called by the parent Wizard to create the UI for this Wizard Page.
   *
   * <p>{@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();
  }