/*
 * 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.ResourceNameValidator;
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.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.CreateXmlResourcePanel;
import org.jetbrains.android.actions.CreateXmlResourceSubdirPanel;
import org.jetbrains.android.actions.CreateXmlResourceSubdirPanel.Parent;
import org.jetbrains.android.util.AndroidResourceUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Embeddable UI for selecting how to create a new resource value (which XML file and directories to
 * place it).
 */
public class BlazeCreateXmlResourcePanel implements CreateXmlResourcePanel, 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 ResourceNameValidator myResourceNameValidator;
  @Nullable private VirtualFile myContextFile;
  @Nullable private VirtualFile myResDirectory;

  public BlazeCreateXmlResourcePanel(
      @NotNull Module module,
      @NotNull ResourceType resourceType,
      @NotNull ResourceFolderType folderType,
      @Nullable String resourceName,
      @Nullable String resourceValue,
      boolean chooseName,
      boolean chooseValue,
      boolean chooseFilename,
      @Nullable VirtualFile defaultFile,
      @Nullable VirtualFile contextFile,
      @NotNull Function<Module, ResourceNameValidator> 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(@NotNull VirtualFile file, @NotNull 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 CreateXmlResourceDialog.checkIfResourceAlreadyExists(
        myModule.getProject(), resourceDir, resourceName, myResourceType, directoryNames, fileName);
  }

  @Override
  public ResourceNameValidator getResourceNameValidator() {
    return myResourceNameValidator;
  }

  @NotNull
  @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);
  }
}
