/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * 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.google.idea.blaze.android.resources.actions;

import com.android.resources.ResourceFolderType;
import com.android.resources.ResourceType;
import com.android.tools.idea.res.IdeResourceNameValidator;
import com.google.idea.sdkcompat.android.resources.actions.CreateXmlResourceDialogAdapter;
import com.google.idea.sdkcompat.android.resources.actions.CreateXmlResourcePanelAdapter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiManager;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.ui.components.JBLabel;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import javax.annotation.Nullable;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.jetbrains.android.actions.CreateXmlResourceDialog;
import org.jetbrains.android.actions.CreateXmlResourceSubdirPanel;
import org.jetbrains.android.actions.CreateXmlResourceSubdirPanel.Parent;
import org.jetbrains.android.util.AndroidResourceUtil;

/**
 * Embeddable UI for selecting how to create a new resource value (which XML file and directories to
 * place it).
 */
public class BlazeCreateXmlResourcePanel extends CreateXmlResourcePanelAdapter implements Parent {

  private JPanel myPanel;
  private JTextField myNameField;
  private JTextField myValueField;
  private JBLabel myValueLabel;
  private JBLabel myNameLabel;
  private JComboBox myFileNameCombo;
  private JBLabel myResDirLabel;
  private ComboboxWithBrowseButton myResDirCombo;
  private JBLabel myFileNameLabel;

  private final Module myModule;
  private final ResourceType myResourceType;

  private JPanel myDirectoriesPanel;
  private JBLabel myDirectoriesLabel;
  private CreateXmlResourceSubdirPanel mySubdirPanel;

  private final IdeResourceNameValidator myResourceNameValidator;
  @Nullable private VirtualFile myContextFile;
  @Nullable private VirtualFile myResDirectory;

  public BlazeCreateXmlResourcePanel(
      Module module,
      ResourceType resourceType,
      ResourceFolderType folderType,
      @Nullable String resourceName,
      @Nullable String resourceValue,
      boolean chooseName,
      boolean chooseValue,
      boolean chooseFilename,
      @Nullable VirtualFile defaultFile,
      @Nullable VirtualFile contextFile,
      Function<Module, IdeResourceNameValidator> nameValidatorFactory) {
    setupUi();
    setChangeNameVisible(false);
    setChangeValueVisible(false);
    setChangeFileNameVisible(chooseFilename);
    myModule = module;
    myContextFile = contextFile;
    if (chooseName) {
      setChangeNameVisible(true);
    }
    if (!StringUtil.isEmpty(resourceName)) {
      myNameField.setText(resourceName);
    }

    if (chooseValue) {
      setChangeValueVisible(true);
      if (!StringUtil.isEmpty(resourceValue)) {
        myValueField.setText(resourceValue);
      }
    }

    myResourceType = resourceType;

    ApplicationManager.getApplication().assertReadAccessAllowed();
    // Set up UI to choose the base directory if needed (use context to prune selection).
    myResDirLabel.setVisible(false);
    myResDirCombo.setVisible(false);
    myResDirCombo.addBrowseFolderListener(
        module.getProject(), FileChooserDescriptorFactory.createSingleFolderDescriptor());
    setupResourceDirectoryCombo();

    if (defaultFile == null) {
      final String defaultFileName = AndroidResourceUtil.getDefaultResourceFileName(myResourceType);

      if (defaultFileName != null) {
        myFileNameCombo.getEditor().setItem(defaultFileName);
      }
    }

    myDirectoriesLabel.setLabelFor(myDirectoriesPanel);
    mySubdirPanel =
        new CreateXmlResourceSubdirPanel(module.getProject(), folderType, myDirectoriesPanel, this);
    myResourceNameValidator = nameValidatorFactory.apply(getModule());

    if (defaultFile != null) {
      resetFromFile(defaultFile, module.getProject());
    }
  }

