package ui.components.pickers;

import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;

import java.util.*;

public class LabelPickerUILogic {

    private Stack<LabelPickerState> history = new Stack<>();
    private final Set<String> repoLabels;

    public LabelPickerUILogic(LabelPickerState state, Set<String> repoLabels) {
        this.repoLabels = repoLabels;
        history.push(state);
    }

    /**
     * Get a new state of LabelPicker after the user presses keyEvent resulting in currentString
     * @param keyEvent
     * @param currentString
     * @return new state of LabelPicker
     */
    public LabelPickerState getNewState(KeyEvent keyEvent, String currentString) {
        LabelPickerState currentState = history.peek();
        LabelPickerState newState;
        if (keyEvent.getCode() == KeyCode.UP || keyEvent.getCode() == KeyCode.KP_UP) {
            newState = handleKeyUp(currentState);
            history.push(newState);
        } else if (keyEvent.getCode() == KeyCode.DOWN || keyEvent.getCode() == KeyCode.KP_DOWN) {
            newState = handleKeyDown(currentState);
            history.push(newState);
        } else if (keyEvent.getCode() == KeyCode.SPACE) {
            newState = handleSpace(currentState, currentString);
            history.push(newState);
        } else if (keyEvent.getCode() == KeyCode.BACK_SPACE) {
            newState = handleBackSpace(currentString);
        } else {
            newState = handleCharAddition(currentState, currentString);
            history.push(newState);
        }
        assert newState != null;
        return newState;
    }

    private LabelPickerState handleKeyUp(LabelPickerState currentState) {
        history.pop();
        return currentState.previousSuggestion();
    }

    private LabelPickerState handleKeyDown(LabelPickerState currentState) {
        history.pop();
        return currentState.nextSuggestion();
    }

    private LabelPickerState handleSpace(LabelPickerState currentState, String currentString) {
        assert currentString.charAt(currentString.length() - 1) == ' ';
        String[] keywords = currentString.split("\\s+");
        if (keywords.length > 0 && !Character.isSpaceChar(currentString.charAt(currentString.length() - 2))) {
            //just confirmed a word
            return currentState.clearMatchedLabels().toggleLabel(keywords[keywords.length - 1]);
        }
        return currentState;
    }

    private LabelPickerState handleBackSpace(String currentString) {
        if (history.size() > 1) {
            history.pop();
        } else {
            assert currentString.length() == 0;
        }
        return history.peek();
    }

    private LabelPickerState handleCharAddition(LabelPickerState currentState, String currentString) {
        return currentState.updateMatchedLabels(repoLabels, currentString);
    }

}

@@ -210,24 +210,67 @@
  Stack%3C%3E();%0A
+    private LabelPickerState currentState;%0A
     private 
@@ -430,27 +430,28 @@
     
-history.push(
+currentState = 
 state
-)
 ;%0A  
@@ -746,64 +746,8 @@
 ) %7B%0A
-        LabelPickerState currentState = history.peek();%0A
     
@@ -918,44 +918,8 @@
 e);%0A
-            history.push(newState);%0A
     
@@ -1068,44 +1068,8 @@
 e);%0A
-            history.push(newState);%0A
     
@@ -1203,32 +1203,35 @@
     history.
-push(new
+add(current
 State);%0A    
@@ -1328,29 +1328,16 @@
 ckSpace(
-currentString
 );%0A     
@@ -1444,16 +1444,19 @@
 ory.
-push(new
+add(current
 Stat
@@ -1502,16 +1502,49 @@
 = null;%0A
+        currentState = newState;%0A
         
@@ -1641,39 +1641,16 @@
 tate) %7B%0A
-        history.pop();%0A
         
@@ -1774,39 +1774,16 @@
 tate) %7B%0A
-        history.pop();%0A
         
@@ -2387,36 +2387,16 @@
 ckSpace(
-String currentString
 ) %7B%0A    
@@ -2403,24 +2403,25 @@
     if (
+!
 history.
 size() %3E
@@ -2416,18 +2416,17 @@
 ory.
-size() %3E 1
+isEmpty()
 ) %7B%0A
@@ -2428,32 +2428,47 @@
 )) %7B%0A           
+ currentState =
  history.pop();%0A
@@ -2465,10 +2465,11 @@
 ry.p
-op
+eek
 ();%0A
@@ -2480,63 +2480,25 @@
     
-%7D else %7B%0A            assert currentString.length() == 0
+    history.pop()
 ;%0A  
@@ -2520,30 +2520,28 @@
  return 
-history.peek()
+currentState
 ;%0A    %7D%0A

Refactor logic