/*
 * Copyright 2000-2011 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.ide.favoritesTreeView;

import com.intellij.ProjectTopics;
import com.intellij.ide.CopyPasteUtil;
import com.intellij.ide.projectView.BaseProjectTreeBuilder;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.ProjectViewPsiTreeChangeListener;
import com.intellij.ide.projectView.impl.ProjectAbstractTreeStructureBase;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.AbstractTreeStructure;
import com.intellij.ide.util.treeView.AbstractTreeUpdater;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootAdapter;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vcs.FileStatusListener;
import com.intellij.openapi.vcs.FileStatusManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

/**
 * @author Konstantin Bulenkov
 */
public class FavoritesViewTreeBuilder extends BaseProjectTreeBuilder {
  private final ProjectViewPsiTreeChangeListener myPsiTreeChangeListener;
  private final FileStatusListener myFileStatusListener;
  private final CopyPasteUtil.DefaultCopyPasteListener myCopyPasteListener;
  private final FavoritesListener myFavoritesListener;

  public FavoritesViewTreeBuilder(@NotNull Project project,
                                  JTree tree,
                                  DefaultTreeModel treeModel,
                                  ProjectAbstractTreeStructureBase treeStructure) {
    super(project,
          tree,
          treeModel,
          treeStructure,
          new FavoritesComparator(ProjectView.getInstance(project), FavoritesProjectViewPane.ID));
    final MessageBusConnection bus = myProject.getMessageBus().connect(this);
    myPsiTreeChangeListener = new ProjectViewPsiTreeChangeListener(myProject) {
      @Override
      protected DefaultMutableTreeNode getRootNode() {
        return FavoritesViewTreeBuilder.this.getRootNode();
      }

      @Override
      protected AbstractTreeUpdater getUpdater() {
        return FavoritesViewTreeBuilder.this.getUpdater();
      }

      @Override
      protected boolean isFlattenPackages() {
        return getStructure().isFlattenPackages();
      }

      @Override
      protected void childrenChanged(PsiElement parent, final boolean stopProcessingForThisModificationCount) {
        if (findNodeByElement(parent) == null) {
          queueUpdate(true);
        }
        else {
          super.childrenChanged(parent, true);
        }
      }
    };
    bus.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
      @Override
      public void rootsChanged(ModuleRootEvent event) {
        queueUpdate(true);
      }
    });
    PsiManager.getInstance(myProject).addPsiTreeChangeListener(myPsiTreeChangeListener);
    myFileStatusListener = new MyFileStatusListener();
    FileStatusManager.getInstance(myProject).addFileStatusListener(myFileStatusListener);
    myCopyPasteListener = new CopyPasteUtil.DefaultCopyPasteListener(getUpdater());
    CopyPasteManager.getInstance().addContentChangedListener(myCopyPasteListener);

    myFavoritesListener = new FavoritesListener() {
      @Override
      public void rootsChanged() {
        updateFromRoot();
      }

      @Override
      public void listAdded(String listName) {
        updateFromRoot();
      }

      @Override
      public void listRemoved(String listName) {
        updateFromRoot();
      }
    };
    initRootNode();
    FavoritesManager.getInstance(myProject).addFavoritesListener(myFavoritesListener);
  }

  @NotNull
  public FavoritesTreeStructure getStructure() {
    final AbstractTreeStructure structure = getTreeStructure();
    assert structure instanceof FavoritesTreeStructure;
    return (FavoritesTreeStructure)structure;
  }

  public AbstractTreeNode getRoot() {
    final Object rootElement = getRootElement();
    assert rootElement instanceof AbstractTreeNode;
    return (AbstractTreeNode)rootElement;
  }

  @Override
  public void updateFromRoot() {
    updateFromRootCB();
  }

  @Override
  @NotNull
  public ActionCallback updateFromRootCB() {
    getStructure().rootsChanged();
    if (isDisposed()) return new ActionCallback.Done();
    getUpdater().cancelAllRequests();
    return super.updateFromRootCB();
  }

  @NotNull
  @Override
  public ActionCallback select(Object element, VirtualFile file, boolean requestFocus) {
    final DefaultMutableTreeNode node = findSmartFirstLevelNodeByElement(element);
    if (node != null) {
      return TreeUtil.selectInTree(node, requestFocus, getTree());
    }
    return super.select(element, file, requestFocus);
  }

  @Nullable
  private static DefaultMutableTreeNode findFirstLevelNodeWithObject(final DefaultMutableTreeNode aRoot, final Object aObject) {
    for (int i = 0; i < aRoot.getChildCount(); i++) {
      final DefaultMutableTreeNode child = (DefaultMutableTreeNode)aRoot.getChildAt(i);
      Object userObject = child.getUserObject();
      if (userObject instanceof FavoritesTreeNodeDescriptor) {
        if (Comparing.equal(((FavoritesTreeNodeDescriptor)userObject).getElement(), aObject)) {
          return child;
        }
      }
    }
    return null;
  }

  @Override
  protected Object findNodeByElement(Object element) {
    final Object node = findSmartFirstLevelNodeByElement(element);
    if (node != null) return node;
    return super.findNodeByElement(element);
  }

  @Nullable
  DefaultMutableTreeNode findSmartFirstLevelNodeByElement(final Object element) {
    for (Object child : getRoot().getChildren()) {
      AbstractTreeNode favorite = (AbstractTreeNode)child;
      Object currentValue = favorite.getValue();
      if (currentValue instanceof SmartPsiElementPointer) {
        currentValue = ((SmartPsiElementPointer)favorite.getValue()).getElement();
      }
       /*else if (currentValue instanceof PsiJavaFile) {
        final PsiClass[] classes = ((PsiJavaFile)currentValue).getClasses();
        if (classes.length > 0) {
          currentValue = classes[0];
        }
      }*/
      if (Comparing.equal(element, currentValue)) {
        final DefaultMutableTreeNode nodeWithObject =
          findFirstLevelNodeWithObject((DefaultMutableTreeNode)getTree().getModel().getRoot(), favorite);
        if (nodeWithObject != null) {
          return nodeWithObject;
        }
      }
    }
    return null;
  }

  @Override
  public final void dispose() {
    super.dispose();
    FavoritesManager.getInstance(myProject).removeFavoritesListener(myFavoritesListener);

    PsiManager.getInstance(myProject).removePsiTreeChangeListener(myPsiTreeChangeListener);
    FileStatusManager.getInstance(myProject).removeFileStatusListener(myFileStatusListener);
    CopyPasteManager.getInstance().removeContentChangedListener(myCopyPasteListener);
  }

  @Override
  protected boolean isAlwaysShowPlus(NodeDescriptor nodeDescriptor) {
    final Object[] childElements = getStructure().getChildElements(nodeDescriptor);
    return childElements != null && childElements.length > 0;
  }

  @Override
  protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) {
    return nodeDescriptor.getParentDescriptor() == null;
  }

  private final class MyFileStatusListener implements FileStatusListener {
    @Override
    public void fileStatusesChanged() {
      queueUpdateFrom(getRootNode(), false);
    }

    @Override
    public void fileStatusChanged(@NotNull VirtualFile vFile) {
      PsiElement element;
      PsiManager psiManager = PsiManager.getInstance(myProject);
      if (vFile.isDirectory()) {
        element = psiManager.findDirectory(vFile);
      }
      else {
        element = psiManager.findFile(vFile);
      }

      if (!getUpdater().addSubtreeToUpdateByElement(element) &&
          element instanceof PsiFile &&
          ((PsiFile)element).getFileType() == StdFileTypes.JAVA) {
        getUpdater().addSubtreeToUpdateByElement(((PsiFile)element).getContainingDirectory());
      }
    }
  }
}

