package org.rstudio.studio.client.workbench.views.source.editors.text.cpp;

import org.rstudio.core.client.Debug;
import org.rstudio.core.client.Rectangle;
import org.rstudio.core.client.theme.res.ThemeStyles;
import org.rstudio.core.client.widget.ScrollableToolbarPopupMenu;
import org.rstudio.studio.client.workbench.views.console.shell.editor.InputEditorPosition;
import org.rstudio.studio.client.workbench.views.source.editors.text.DocDisplay;
import org.rstudio.studio.client.workbench.views.source.editors.text.ace.Position;
import org.rstudio.studio.client.workbench.views.source.model.CppCompletion;

import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.MenuItem;

public class CppCompletionPopupMenu extends ScrollableToolbarPopupMenu
{
   CppCompletionPopupMenu(DocDisplay docDisplay, Position completionPosition)
   {  
      docDisplay_ = docDisplay;
      completionPosition_ = completionPosition;
        
      addSelectionHandler(new SelectionHandler<MenuItem>()
      {
         public void onSelection(SelectionEvent<MenuItem> event)
         {
            int index = menuBar_.getItemIndex(event.getSelectedItem());
            if (index != -1)
            {
               CppCompletion completion = completions_.get(index);
               Debug.logToConsole(completion.getText());
            }
         }
      });
      
      addStyleName(ThemeStyles.INSTANCE.statusBarMenu());
   }
   
   public void setCompletions(JsArray<CppCompletion> completions)
   {
      // save completions
      completions_ = completions;
      
      // clear existing items
      menuBar_.clearItems();
      
      // add items (remember first item for programmatic selection)
      MenuItem firstItem = null;
      for (int i = 0; i<completions.length(); i++)
      {
         final CppCompletion completion = completions.get(i);
         MenuItem menuItem = new MenuItem(completion.getText(), 
               new ScheduledCommand() {
            @Override
            public void execute()
            {
               docDisplay_.setFocus(true); 
               docDisplay_.setSelection(docDisplay_.createSelection(
                     completionPosition_, docDisplay_.getCursorPosition()));
               docDisplay_.replaceSelection(completion.getText(), true) ; 

            }
         });
         
         addItem(menuItem);
         
         if (i == 0)
            firstItem = menuItem;
      }
      
      // select first item
      if (firstItem != null)
         selectItem(firstItem);
      
      // ensure the menu is visible
      if (!isAttached())
         showMenu();
      else if (!isVisible())
         setVisible(true);
   }
   
   private void showMenu()
   {
      setPopupPositionAndShow(new PositionCallback()
      {
         public void setPosition(int offsetWidth, int offsetHeight)
         {
            InputEditorPosition position = 
               docDisplay_.createInputEditorPosition(completionPosition_);  
            Rectangle bounds = docDisplay_.getPositionBounds(position);
            
            int windowBottom = Window.getScrollTop() + 
                               Window.getClientHeight() ;
            int cursorBottom = bounds.getBottom() ;
            
            final int PAD = 3;
            if (windowBottom - cursorBottom >= offsetHeight)
               setPopupPosition(bounds.getLeft(), cursorBottom + PAD) ;
            else
               setPopupPosition(bounds.getLeft(), 
                                bounds.getTop() - offsetHeight) ;
         }
      });
   }
   
   private final DocDisplay docDisplay_;
   private final Position completionPosition_;
   private JsArray<CppCompletion> completions_;
}

@@ -1299,32 +1299,78 @@
 ent)%0A         %7B%0A
+            if (selectable_)%0A            %7B%0A   
             int 
@@ -1433,24 +1433,27 @@
             
+   
 if (index !=
@@ -1461,34 +1461,39 @@
 -1)%0A            
-%7B%0A
+   %7B%0A  
                C
@@ -1491,16 +1491,17 @@
         
+ 
 CppCompl
@@ -1559,16 +1559,19 @@
         
+   
 Debug.lo
@@ -1600,24 +1600,27 @@
 getText());%0A
+   
             
@@ -1613,32 +1613,46 @@
               %7D%0A
+            %7D%0A
          %7D%0A     
@@ -1752,86 +1752,498 @@
  set
-Completions(JsArray%3CCppCompletion%3E completions)%0A   %7B%0A      // save completions
+Text(String text)%0A   %7B%0A      JsArray%3CCppCompletion%3E completions = JsArray.createArray().cast();%0A      completions.push(CppCompletion.create(text));%0A      setCompletions(completions, false);%0A   %7D%0A   %0A   public void setCompletions(JsArray%3CCppCompletion%3E completions)%0A   %7B%0A      setCompletions(completions, true);%0A   %7D%0A   %0A   private void setCompletions(JsArray%3CCppCompletion%3E completions, %0A                               boolean selectable)%0A   %7B%0A      // save completions and selectable state
 %0A   
@@ -2273,16 +2273,48 @@
 etions;%0A
+      selectable_ = selectable;%0A
       %0A 
@@ -2819,16 +2819,68 @@
 true); %0A
+               if (selectable_)%0A               %7B%0A   
         
@@ -3024,32 +3024,35 @@
 %0A               
+   
 docDisplay_.repl
@@ -3094,16 +3094,33 @@
 true) ; 
+%0A               %7D
 %0A%0A      
@@ -3293,16 +3293,31 @@
       if
+ (selectable &&
  (firstI
@@ -3328,16 +3328,17 @@
 != null)
+)
 %0A       
@@ -4537,10 +4537,50 @@
 tions_;%0A
+   private boolean selectable_ = false;%0A
 %7D%0A

add setText to cpp completion popup