  private void setupResourceDirectoryCombo() {
    Project project = myModule.getProject();
    if (myContextFile != null) {
      // Try to figure out res/ dir from context
      // (e.g., while refactoring an xml file that's a child of a res/ directory).
      // We currently take the parent and hide the combo box.
      PsiManager manager = PsiManager.getInstance(project);
      VirtualFile virtualDirectory =
          BlazeCreateResourceUtils.getResDirFromDataContext(myContextFile);
      PsiDirectory directory =
          virtualDirectory != null ? manager.findDirectory(virtualDirectory) : null;
      if (directory != null) {
        myResDirectory = directory.getVirtualFile();
      } else {
        // As a last resort, if we have poor context,
        // e.g., quick fix from within a .java file, set up the UI
        // based on the deps of the .java file.
        BlazeCreateResourceUtils.setupResDirectoryChoices(
            project, myContextFile, myResDirLabel, myResDirCombo);
      }
    } else {
      // As a last resort, if we have no context at all, set up some UI.
      BlazeCreateResourceUtils.setupResDirectoryChoices(
          project, null, myResDirLabel, myResDirCombo);
    }
  }

  @Override
  public void resetToDefault() {
    String defaultFileName = AndroidResourceUtil.getDefaultResourceFileName(myResourceType);
    if (defaultFileName != null) {
      myFileNameCombo.getEditor().setItem(defaultFileName);
    }
    setupResourceDirectoryCombo();
    mySubdirPanel.resetToDefault();
  }

  @Override
  public void resetFromFile(VirtualFile file, Project project) {
    final VirtualFile parent = file.getParent();
    if (parent == null) {
      return;
    }
    mySubdirPanel.resetFromFile(parent);
    myFileNameCombo.getEditor().setItem(file.getName());
    setupResourceDirectoryCombo();
    myPanel.repaint();
  }

  @Override
  public String getResourceName() {
    return myNameField.getText().trim();
  }

  @Override
  public ResourceType getType() {
    return myResourceType;
  }

  @Override
  public String getValue() {
    return myValueField.getText().trim();
  }

  @Override
  public VirtualFile getResourceDirectory() {
    if (myResDirectory != null) {
      return myResDirectory;
    }
    if (myResDirCombo.isVisible()) {
      PsiDirectory directory =
          BlazeCreateResourceUtils.getResDirFromUI(myModule.getProject(), myResDirCombo);
      return directory != null ? directory.getVirtualFile() : null;
    }
    return null;
  }

  @Override
  public List<String> getDirNames() {
    return mySubdirPanel.getDirNames();
  }

  @Override
  public String getFileName() {
    return ((String) myFileNameCombo.getEditor().getItem()).trim();
  }

  @Override
  public ValidationInfo doValidate() {
    String resourceName = getResourceName();
    VirtualFile resourceDir = getResourceDirectory();
    List<String> directoryNames = getDirNames();
    String fileName = getFileName();

    if (myNameField.isVisible() && resourceName.isEmpty()) {
      return new ValidationInfo("specify resource name", myNameField);
    } else if (myNameField.isVisible()
        && !AndroidResourceUtil.isCorrectAndroidResourceName(resourceName)) {
      return new ValidationInfo(resourceName + " is not correct resource name", myNameField);
    } else if (fileName.isEmpty()) {
      return new ValidationInfo("specify file name", myFileNameCombo);
    } else if (resourceDir == null) {
      return new ValidationInfo("specify a resource directory", myResDirCombo);
    } else if (directoryNames.isEmpty()) {
      return new ValidationInfo("choose directories", myDirectoriesPanel);
    }

    return CreateXmlResourceDialogAdapter.checkIfResourceAlreadyExists(
        myModule.getProject(),
        resourceDir,
        resourceName,
        null,
        myResourceType,
        directoryNames,
        fileName);
  }

  @Override
  public IdeResourceNameValidator getResourceNameValidatorCompat() {
    return myResourceNameValidator;
  }

  @Override
  public Module getModule() {
    return myModule;
  }

  /** @see CreateXmlResourceDialog#getPreferredFocusedComponent() */
  @Override
  public JComponent getPreferredFocusedComponent() {
    String name = myNameField.getText();
    if (name.isEmpty()) {
      return myNameField;
    } else if (myValueField.isVisible()) {
      return myValueField;
    } else {
      return myFileNameCombo;
    }
  }

  @Override
  public JComponent getPanel() {
    return myPanel;
  }

  private void setChangeFileNameVisible(boolean isVisible) {
    myFileNameLabel.setVisible(isVisible);
    myFileNameCombo.setVisible(isVisible);
  }

  private void setChangeValueVisible(boolean isVisible) {
    myValueField.setVisible(isVisible);
    myValueLabel.setVisible(isVisible);
  }

