/*
 * Copyright 2000-2013 JetBrains s.r.o.
 *
 * 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.intellij.vcs.log.ui;

import com.intellij.ide.util.treeView.AbstractTreeUi;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diff.impl.patch.formove.FilePathComparator;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.ex.FileNodeDescriptor;
import com.intellij.openapi.fileChooser.ex.FileSystemTreeImpl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.changes.ui.VirtualFileListCellRenderer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.PlatformIcons;
import com.intellij.util.PlusMinus;
import com.intellij.util.TreeNodeState;
import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.hash.HashSet;
import com.intellij.util.treeWithCheckedNodes.SelectionManager;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;

/**
 * @author irengrig
 *         Date: 2/3/11
 *         Time: 12:04 PM
 */
public class VcsStructureChooser extends DialogWrapper {
  private final static int MAX_FOLDERS = 100;
  public static final Border BORDER = IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.LEFT);
  public static final String DEFAULT_TEXT = "<html>Selected:</html>";
  public static final String CAN_NOT_ADD_TEXT = "<html>Selected: <font color=red>(You have added " + MAX_FOLDERS + " elements. No more is allowed.)</font></html>";
  @NotNull private final Project myProject;
  private Set<VirtualFile> myRoots;
  private Map<VirtualFile, String> myModulesSet;
  private SelectionManager mySelectionManager;
  private DefaultMutableTreeNode myRoot;
  private JBList mySelectedList;
  private JLabel mySelectedLabel;
  private Tree myTree;
  private final List<VirtualFile> myInitialRoots;

  public VcsStructureChooser(@NotNull Project project,
                             final String title,
                             final Collection<VirtualFile> initialSelection,
                             List<VirtualFile> initialRoots) {
    super(project, true);
    myInitialRoots = initialRoots;
    setTitle(title);
    myProject = project;
    mySelectionManager = new SelectionManager(MAX_FOLDERS, 500, MyNodeConvertor.getInstance());
    init();
    mySelectionManager.setSelection(initialSelection);
    checkEmptyness();
  }

  private void calculateRoots() {
    final ModuleManager moduleManager = ModuleManager.getInstance(myProject);
    // assertion for read access inside
    final Module[] modules = ApplicationManager.getApplication().runReadAction(new Computable<Module[]>() {
      public Module[] compute() {
        return moduleManager.getModules();
      }
    });

    final TreeSet<VirtualFile> checkSet = new TreeSet<VirtualFile>(FilePathComparator.getInstance());
    myRoots = new HashSet<VirtualFile>();
    myRoots.addAll(myInitialRoots);
    checkSet.addAll(myInitialRoots);
    myModulesSet = new HashMap<VirtualFile, String>();
    for (Module module : modules) {
      final VirtualFile[] files = ModuleRootManager.getInstance(module).getContentRoots();
      for (VirtualFile file : files) {
        final VirtualFile floor = checkSet.floor(file);
        if (floor != null) {
          myModulesSet.put(file, module.getName());
          myRoots.add(file);
        }
      }
    }
  }

  public Map<VirtualFile, String> getModulesSet() {
    return myModulesSet;
  }

  @NotNull
  public Collection<VirtualFile> getSelectedFiles() {
    return ((CollectionListModel) mySelectedList.getModel()).getItems();
  }

  private void checkEmptyness() {
    setOKActionEnabled(mySelectedList.getModel().getSize() > 0);
  }

  @Override
  protected String getDimensionServiceKey() {
    return "git4idea.history.wholeTree.VcsStructureChooser";
  }

  @Override
  public JComponent getPreferredFocusedComponent() {
    return myTree;
  }

  @Override
  protected JComponent createCenterPanel() {
    final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createAllButJarContentsDescriptor();
    calculateRoots();
    final ArrayList<VirtualFile> list = new ArrayList<VirtualFile>(myRoots);
    final Comparator<VirtualFile> comparator = new Comparator<VirtualFile>() {
      @Override
      public int compare(VirtualFile o1, VirtualFile o2) {
        final boolean isDir1 = o1.isDirectory();
        final boolean isDir2 = o2.isDirectory();
        if (isDir1 != isDir2) return isDir1 ? -1 : 1;

        final String module1 = myModulesSet.get(o1);
        final String path1 = module1 != null ? module1 : o1.getPath();
        final String module2 = myModulesSet.get(o2);
        final String path2 = module2 != null ? module2 : o2.getPath();
        return path1.compareToIgnoreCase(path2);
      }
    };
    descriptor.setRoots(list);
    myTree = new Tree();
    myTree.setMinimumSize(new Dimension(200, 200));
    myTree.setBorder(BORDER);
    myTree.setShowsRootHandles(true);
    myTree.setRootVisible(true);
    myTree.getExpandableItemsHandler().setEnabled(false);
    final MyCheckboxTreeCellRenderer cellRenderer = new MyCheckboxTreeCellRenderer(mySelectionManager, myModulesSet, myProject,
                                                                                   myTree, myRoots);
    final FileSystemTreeImpl fileSystemTree = new FileSystemTreeImpl(myProject, descriptor, myTree, cellRenderer, null, new Convertor<TreePath, String>() {
      @Override
      public String convert(TreePath o) {
        final DefaultMutableTreeNode lastPathComponent = ((DefaultMutableTreeNode) o.getLastPathComponent());
        final Object uo = lastPathComponent.getUserObject();
        if (uo instanceof FileNodeDescriptor) {
          final VirtualFile file = ((FileNodeDescriptor)uo).getElement().getFile();
          final String module = myModulesSet.get(file);
          if (module != null) return module;
          return file == null ? "" : file.getName();
        }
        return o.toString();
      }
    });
    final AbstractTreeUi ui = fileSystemTree.getTreeBuilder().getUi();
    ui.setNodeDescriptorComparator(new Comparator<NodeDescriptor>() {
      @Override
      public int compare(NodeDescriptor o1, NodeDescriptor o2) {
        if (o1 instanceof FileNodeDescriptor && o2 instanceof FileNodeDescriptor) {
          final VirtualFile f1 = ((FileNodeDescriptor)o1).getElement().getFile();
          final VirtualFile f2 = ((FileNodeDescriptor)o2).getElement().getFile();
          return comparator.compare(f1, f2);
        }
        return o1.getIndex() - o2.getIndex();
      }
    });
    myRoot = (DefaultMutableTreeNode)myTree.getModel().getRoot();

    new ClickListener() {
      @Override
      public boolean onClick(@NotNull MouseEvent e, int clickCount) {
        int row = myTree.getRowForLocation(e.getX(), e.getY());
        if (row < 0) return false;
        final Object o = myTree.getPathForRow(row).getLastPathComponent();
        if (myRoot == o || getFile(o) == null) return false;

        Rectangle rowBounds = myTree.getRowBounds(row);
        cellRenderer.setBounds(rowBounds);
        Rectangle checkBounds = cellRenderer.myCheckbox.getBounds();
        checkBounds.setLocation(rowBounds.getLocation());

        if (checkBounds.height == 0) checkBounds.height = rowBounds.height;

        if (checkBounds.contains(e.getPoint())) {
          mySelectionManager.toggleSelection((DefaultMutableTreeNode)o);
          myTree.revalidate();
          myTree.repaint();
        }
        return true;
      }
    }.installOn(myTree);

    myTree.addKeyListener(new KeyAdapter() {
      public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_SPACE) {
          TreePath treePath = myTree.getLeadSelectionPath();
          if (treePath == null) return;
          final Object o = treePath.getLastPathComponent();
          if (myRoot == o || getFile(o) == null) return;
           mySelectionManager.toggleSelection((DefaultMutableTreeNode)o);
          myTree.revalidate();
          myTree.repaint();
          e.consume();
        }
      }
    });

    final Splitter splitter = new Splitter(true, 0.7f);
    Disposer.register(this.getDisposable(), new Disposable() {
      public void dispose() {
        splitter.dispose();
      }
    });
    splitter.setFirstComponent(new JBScrollPane(fileSystemTree.getTree()));
    final JPanel wrapper = new JPanel(new BorderLayout());
    mySelectedLabel = new JLabel(DEFAULT_TEXT);
    mySelectedLabel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0));
    wrapper.add(mySelectedLabel, BorderLayout.NORTH);
    mySelectedList = new JBList(new CollectionListModel(new ArrayList<VirtualFile>()));
    mySelectedList.setCellRenderer(new WithModulesListCellRenderer(myProject, myModulesSet));
    wrapper.add(ScrollPaneFactory.createScrollPane(mySelectedList), BorderLayout.CENTER);
    splitter.setSecondComponent(wrapper);

    mySelectionManager.setSelectionChangeListener(new PlusMinus<VirtualFile>() {
      @Override
      public void plus(VirtualFile virtualFile) {
        final CollectionListModel model = (CollectionListModel)mySelectedList.getModel();
        model.add(virtualFile);
        model.sort(FilePathComparator.getInstance());
        recalculateErrorText();
        mySelectedList.revalidate();
        mySelectedList.repaint();
      }

      private void recalculateErrorText() {
        checkEmptyness();
        if (mySelectionManager.canAddSelection()) {
          mySelectedLabel.setText(DEFAULT_TEXT);
        } else {
          mySelectedLabel.setText(CAN_NOT_ADD_TEXT);
        }
        mySelectedLabel.revalidate();
      }

      @Override
      public void minus(VirtualFile virtualFile) {
        final CollectionListModel defaultListModel = (CollectionListModel)mySelectedList.getModel();
        for (int i = 0; i < defaultListModel.getSize(); i++) {
          final VirtualFile elementAt = (VirtualFile)defaultListModel.getElementAt(i);
          if (virtualFile.equals(elementAt)) {
            defaultListModel.remove(i);
            break;
          }
        }
        defaultListModel.sort(FilePathComparator.getInstance());
        recalculateErrorText();
        mySelectedList.revalidate();
        mySelectedList.repaint();
      }
    });
    mySelectedList.addKeyListener(new KeyAdapter() {
      @Override
      public void keyReleased(KeyEvent e) {
        if (e.getModifiers() == 0 && e.getKeyCode() == KeyEvent.VK_DELETE) {
          final int[] idx = mySelectedList.getSelectedIndices();
          if (idx != null && idx.length > 0) {
            final int answer = Messages
              .showYesNoDialog(myProject, "Remove selected paths from filter?", "Remove from filter", Messages.getQuestionIcon());
            if (Messages.YES == answer) {
              Arrays.sort(idx);
              for (int i = idx.length - 1; i >= 0; --i) {
                int i1 = idx[i];
                mySelectionManager.removeSelection((VirtualFile)((CollectionListModel) mySelectedList.getModel()).getElementAt(i1));
                myTree.revalidate();
                myTree.repaint();
              }
            }
          }
        }
      }
    });

    return splitter;
  }

  @Nullable
  private static VirtualFile getFile(final Object node) {
    if (! (((DefaultMutableTreeNode)node).getUserObject() instanceof FileNodeDescriptor)) return null;
    final FileNodeDescriptor descriptor = (FileNodeDescriptor)((DefaultMutableTreeNode)node).getUserObject();
    if (descriptor.getElement().getFile() == null) return null;
    return descriptor.getElement().getFile();
  }

  private static class MyCheckboxTreeCellRenderer extends JPanel implements TreeCellRenderer {
    private final WithModulesListCellRenderer myTextRenderer;
    public final JCheckBox myCheckbox;
    private final SelectionManager mySelectionManager;
    private final Map<VirtualFile, String> myModulesSet;
    private final Collection<VirtualFile> myRoots;
    private final ColoredTreeCellRenderer myColoredRenderer;
    private final JLabel myEmpty;
    private final JList myFictive;

    private MyCheckboxTreeCellRenderer(final SelectionManager selectionManager, Map<VirtualFile, String> modulesSet, final Project project,
                                       final JTree tree, final Collection<VirtualFile> roots) {
      super(new BorderLayout());
      mySelectionManager = selectionManager;
      myModulesSet = modulesSet;
      myRoots = roots;
      setBackground(tree.getBackground());
      myColoredRenderer = new ColoredTreeCellRenderer() {
        @Override
        public void customizeCellRenderer(JTree tree,
                                          Object value,
                                          boolean selected,
                                          boolean expanded,
                                          boolean leaf,
                                          int row,
                                          boolean hasFocus) {
          append(value.toString());
        }
      };
      myFictive = new JBList();
      myFictive.setBackground(tree.getBackground());
      myFictive.setSelectionBackground(UIUtil.getListSelectionBackground());
      myFictive.setSelectionForeground(UIUtil.getListSelectionForeground());

      myTextRenderer = new WithModulesListCellRenderer(project, myModulesSet) {
        @Override
        protected void putParentPath(Object value, FilePath path, FilePath self) {
          if (myRoots.contains(self.getVirtualFile())) {
            super.putParentPath(value, path, self);
          }
        }
      };
      myTextRenderer.setBackground(tree.getBackground());

      myCheckbox = new JCheckBox();
      myCheckbox.setBackground(tree.getBackground());
      myEmpty = new JLabel("");

      add(myCheckbox, BorderLayout.WEST);
      add(myTextRenderer, BorderLayout.CENTER);
      myCheckbox.setVisible(true);
    }

    @Override
    public Component getTreeCellRendererComponent(JTree tree,
                                                  Object value,
                                                  boolean selected,
                                                  boolean expanded,
                                                  boolean leaf,
                                                  int row,
                                                  boolean hasFocus) {
      invalidate();
      final VirtualFile file = getFile(value);
      final DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
      if (file == null) {
        if (value instanceof DefaultMutableTreeNode) {
          final Object uo = node.getUserObject();
          if (uo instanceof String) {
            myColoredRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
            return myColoredRenderer;
          }
        }
        return myEmpty;
      }
      myCheckbox.setVisible(true);
      final TreeNodeState state = mySelectionManager.getState(node);
      myCheckbox.setEnabled(TreeNodeState.CLEAR.equals(state) || TreeNodeState.SELECTED.equals(state));
      myCheckbox.setSelected(!TreeNodeState.CLEAR.equals(state));
      myTextRenderer.getListCellRendererComponent(myFictive, file, 0, selected, hasFocus);
      revalidate();
      return this;
    }
  }

  private static class MyNodeConvertor implements Convertor<DefaultMutableTreeNode, VirtualFile> {
    private final static MyNodeConvertor ourInstance = new MyNodeConvertor();

    public static MyNodeConvertor getInstance() {
      return ourInstance;
    }

    @Override
    public VirtualFile convert(DefaultMutableTreeNode o) {
      return ((FileNodeDescriptor)o.getUserObject()).getElement().getFile();
    }
  }

  private static class WithModulesListCellRenderer extends VirtualFileListCellRenderer {
    private final Map<VirtualFile, String> myModules;

    private WithModulesListCellRenderer(Project project, final Map<VirtualFile, String> modules) {
      super(project, true);
      myModules = modules;
    }

    @Override
    protected String getName(FilePath path) {
      final String module = myModules.get(path.getVirtualFile());
      if (module != null) {
        return module;
      }
      return super.getName(path);
    }

    @Override
    protected void renderIcon(FilePath path) {
      final String module = myModules.get(path.getVirtualFile());
      if (module != null) {
        setIcon(PlatformIcons.CONTENT_ROOT_ICON_CLOSED);
      } else {
        if (path.isDirectory()) {
          setIcon(PlatformIcons.DIRECTORY_CLOSED_ICON);
        } else {
          setIcon(path.getFileType().getIcon());
        }
      }
    }

    @Override
    protected void putParentPathImpl(Object value, String parentPath, FilePath self) {
      append(self.getPath(), SimpleTextAttributes.GRAYED_ATTRIBUTES);
    }
  }
}
