package seedu.doist.ui.util;

import java.util.ArrayList;

import org.fxmisc.richtext.InlineCssTextArea;

import javafx.geometry.Point2D;
import seedu.doist.logic.Logic;
import seedu.doist.logic.parser.ArgumentTokenizer.Prefix;
import seedu.doist.logic.parser.CliSyntax;


//@@author A0147980U
public class CommandAutoCompleteManager {
    private static CommandAutoCompleteManager instance;

    // relative to cursor center
    private final Point2D suggestionBoxOffset = new Point2D(-8, 12);
    private final int maxItemNu = 8;

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

    // main function method
    public void suggestCompletion(InlineCssTextArea commandTextField, Logic logic) {
        attachSuggestionWindowIfNecessary(commandTextField);

        int cursorPosition = commandTextField.getCaretPosition();
        String[] words = commandTextField.getText(0, cursorPosition).split(" +", -1);
        String lastWord = words[words.length - 1];  // -1 means trailing space will NOT be discarded
        if (!"".equals(lastWord)) {
            displaySuggestions(commandTextField, getSuggestions(lastWord, logic));
        } else {
            commandTextField.getPopupWindow().hide();
        }
    }

    private ArrayList<String> getSuggestions(String lastWord, Logic logic) {
        // 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
        int count = 0;
        ArrayList<String> suggestions = new ArrayList<>();
        for (String commandWord : logic.getAllCommandWords()) {
            if (commandWord.startsWith(lastWord) && count < maxItemNu) {
                suggestions.add(commandWord);
                count++;
            }
        }
        for (Prefix prefix : CliSyntax.ALL_PREFICES) {
            if (prefix.toString().startsWith(lastWord) && count < maxItemNu) {
                suggestions.add(prefix.toString());
                count++;
            }
        }
        return suggestions;
    }

    /**
     * display the suggested text in a ContextMenu pop-up window
     */
    private void displaySuggestions(InlineCssTextArea commandTextField, ArrayList<String> suggestions) {
        ContentAssistPopupWindow suggestionList = (ContentAssistPopupWindow) commandTextField.getPopupWindow();
        suggestionList.replaceItems(suggestions);

        if (!commandTextField.getPopupWindow().isShowing()) {
            suggestionList.show(commandTextField);
        }
    }

    public void attachSuggestionWindowIfNecessary(InlineCssTextArea commandTextField) {
        if (commandTextField.getPopupWindow() == null) {
            commandTextField.setPopupWindow(new ContentAssistPopupWindow());
            commandTextField.setPopupAnchorOffset(suggestionBoxOffset);
        }
    }
}


@@ -264,16 +264,48 @@
 Syntax;%0A
+import seedu.doist.model.Model;%0A
 %0A%0A//@@au
@@ -416,16 +416,52 @@
 nstance;
+%0A    private boolean isFind = false;
 %0A%0A    //
@@ -916,32 +916,45 @@
 eld, Logic logic
+, Model model
 ) %7B%0A        atta
@@ -1256,16 +1256,46 @@
 scarded%0A
+        isFindCommand(words);%0A
         
@@ -1318,24 +1318,168 @@
 astWord)) %7B%0A
+            if (isFind) %7B%0A                displaySuggestions(commandTextField, getSuggestionsForSearch(words, model));%0A            %7D else %7B%0A    
             
@@ -1545,24 +1545,38 @@
 d, logic));%0A
+            %7D%0A
         %7D el
@@ -2532,24 +2532,885 @@
 ons;%0A    %7D%0A%0A
+    private ArrayList%3CString%3E getSuggestionsForSearch(String%5B%5D words, Model model) %7B%0A        int count = 0;%0A        StringBuilder s = new StringBuilder();%0A        for (int i = 1; i %3C words.length; i++) %7B%0A            s.append(words%5Bi%5D).append(%22 %22);%0A        %7D%0A        ArrayList%3CString%3E suggestions = new ArrayList%3C%3E();%0A        for (String desc : model.getAllNames()) %7B%0A            if ((Double.compare(org.apache.commons.lang3.StringUtils.%0A                    getJaroWinklerDistance(desc, s.toString()), 0.60) %3E= 0) && count %3C maxItemNu) %7B%0A                suggestions.add(desc);%0A                count++;%0A            %7D%0A        %7D%0A%0A        return suggestions;%0A    %7D%0A%0A    private void isFindCommand(String%5B%5D words) %7B%0A        if (words.length %3E 0) %7B%0A            isFind = words%5B0%5D.equals(new String(%22find%22));%0A        %7D else %7B%0A            isFind = false;%0A        %7D%0A    %7D%0A
     /**%0A    

Add auto-complete feature for search