/*
 * Copyright 2000-2012 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.packaging.impl.compiler;

import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.packaging.elements.IncrementalCompilerInstructionCreator;
import com.intellij.packaging.elements.PackagingFileFilter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

/**
 * @author nik
 */
public abstract class IncrementalCompilerInstructionCreatorBase implements IncrementalCompilerInstructionCreator {
  protected final ArtifactsProcessingItemsBuilderContext myContext;

  public IncrementalCompilerInstructionCreatorBase(ArtifactsProcessingItemsBuilderContext context) {
    myContext = context;
  }

  public void addDirectoryCopyInstructions(@NotNull VirtualFile directory) {
    addDirectoryCopyInstructions(directory, null);
  }

  public void addDirectoryCopyInstructions(@NotNull VirtualFile directory, @Nullable PackagingFileFilter filter) {
    ProjectFileIndex index = ProjectRootManager.getInstance(myContext.getCompileContext().getProject()).getFileIndex();
    final boolean copyExcluded = index.isIgnored(directory);
    collectInstructionsRecursively(directory, this, filter, index, FileTypeManager.getInstance(), copyExcluded);
  }

  private static final Key<IncrementalCompilerInstructionCreatorBase> INSTRUCTION_CREATOR = Key.create("pkg.compiler.instruction.creator");

  private static void collectInstructionsRecursively(VirtualFile directory,
                                                     final IncrementalCompilerInstructionCreatorBase creator,
                                                     final PackagingFileFilter filter,
                                                     final ProjectFileIndex index,
                                                     final FileTypeManager fileTypeManager,
                                                     final boolean copyExcluded) {
    VfsUtilCore.visitChildrenRecursively(directory, new VirtualFileVisitor(VirtualFileVisitor.SKIP_ROOT) {
      { set(INSTRUCTION_CREATOR, creator); }

      @Override
      public boolean visitFile(@NotNull VirtualFile child) {
        if (copyExcluded) {
          if (fileTypeManager.isFileIgnored(child)) return false;
        }
        else {
          if (index.isIgnored(child)) return false;
        }

        final IncrementalCompilerInstructionCreatorBase creator = get(INSTRUCTION_CREATOR);
        if (filter == null || filter.accept(child, creator.myContext.getCompileContext())) {
          if (!child.isDirectory()) {
            creator.addFileCopyInstruction(child, child.getName());
          }
          else {
            set(INSTRUCTION_CREATOR, creator.subFolder(child.getName()));
          }
        }

        return true;
      }
    });
  }

  @Override
  public abstract IncrementalCompilerInstructionCreatorBase subFolder(@NotNull String directoryName);

  public IncrementalCompilerInstructionCreator subFolderByRelativePath(@NotNull String relativeDirectoryPath) {
    final List<String> folders = StringUtil.split(relativeDirectoryPath, "/");
    IncrementalCompilerInstructionCreator current = this;
    for (String folder : folders) {
      current = current.subFolder(folder);
    }
    return current;
  }
}

@@ -1870,16 +1870,22 @@
 ) %7B%0A    
+final 
 ProjectF
@@ -2123,39 +2123,8 @@
 dex,
- FileTypeManager.getInstance(),
  cop
@@ -2641,100 +2641,8 @@
 ex,%0A
-                                                     final FileTypeManager fileTypeManager,%0A
     
@@ -2716,24 +2716,99 @@
 Excluded) %7B%0A
+    final FileTypeManager fileTypeManager = FileTypeManager.getInstance();%0A
     VfsUtilC
@@ -3322,19 +3322,20 @@
 ter 
-=
+!
 = null 
-%7C%7C 
+&& !
 filt
@@ -3391,24 +3391,57 @@
 ext())) %7B%0A  
+        return false;%0A        %7D%0A%0A
         if (
@@ -3460,26 +3460,24 @@
 ectory()) %7B%0A
-  
           cr
@@ -3530,34 +3530,32 @@
 ame());%0A        
-  
 %7D%0A          else
@@ -3544,35 +3544,31 @@
   %7D%0A        
- 
- 
 else %7B%0A
-  
           se
@@ -3631,20 +3631,8 @@
 ));%0A
-          %7D%0A
     

Fix test