package bluej.stride.framedjava.frames;

import bluej.Config;
import bluej.editor.stride.BirdseyeManager;
import bluej.parser.entity.EntityResolver;
import bluej.stride.framedjava.ast.JavadocUnit;
import bluej.stride.framedjava.ast.NameDefSlotFragment;
import bluej.stride.framedjava.ast.TypeSlotFragment;
import bluej.stride.framedjava.elements.ImportElement;
import bluej.stride.framedjava.elements.CodeElement;
import bluej.stride.framedjava.elements.InterfaceElement;
import bluej.stride.framedjava.slots.TypeSlot;
import bluej.stride.generic.ExtensionDescription;
import bluej.stride.generic.Frame;
import bluej.stride.generic.FrameCanvas;
import bluej.stride.generic.FrameCursor;
import bluej.stride.generic.FrameContentRow;
import bluej.stride.generic.FrameTypeCheck;
import bluej.stride.generic.InteractionManager;
import bluej.stride.generic.TopLevelDocumentMultiCanvasFrame;
import bluej.stride.operations.CopyFrameAsImageOperation;
import bluej.stride.operations.CopyFrameAsJavaOperation;
import bluej.stride.operations.CopyFrameAsStrideOperation;
import bluej.stride.operations.CustomFrameOperation;
import bluej.stride.operations.FrameOperation;
import bluej.stride.slots.EditableSlot;
import bluej.stride.slots.ExtendsList;
import bluej.stride.slots.Focus;
import bluej.stride.slots.HeaderItem;
import bluej.stride.slots.SlotLabel;
import bluej.utility.Utility;
import bluej.utility.javafx.SharedTransition;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import threadchecker.OnThread;
import threadchecker.Tag;

