package seedu.doist.ui;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.fxmisc.richtext.InlineCssTextArea;

import seedu.doist.model.Model;

public class CommandAutoCompleteManager {
    private static CommandAutoCompleteManager instance;
    private static final String SUGGESTION_STYLE = "-fx-fill: grey;";

    private boolean hasTriggered = false;

    // for singleton pattern
    protected static CommandAutoCompleteManager getInstance() {
        if (instance == null) {
            instance = new CommandAutoCompleteManager();
        }
        return instance;
    }

    // main function method
    public void suggestCompletion(InlineCssTextArea commandTextField, Model model) {
        // prevent "recursive" call since this method will trigger change event,
        // which, again, will call this method
        if (hasTriggered) {
            return;
        }

        hasTriggered = true;
        removeSuggestionAfterCursor(commandTextField);

        String[] words = commandTextField.getText().split(" +");
        String lastWord = words[words.length - 1];
        if (!lastWord.equals("")) {
            displaySuggestion(commandTextField, lastWord, getSuggestion(lastWord, model));
        }
        hasTriggered = false;
    }

    private String getSuggestion(String lastWord, Model model) {
        //TODO: make this method more "powerful"
        // handle different cases (command word, key, search history) differently
        // make better suggestion by using a queue to store history and store the frequency
        List<String> allCommandWords = getAllCommandWords(model);
        for (String commandWord : allCommandWords) {
            if (commandWord.startsWith(lastWord)) {
                return commandWord;
            }
        }
        return "";
    }

    /**
     * display the suggested text in light grey
     */
    private void displaySuggestion(InlineCssTextArea commandTextField, String lastWord, String suggestedWord) {
        if (lastWord == suggestedWord) {
            return;
        }
        String remainingWord = suggestedWord.replace(lastWord, "");
        int previousLength = commandTextField.getLength();
        commandTextField.appendText(remainingWord);
        commandTextField.setStyle(previousLength, previousLength + remainingWord.length(), SUGGESTION_STYLE);
        commandTextField.moveTo(previousLength);
    }

    private void removeSuggestionAfterCursor(InlineCssTextArea commandTextField) {
        int cursorPosition = commandTextField.getCaretPosition();
        commandTextField.deleteText(cursorPosition, commandTextField.getLength());
    }

    private List<String> getAllCommandWords(Model model) {
        ArrayList<String> allCommandWords = new ArrayList<String>();
        Set<String> allDefaultCommandWords = model.getDefaultCommandWordSet();
        for (String defaultCommandWords : allDefaultCommandWords) {
            allCommandWords.addAll(model.getValidCommandList(defaultCommandWords));
        }
        return allCommandWords;
    }
}

@@ -139,16 +139,127 @@
 tArea;%0A%0A
+import javafx.geometry.Point2D;%0Aimport javafx.scene.control.ContextMenu;%0Aimport javafx.scene.control.MenuItem;%0A
 import s
@@ -456,51 +456,8 @@
 %22;%0A%0A
-    private boolean hasTriggered = false;%0A%0A
     
@@ -793,280 +793,8 @@
 ) %7B%0A
-        // prevent %22recursive%22 call since this method will trigger change event,%0A        // which, again, will call this method%0A        if (hasTriggered) %7B%0A            return;%0A        %7D%0A%0A        hasTriggered = true;%0A        removeSuggestionAfterCursor(commandTextField);%0A%0A
     
@@ -988,26 +988,16 @@
 xtField,
- lastWord,
  getSugg
@@ -1002,16 +1002,17 @@
 ggestion
+s
 (lastWor
@@ -1037,38 +1037,8 @@
   %7D%0A
-        hasTriggered = false;%0A
     
@@ -1052,22 +1052,33 @@
 private 
+ArrayList%3C
 String
+%3E
  getSugg
@@ -1083,16 +1083,17 @@
 ggestion
+s
 (String 
@@ -1339,16 +1339,76 @@
 requency
+%0A%0A        ArrayList%3CString%3E suggestions = new ArrayList%3C%3E();
 %0A       
@@ -1587,23 +1587,32 @@
         
-return 
+suggestions.add(
 commandW
@@ -1614,16 +1614,17 @@
 mandWord
+)
 ;%0A      
@@ -1656,18 +1656,27 @@
  return 
-%22%22
+suggestions
 ;%0A    %7D%0A
@@ -1815,31 +1815,25 @@
 ld, 
-String lastWord, 
+ArrayList%3C
 String
+%3E
  sug
@@ -1834,36 +1834,38 @@
 g%3E suggestedWord
+s
 ) %7B%0A
+%0A
         if (last
@@ -1864,163 +1864,177 @@
 if (
-lastWord == suggestedWord) %7B%0A            return;%0A        %7D%0A        String remainingWord = suggestedWord.replace(lastWord, %22%22);%0A        int previousLength =
+commandTextField.getPopupWindow() == null) %7B%0A            commandTextField.setPopupWindow(new ContextMenu());%0A        %7D%0A        ContextMenu suggestionList = (ContextMenu)
  com
@@ -2050,22 +2050,27 @@
 ield.get
-Length
+PopupWindow
 ();%0A    
@@ -2094,432 +2094,508 @@
 eld.
-appendText(remainingWord);%0A        commandTextField.setStyle(previousLength, previousLength + remainingWord.length(), SUGGESTION_STYLE);%0A        commandTextField.moveTo(previousLength
+setPopupAnchorOffset(new Point2D(-18, 18));%0A        suggestionList.getItems().clear();%0A        int index = 0;%0A        for (String word : suggestedWords) %7B%0A            MenuItem m = new MenuItem(word
 );%0A    
-%7D%0A%0A
     
-private void removeSuggestionAfterCursor(InlineCssTextArea comma
+    suggestionList.getItems().add(index, m);%0A            i
 nd
-T
 ex
-tField) %7B%0A        int cursorPosition = commandTextField.getCaretPosition();%0A        commandTextField.deleteText(cursorPosition, commandTextField.getLength
+++;%0A        %7D%0A        if (commandTextField.getPopupWindow().isShowing()) %7B%0A            return;%0A        %7D%0A        commandTextField.getPopupWindow().show(commandTextField, suggestionList.getAnchorX(), suggestionList.getAnchorY
 ());
+;;
 %0A   

use menu box rather than grey text to display suggestions TODO: NEED REFACTORING, current code is only for trial purpose