package bluej.stride.slots;

import javafx.animation.FadeTransition;
import javafx.beans.binding.DoubleExpression;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.util.Duration;

import bluej.utility.javafx.FXPlatformConsumer;
import bluej.utility.javafx.JavaFXUtil;
import bluej.utility.javafx.ScalableHeightLabel;

class SuggestionCell extends ListCell<SuggestionList.SuggestionListItem> implements ChangeListener<Object>{    
   private final Label special;
   
   private final Label type;
   
   private final Label prefix;
   
   private final Label matching;
   
   private final Label next; 
   private final Label suffix;
   
   private final Label fixedPostSuffix;
   
   private final BorderPane pane;
   
   private final HBox hbox;

   
   public SuggestionCell(DoubleExpression typeWidth, FXPlatformConsumer<SuggestionList.SuggestionListItem> clickListener)
   {        
      this.special = new Label();
       
      this.type = new Label();
      this.type.minWidthProperty().bind(typeWidth);
      this.type.maxWidthProperty().bind(typeWidth);
      this.type.setEllipsisString("\u2026");
       
      this.prefix = new Label();
       
      this.matching = new Label();
       
      this.next = new Label();
       
      this.suffix = new Label();
       
      this.fixedPostSuffix = new Label();

      JavaFXUtil.addStyleClass(this, "suggestion-cell");
      JavaFXUtil.addStyleClass(this.type, "suggestion-type");
      JavaFXUtil.addStyleClass(prefix, "suggestion-prefix");
      JavaFXUtil.addStyleClass(matching, "suggestion-matching");
      JavaFXUtil.addStyleClass(next, "suggestion-next");
      JavaFXUtil.addStyleClass(suffix, "suggestion-suffix");
      prefix.setMinWidth(Region.USE_PREF_SIZE);
      matching.setMinWidth(Region.USE_PREF_SIZE);
      next.setMinWidth(Region.USE_PREF_SIZE);
       
      
      suffix.setMinWidth(0.0);
      fixedPostSuffix.setMinWidth(0.0);
        
      special.setMaxWidth(9999.0);
      special.setText("Related:");
      JavaFXUtil.addStyleClass(special, "suggestion-similar-heading");

       
      hbox = new HBox();
      hbox.getChildren().addAll(this.type, prefix, matching, next, suffix, fixedPostSuffix);
      hbox.setSpacing(0);
        
       
      
      
      pane = new BorderPane();
      pane.setCenter(hbox);
      JavaFXUtil.addStyleClass(pane, "suggestion");

      pane.setOnMouseClicked(e -> clickListener.accept(itemProperty().get()));

      itemProperty().addListener((_obs, oldItem, item) -> {
      if (oldItem != null)
           {
         oldItem.eligibleAt.removeListener(this);
         oldItem.eligibleLength.removeListener(this);
         oldItem.eligibleCanTab.removeListener(this);
         oldItem.highlighted.removeListener(this);             
         }

      update(item);

      if (item != null)
           {
         item.eligibleAt.addListener(this);
         item.eligibleLength.addListener(this);
         item.eligibleCanTab.addListener(this);
         item.highlighted.addListener(this);             
         }         
      });
   setGraphic(pane);     
   }

   
private void update(SuggestionList.SuggestionListItem item)
   {
   if (item != null && item.index == -1)
       {
      pane.setCenter(special);
      pane.setRight(null);         
      }
       

   else
       {
      pane.setCenter(hbox);         
      }

   if (item != null && item.index != -1)
       { 
      update(item.getDetails().choice, item.getDetails().suffix, item.getDetails().type, item.typeMatch, item.direct, item.eligibleAt.get(), item.eligibleLength.get(), item.eligibleCanTab.get(), item.highlighted.get());         
      }
       

   else
       {
      update("", "", "", false, true, 0, 0, false, false);         
      }     
   }

   
private void update(String text, String unmatchableSuffix, String type, boolean typeMatch, boolean direct, int at, int len, boolean canTab, boolean highlighted)
   {
   this.type.setText(type);
   JavaFXUtil.setPseudoclass("bj-match", typeMatch, this.type);
   if (text.length() >= 1)
       {
      this.next.setText(text.substring(0, 1));
      this.suffix.setText(text.substring(1));         
      }
       

   else
       {
      this.next.setText("");
      this.suffix.setText("");         
      }
   this.fixedPostSuffix.setText(unmatchableSuffix);
   JavaFXUtil.setPseudoclass("bj-suggestion-similar", !direct, pane);

   JavaFXUtil.setPseudoclass("bj-suggestion-highlight", highlighted, pane);
        
   prefix.setText(text.substring(0, at));
   int end = Math.min(at + len, text.length());
   matching.setText(text.substring(at, end));
   String rest = text.substring(end);
   if (rest.length() >= 1)
       {
      next.setText(rest.substring(0, 1));
      suffix.setText(rest.substring(1));         
      }
       

   else
       {
      next.setText("");
      suffix.setText("");         
      }     
   }

   


@Override
   
public void changed(ObservableValue<?> observable, Object oldValue, Object newValue)
   {
   update(itemProperty().get());     
   } 
}

.   SuggestionCell
.   update
.   update
.   changed




182 neLoCode + 0 LoComm