public class InterfaceFrame extends TopLevelDocumentMultiCanvasFrame<InterfaceElement>{    
   private final ExtendsList extendsList;

   
   public InterfaceFrame(InteractionManager editor, EntityResolver projectResolver, String packageName,
                         
   List<ImportElement> imports, JavadocUnit documentation, NameDefSlotFragment interfaceName,
                         
   List<TypeSlotFragment> extendsTypes, boolean enabled)
   {
      super(editor, projectResolver, "interface", "interface-", packageName, imports, documentation, interfaceName, enabled);

       
      extendsList = new ExtendsList(this, () -> {
           
      TypeSlot s = new TypeSlot(editor, this, this, getHeaderRow(), TypeSlot.Role.INTERFACE, "interface-");
      s.setSimplePromptText("interface type");
           
      return s;         
      }, () -> getCanvases().findFirst().ifPresent(c -> c.getFirstCursor().requestFocus()), editor);
   extendsTypes.forEach(t -> this.extendsList.addTypeSlotAtEnd(t.getContent(), false));
   extendsList.focusedProperty().addListener((obs, oldVal, newVal) -> {
   if (newVal)
   extendsList.ensureAtLeastOneSlot();
           
   else{ extendsList.clearIfSingleEmpty();
      }         
   });
getHeaderRow().bindContentsConcat(FXCollections.<ObservableList<? extends HeaderItem>>observableArrayList(
FXCollections.observableArrayList(headerCaptionLabel),
FXCollections.observableArrayList(paramName),
extendsList.getHeaderItems()
       
));     
}

   
protected Frame findASpecialMethod()
   {        
   return null;     
   }

   
@Override
   
public synchronized void regenerateCode()
   {
   List<CodeElement> fields = getMembers(fieldsCanvas);
   List<CodeElement> methods = getMembers(methodsCanvas);
   List<ImportElement> imports = Utility.mapList(getMembers(importCanvas), e -> (ImportElement)e);
       
   element = new InterfaceElement(this, projectResolver, paramName.getSlotElement(), extendsList.getTypes(),
               
   fields, methods, new JavadocUnit(getDocumentation()), packageNameLabel == null ? null : packageNameLabel.getText(),
   imports, frameEnabledProperty.get());     
   }

   
@Override
@OnThread(value = Tag.Any, ignoreParent = true)
   
public synchronized InterfaceElement getCode()
   {        
   return element;     
   }

   
@Override
   
public List getContextOperations()
   {        
   ArrayList<FrameOperation> ops = new ArrayList<>();
       
   ops.add(new CopyFrameAsStrideOperation(editor));
       
   ops.add(new CopyFrameAsImageOperation(editor));
       
   ops.add(new CopyFrameAsJavaOperation(editor));
       
   ops.add(new CustomFrameOperation(getEditor(), "addExtends", Arrays.asList(Config.getString("frame.class.add.extends")),
   EditableSlot.MenuItemOrder.TOGGLE_EXTENDS, this, () -> extendsList.addTypeSlotAtEnd("", true)));

   final List<TypeSlotFragment> types = extendsList.getTypes();
       
   for (int i = 0; i < types.size(); i++)
       {            
      final int index = i;
      TypeSlotFragment type = types.get(i);
           
      CustomFrameOperation removeOp = new CustomFrameOperation(getEditor(), "removeExtends",
      Arrays.asList(Config.getString("frame.class.remove.extends.from").replace("$", type.getContent())), EditableSlot.MenuItemOrder.TOGGLE_EXTENDS,
      this, () -> extendsList.removeIndex(index));
      removeOp.setWideCustomItem(true);
      ops.add(removeOp);         
      }

       
   return ops;     
   }

   
@Override
   
public List getAvailableExtensions(FrameCanvas canvas, FrameCursor cursorInCanvas)
   {        
   
   ExtensionDescription extendsExtension = null;
   if (fieldsCanvas.equals(canvas) || canvas == null) {            
      extendsExtension = new ExtensionDescription(StrideDictionary.EXTENDS_EXTENSION_CHAR,  Config.getString("frame.class.add.extends.declaration"),
      () -> extendsList.addTypeSlotAtEnd("", true), true, ExtensionDescription.ExtensionSource.INSIDE_FIRST,
                   
      ExtensionDescription.ExtensionSource.MODIFIER);         
      }
   return Utility.nonNulls(Arrays.asList(extendsExtension));     
   }

   
@Override
   
public void saved()
   {        
   
   
        
   }

   
@Override
   
public BirdseyeManager prepareBirdsEyeView(SharedTransition animate)
   {        
   
   return null;     
   }

   
@Override
   
public void addExtendsClassOrInterface(String className)
   {
   extendsList.addTypeSlotAtEnd(className, false);     
   }

   
@Override
   
public void addImplements(String className)
   {        
   throw new UnsupportedOperationException();     
   }

   
@Override
   
public void removeExtendsClass()
   {        
   throw new UnsupportedOperationException();     
   }

   
@Override
   
public void removeExtendsOrImplementsInterface(String interfaceName)
   {
   List<TypeSlotFragment> extendsTypes = extendsList.getTypes();
       
   for (int i = 0; i < extendsTypes.size(); i++)
       {
      if (extendsTypes.get(i).getContent().equals(interfaceName))
           {
         extendsList.removeIndex(i);
               
         return;             
         }         
      }     
   }
    
   
@Override
   
public boolean canDoBirdseye()
   {        
   
   return false;     
   }

   
@Override
   
public void addDefaultConstructor()
   {        
   throw new IllegalAccessError();     
   }

   
@Override
   
public List getConstructors()
   {
   return Collections.emptyList();     
   }

   
@Override
   
public List getMethods()
   {
   return methodsCanvas.getBlocksSubtype(MethodProtoFrame.class);     
   }

   
@Override
   
public Stream getPersistentCanvases()
   {
   return getCanvases();
        
   }

   
@Override
   
public FrameTypeCheck check(FrameCanvas canvas)
   {
   if (canvas == fieldsCanvas)
   return StrideDictionary.checkInterfaceField();
   else if (canvas == methodsCanvas)
   return StrideDictionary.checkInterfaceMethod();
       
   else{ throw new IllegalStateException("Asking about canvas unknown to InterfaceFrame");
      }     
   }

   
@Override
   
public CanvasKind getChildKind(FrameCanvas c)
   {
   if (c == fieldsCanvas)
           
   return CanvasKind.FIELDS;
   else if (c == methodsCanvas)
           
   return CanvasKind.METHODS;
       
   else{ return CanvasKind.STATEMENTS;
      }      
   }

   
@Override
   
public void restore(InterfaceElement target)
   {
   paramName.setText(target.getName());
   extendsList.setTypes(target.getExtends());
   importCanvas.restore(target.getImports(), editor);
   fieldsCanvas.restore(target.getFields(), editor);
   methodsCanvas.restore(target.getMethods(), editor);     
   }

   
@Override
   
protected FrameContentRow makeHeader(String stylePrefix)
   {        
   return new FrameContentRow(this, stylePrefix) {            
      @Override
           
      public boolean focusRightEndFromNext()
           {
         extendsList.ensureAtLeastOneSlot();
         Utility.findLast(extendsList.getTypeSlots()).get().requestFocus(Focus.RIGHT);
               
         return true;             
         }         
      };
   }

   
@Override
   
protected List getLabelRows()
   {
   return Arrays.asList(importRow, fieldsLabelRow, methodsLabelRow);     
   }

   
@Override
   
protected List getCanvasLabels()
   {
   return Arrays.asList(importsLabel, fieldsLabel, methodsLabel);     
   } 
}

.   InterfaceFrame
.   HeaderItem>>observableArrayList
.   findASpecialMethod
.   regenerateCode
.   getCode
.   getContextOperations
.   getAvailableExtensions
.   saved
.   prepareBirdsEyeView
.   addExtendsClassOrInterface
.   addImplements
.   removeExtendsClass
.   removeExtendsOrImplementsInterface
.   canDoBirdseye
.   addDefaultConstructor
.   getConstructors
.   getMethods
.   getPersistentCanvases
.   check
.   getChildKind
.   restore
.   makeHeader
.   focusRightEndFromNext
.   getLabelRows
.   getCanvasLabels




340 neLoCode + 0 LoComm