package bluej.stride.slots;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import bluej.stride.framedjava.slots.ExpressionSlot;
import bluej.stride.framedjava.slots.StructuredCompletionCalculator;
import bluej.utility.Utility;
import bluej.stride.framedjava.ast.JavaFragment.PosInSourceDoc;
import bluej.stride.framedjava.elements.CodeElement;
import bluej.stride.framedjava.slots.ExpressionCompletionCalculator;
import bluej.stride.generic.AssistContentThreadSafe;
import bluej.stride.generic.InteractionManager;
import bluej.stride.slots.SuggestionList.SuggestionDetailsWithHTMLDoc;
import bluej.stride.slots.SuggestionList.SuggestionListListener;
import bluej.utility.javafx.FXPlatformConsumer;
import javafx.application.Platform;
import threadchecker.OnThread;
import threadchecker.Tag;

public class TypeCompletionCalculator
implements StructuredCompletionCalculator{    
   private final InteractionManager editor;
   
   private final Class<?> superType; 
   private final Set<InteractionManager.Kind> kinds = new HashSet<>();
   
   private List<AssistContentThreadSafe> acs;
    
   
   public TypeCompletionCalculator(InteractionManager editor)
   {
      this(editor, (Class<?>)null);     
      }
    
   
   public TypeCompletionCalculator(InteractionManager editor, Class<?> superType)
   {        
      this.editor = editor;
       
      this.superType = superType;
      if (superType == null)
      kinds.addAll(Arrays.asList(InteractionManager.Kind.values()));
       
      else{ 
         kinds.addAll(Arrays.asList(InteractionManager.Kind.CLASS_FINAL, InteractionManager.Kind.INTERFACE, InteractionManager.Kind.CLASS_NON_FINAL));
         }     
      }
    
   
   public TypeCompletionCalculator(InteractionManager editor, InteractionManager.Kind kind)
   {        
      this.editor = editor;
       
      this.superType = null;
      this.kinds.add(kind);     
      }

   
   private static final Map<String, List<String>> commonTypes = new HashMap<>();
   
   private static final Map<String, List<String>> boxedTypes = new HashMap<>();
   
   static {
   commonTypes.put(null, Arrays.asList("boolean", "char", "double", "int", "void"));
   commonTypes.put("greenfoot", Arrays.asList("Actor", "GreenfootImage", "GreenfootSound", "MouseInfo", "UserInfo", "World"));
   commonTypes.put("java.lang", Arrays.asList("Exception", "Object", "String"));
   commonTypes.put("java.util", Arrays.asList("ArrayList", "HashMap", "HashSet", "LinkedList", "List", "Map", "Set"));
   boxedTypes.put("java.lang", Arrays.asList("Boolean", "Character", "Double", "Float", "Integer"));     
   }

   
public static SuggestionList.SuggestionShown getRarity(AssistContentThreadSafe ac, boolean boxedAsCommon)
   {
   switch (ac.getKind())
       {            
      case TYPE:
      if (boxedAsCommon && boxedTypes.containsKey(ac.getPackage()) && boxedTypes.get(ac.getPackage()).contains(ac.getName()) )
               {                    
         return SuggestionList.SuggestionShown.COMMON;                 
         }

      else if (commonTypes.containsKey(ac.getPackage()))
               {
         return commonTypes.get(ac.getPackage()).contains(ac.getName()) ? SuggestionList.SuggestionShown.COMMON : SuggestionList.SuggestionShown.RARE;                 
         }
               

      else
               {                    
         return SuggestionList.SuggestionShown.COMMON;                 
         }
           
      default:
               
      throw new IllegalStateException();         
      }     
   }
    
   
@Override
@OnThread(Tag.FXPlatform)
   
public void withCalculatedSuggestionList(PosInSourceDoc pos, ExpressionSlot<?> completing,
                                            
CodeElement codeEl, SuggestionListListener listener, String targetType, boolean completingStartOfSlot, FXPlatformConsumer<SuggestionList> handler) {         
   HashSet<InteractionManager.Kind> curKinds = new HashSet<>(kinds);
       
   
   
   if (!completingStartOfSlot)
   curKinds.remove(InteractionManager.Kind.PRIMITIVE);
   editor.withTypes(superType, true, curKinds, acs -> {
   Platform.runLater(() ->
           {                
      this.acs = new ArrayList<>(acs.values());
      this.acs.removeIf(ac -> !ac.accessibleFromPackage(""));
      this.acs.sort(Comparator.comparing(AssistContentThreadSafe::getName));
               
      List<SuggestionDetailsWithHTMLDoc> suggestions = Utility.mapList(this.acs, ac -> new SuggestionDetailsWithHTMLDoc(ac.getName(), getRarity(ac, !completingStartOfSlot), ac.getDocHTML()));
               
      SuggestionList suggestionDisplay = new SuggestionList(editor, suggestions, null, SuggestionList.SuggestionShown.COMMON, null, listener);
      handler.accept(suggestionDisplay);             
      });
   });
}
    
   
@Override
   
public String getName(int selected)
   {
   return acs.get(selected).getName();     
   }

   
@Override
   
public List getParams(int selected)
   {        
   
   return null;     
   }

   
@Override
   
public char getOpening(int selected)
   {        
   return '<';     
   } 
}
top, use, map, class TypeCompletionCalculator

.   TypeCompletionCalculator
.   TypeCompletionCalculator
.   TypeCompletionCalculator
.   getRarity
.   withCalculatedSuggestionList
.   getName
.   getParams
.   getOpening




161 neLoCode + 0 LoComm