  private void setChangeNameVisible(boolean isVisible) {
    myNameField.setVisible(isVisible);
    myNameLabel.setVisible(isVisible);
  }

  // Only public for CreateXmlResourceSubdirPanel.Parent
  @Override
  public void updateFilesCombo(List<VirtualFile> directories) {
    final Object oldItem = myFileNameCombo.getEditor().getItem();
    final Set<String> fileNameSet = new HashSet<>();

    for (VirtualFile dir : directories) {
      for (VirtualFile file : dir.getChildren()) {
        fileNameSet.add(file.getName());
      }
    }
    final List<String> fileNames = new ArrayList<>(fileNameSet);
    Collections.sort(fileNames);
    myFileNameCombo.setModel(new DefaultComboBoxModel(fileNames.toArray()));
    myFileNameCombo.getEditor().setItem(oldItem);
  }

  /** Initially generated by IntelliJ from a .form file. */
  private void setupUi() {
    myPanel = new JPanel();
    myPanel.setLayout(new GridLayoutManager(6, 2, new Insets(0, 0, 5, 0), -1, -1));
    myNameLabel = new JBLabel();
    myNameLabel.setText("Resource name:");
    myNameLabel.setDisplayedMnemonic('N');
    myNameLabel.setDisplayedMnemonicIndex(9);
    myPanel.add(
        myNameLabel,
        new GridConstraints(
            0,
            0,
            1,
            1,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_FIXED,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    myNameField = new JTextField();
    myPanel.add(
        myNameField,
        new GridConstraints(
            0,
            1,
            1,
            1,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_WANT_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            new Dimension(150, -1),
            null,
            0,
            false));
    myFileNameLabel = new JBLabel();
    myFileNameLabel.setText("File name:");
    myFileNameLabel.setDisplayedMnemonic('F');
    myFileNameLabel.setDisplayedMnemonicIndex(0);
    myPanel.add(
        myFileNameLabel,
        new GridConstraints(
            3,
            0,
            1,
            1,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_FIXED,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    myDirectoriesPanel = new JPanel();
    myDirectoriesPanel.setLayout(new BorderLayout(0, 0));
    myPanel.add(
        myDirectoriesPanel,
        new GridConstraints(
            5,
            0,
            1,
            2,
            GridConstraints.ANCHOR_CENTER,
            GridConstraints.FILL_BOTH,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            null,
            null,
            null,
            0,
            false));
    myDirectoriesLabel = new JBLabel();
    myDirectoriesLabel.setText("Create the resource in directories:");
    myDirectoriesLabel.setDisplayedMnemonic('C');
    myDirectoriesLabel.setDisplayedMnemonicIndex(0);
    myPanel.add(
        myDirectoriesLabel,
        new GridConstraints(
            4,
            0,
            1,
            2,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_FIXED,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    myValueLabel = new JBLabel();
    myValueLabel.setText("Resource value:");
    myValueLabel.setDisplayedMnemonic('V');
    myValueLabel.setDisplayedMnemonicIndex(9);
    myPanel.add(
        myValueLabel,
        new GridConstraints(
            1,
            0,
            1,
            1,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_FIXED,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    myValueField = new JTextField();
    myPanel.add(
        myValueField,
        new GridConstraints(
            1,
            1,
            1,
            1,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_WANT_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            new Dimension(150, -1),
            null,
            0,
            false));
    myFileNameCombo = new JComboBox();
    myFileNameCombo.setEditable(true);
    myPanel.add(
        myFileNameCombo,
        new GridConstraints(
            3,
            1,
            1,
            1,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    myResDirLabel = new JBLabel();
    myResDirLabel.setText("Base directory:");
    myResDirLabel.setDisplayedMnemonic('B');
    myResDirLabel.setDisplayedMnemonicIndex(0);
    myPanel.add(
        myResDirLabel,
        new GridConstraints(
            2,
            0,
            1,
            1,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_FIXED,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    myResDirCombo = new ComboboxWithBrowseButton();
    myPanel.add(
        myResDirCombo,
        new GridConstraints(
            2,
            1,
            1,
            1,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    myNameLabel.setLabelFor(myNameField);
    myFileNameLabel.setLabelFor(myFileNameCombo);
    myValueLabel.setLabelFor(myValueField);
  }
}
