package org.intellij.lang.xpath.xslt.associations.impl;

import com.intellij.ide.projectView.ProjectViewNode;
import com.intellij.ide.projectView.impl.AbstractProjectTreeStructure;
import com.intellij.ide.projectView.impl.GroupByTypeComparator;
import com.intellij.ide.projectView.impl.ProjectTreeBuilder;
import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
import com.intellij.ide.util.PsiElementListCellRenderer;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.ide.util.treeView.NodeRenderer;
import com.intellij.ide.util.treeView.TreeState;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Progressive;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Disposer;
import com.intellij.psi.PsiFile;
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.IconUtil;
import com.intellij.util.config.StorageAccessors;
import com.intellij.util.ui.UIUtil;
import icons.XpathIcons;
import org.intellij.lang.xpath.xslt.XsltSupport;
import org.intellij.lang.xpath.xslt.associations.FileAssociationsManager;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class AssociationsEditor {
  @NonNls private static final String DIVIDER_PROPORTION = "dividerProportion";

  private JPanel myComponent;
  private JBList myList;
  private Tree myTree;
  private Splitter mySplitter;
  private final StorageAccessors myProperties = StorageAccessors.createGlobal("AssociationsEditor");

  private final AssociationsModel myListModel;
  private final TransactionalManager myManager;
  private final ProjectTreeBuilder myBuilder;

  public AssociationsEditor(final Project project, final TreeState oldState) {
    myManager = ((FileAssociationsManagerImpl)FileAssociationsManager.getInstance(project)).getTempManager();

    initUI();

    final DefaultTreeModel treeModel = new DefaultTreeModel(new DefaultMutableTreeNode());
    myTree.setModel(treeModel);

    myBuilder = new ProjectTreeBuilder(project, myTree, treeModel, new MyGroupByTypeComparator(), new MyProjectStructure(project));

    myTree.setCellRenderer(new MyNodeRenderer(myManager));
    new TreeSpeedSearch(myTree);

    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        ApplicationManager.getApplication().invokeLater(new Runnable() {
          @Override
          public void run() {
            if (oldState == null) {
              expandTree(treeModel);
            }
            else {
              oldState.applyTo(myTree);
            }
          }
        });
      }
    });

    myListModel = new AssociationsModel(myTree, myManager);
    myListModel.addListDataListener(new ListDataListener() {
      public void intervalAdded(ListDataEvent listDataEvent) {
        myTree.invalidate();
        myTree.repaint();
      }

      public void intervalRemoved(ListDataEvent listDataEvent) {
        myTree.invalidate();
        myTree.repaint();
      }

      public void contentsChanged(ListDataEvent listDataEvent) {
      }
    });
    myList.setModel(myListModel);

  }

  private void initUI() {
    myComponent = new JPanel(new BorderLayout());
    mySplitter = new Splitter(false, 0.3f);
    myComponent.add(mySplitter, BorderLayout.CENTER);

    JPanel leftPanel = new JPanel(new BorderLayout());
    leftPanel.setBorder(IdeBorderFactory.createTitledBorder("Project XSLT Files", false, new Insets(0, 0, 0, 0)));
    myTree = new Tree();
    myTree.setRootVisible(false);
    myTree.setShowsRootHandles(false);
    leftPanel.add(new JBScrollPane(myTree), BorderLayout.CENTER);
    mySplitter.setFirstComponent(leftPanel);

    myList = new JBList();
    myList.setCellRenderer(new MyCellRenderer());
    myList.setMinimumSize(new Dimension(120, 200));
    myList.getEmptyText().setText("No associated files");
    JPanel rightPanel = ToolbarDecorator.createDecorator(myList)
      .addExtraAction(AnActionButton.fromAction(new AddAssociationActionWrapper()))
      .addExtraAction(AnActionButton.fromAction(new RemoveAssociationAction()))
      .disableUpDownActions().disableAddAction().disableRemoveAction().createPanel();
    UIUtil.addBorder(rightPanel, IdeBorderFactory.createTitledBorder("Associated Files", false, new Insets(0, 0, 0, 0)));
    mySplitter.setSecondComponent(rightPanel);

    final float dividerProportion = myProperties.getFloat(DIVIDER_PROPORTION, 0.3f);
    mySplitter.setProportion(dividerProportion);
  }

  private void expandTree(DefaultTreeModel newModel) {
    final TreePath rootPath = new TreePath(newModel.getRoot());

    final Object element = myBuilder.getTreeStructure().getRootElement();
    myBuilder.batch(new Progressive() {
      @Override
      public void run(@NotNull ProgressIndicator indicator) {
        myBuilder.expand(element, null);
        myBuilder.expand(myBuilder.getTreeStructure().getChildElements(element), null);
      }
    });

    myTree.setSelectionPath(rootPath);
    myTree.scrollRectToVisible(new Rectangle(new Point(0, 0)));
  }

  public TreeState getState() {
    return TreeState.createOn(myTree);
  }

  public JPanel getComponent() {
    return myComponent;
  }

  @Nullable
  static Object getTreeSelection(JTree tree) {
    final TreePath[] selectionPath = tree.getSelectionPaths();
    if (selectionPath == null || selectionPath.length != 1) return null;
    final Object component = selectionPath[0].getLastPathComponent();
    return getObject(component);
  }

  @Nullable
  private static Object getObject(Object component) {
    if (!(component instanceof DefaultMutableTreeNode)) return null;
    final DefaultMutableTreeNode node = ((DefaultMutableTreeNode)component);
    final Object userObject = node.getUserObject();
    if (!(userObject instanceof ProjectViewNode)) return null;
    return ((ProjectViewNode<?>)userObject).getValue();
  }

  public boolean isModified() {
    return myManager.isModified();
  }

  public void apply() {
    myManager.applyChanges();
  }

  public void reset() {
    myManager.reset();
    final Object selection = getTreeSelection(myTree);
    myListModel.update(selection instanceof PsiFile ? ((PsiFile)selection) : null);
  }

  public void dispose() {
    myProperties.setFloat(DIVIDER_PROPORTION, mySplitter.getProportion());
    Disposer.dispose(myBuilder);
    myManager.dispose();
  }

  public void select(final PsiFile file) {
    myBuilder.getReady(this).doWhenDone(new Runnable() {
      @Override
      public void run() {
        myBuilder.select(file, file.getVirtualFile(), true);
      }
    });
  }

  class AddAssociationActionWrapper extends AddAssociationAction {
    public AddAssociationActionWrapper() {
      super(myManager);
    }

    public void actionPerformed(AnActionEvent e) {
      final PsiFile selection = (PsiFile)getTreeSelection(myTree);
      addAssociation(selection);
      myListModel.update(selection);
    }

    public void update(AnActionEvent e) {
      e.getPresentation().setEnabled(getTreeSelection(myTree) instanceof PsiFile);
    }
  }

  class RemoveAssociationAction extends AnAction {
    public RemoveAssociationAction() {
      super("Remove", "Remove Association", IconUtil.getRemoveIcon());
    }

    public void actionPerformed(AnActionEvent e) {
      final PsiFile selection = (PsiFile)getTreeSelection(myTree);
      final PsiFile listSelection = (PsiFile)getListSelection();

      myManager.removeAssociation(selection, listSelection);
      myListModel.update(selection);
    }

    public void update(AnActionEvent e) {
      e.getPresentation().setEnabled(getListSelection() instanceof PsiFile);
    }

    private Object getListSelection() {
      return myList.getSelectedValue();
    }
  }

  private static class MyGroupByTypeComparator extends GroupByTypeComparator {
    public MyGroupByTypeComparator() {
      super(true);
    }

    protected boolean isSortByType() {
      return false;
    }
  }

  @SuppressWarnings({"ALL"})
  private static class MyProjectStructure extends AbstractProjectTreeStructure {

    public MyProjectStructure(Project project) {
      super(project);
    }

    public List getProviders() {
      return Collections.EMPTY_LIST;
    }

    public Object[] getChildElements(Object obj) {
      final Object[] childElements = super.getChildElements(obj);
      List l = new ArrayList(childElements.length);
      for (Object o : childElements) {
        if (o instanceof ProjectViewNode) {
          final ProjectViewNode node = (ProjectViewNode)o;
          final Object element = node.getValue();
          if (element instanceof PsiFile) {
            if (XsltSupport.isXsltFile((PsiFile)element)) {
              l.add(o);
            }
          }
          else {
            l.add(o);
          }
        }
      }
      return l.size() != childElements.length ? (Object[])l.toArray(new Object[l.size()]) : childElements;
    }

    public boolean isShowMembers() {
      return false;
    }

    public boolean isShowModules() {
      return true;
    }

    public boolean isFlattenPackages() {
      return true;
    }

    public boolean isAbbreviatePackageNames() {
      return false;
    }

    public boolean isHideEmptyMiddlePackages() {
      return true;
    }

    public boolean isShowLibraryContents() {
      return false;
    }
  }

  static class AssociationsModel extends AbstractListModel implements TreeSelectionListener {
    private final Tree myTree;
    private final FileAssociationsManager myManager;
    private PsiFile[] myFiles;

    public AssociationsModel(Tree tree, FileAssociationsManager manager) {
      myTree = tree;
      myManager = manager;
      myFiles = PsiFile.EMPTY_ARRAY;
      myTree.addTreeSelectionListener(this);
    }

    public int getSize() {
      return myFiles.length;
    }

    public Object getElementAt(int index) {
      return myFiles[index];
    }

    public void valueChanged(TreeSelectionEvent e) {
      final Object selection = getTreeSelection(myTree);
      if (selection instanceof PsiFile) {
        update((PsiFile)selection);
      }
      else {
        update(null);
      }
    }

    public void update(@Nullable PsiFile selection) {
      final int oldSize = myFiles.length;
      myFiles = PsiFile.EMPTY_ARRAY;
      if (myFiles.length != oldSize) fireIntervalRemoved(this, 0, oldSize - 1);
      if (selection != null) {
        myFiles = myManager.getAssociationsFor(selection);
        if (myFiles.length > 0) fireIntervalAdded(this, 0, myFiles.length - 1);
      }
    }
  }

  private static class MyNodeRenderer extends NodeRenderer {
    private final DefaultMutableTreeNode myTemp = new DefaultMutableTreeNode();
    private final FileAssociationsManager myManager;

    public MyNodeRenderer(FileAssociationsManager manager) {
      myManager = manager;
    }

    public void customizeCellRenderer(JTree tree,
                                      Object value,
                                      boolean selected,
                                      boolean expanded,
                                      boolean leaf,
                                      int row,
                                      boolean hasFocus) {
      final Object object = getObject(value);
      if (object instanceof PsiFile) {
        final PsiFile file = (PsiFile)object;
        final Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
        if (myManager.getAssociationsFor(file).length > 0) {
          //noinspection unchecked
          myTemp.setUserObject(new MyNodeDescriptor((NodeDescriptor<PsiFileNode>)userObject));
          super.customizeCellRenderer(tree, myTemp, selected, expanded, leaf, row, hasFocus);
          return;
        }
      }
      super.customizeCellRenderer(tree, value, selected, expanded, leaf, row, hasFocus);
    }

    private static class MyNodeDescriptor extends NodeDescriptor<PsiFileNode> {
      private final PsiFileNode myNode;

      public MyNodeDescriptor(NodeDescriptor<PsiFileNode> nodeDescriptor) {
        super(nodeDescriptor.getProject(), null);
        myName = nodeDescriptor.toString();
        setIcon(LayeredIcon.create(nodeDescriptor.getIcon(), XpathIcons.Association_small));
        myColor = nodeDescriptor.getColor();
        myNode = nodeDescriptor.getElement();
      }

      public boolean update() {
        return false;
      }

      public PsiFileNode getElement() {
        return myNode;
      }
    }
  }

  private static class MyCellRenderer extends PsiElementListCellRenderer<PsiFile> {
    public String getElementText(PsiFile file) {
      return file.getName();
    }

    protected String getContainerText(PsiFile psiElement, String string) {
      //noinspection ConstantConditions
      return "(" + psiElement.getVirtualFile().getParent().getPresentableUrl() + ")";
    }

    protected int getIconFlags() {
      return 0;
    }
  }
}
