package com.mnr.java.intellij.idea.plugin.base64helper;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorModificationUtil;
import com.intellij.openapi.editor.SelectionModel;

/**
 * @author mnr
 */
public abstract class AbstractEncoderDecoder extends AnAction {
    public static final String EDITOR = "editor";

    @Override
    public void actionPerformed(AnActionEvent anActionEvent) {
        DataContext dataContext = anActionEvent.getDataContext();
        final Editor editor = getEditor(dataContext);

        if (editor == null) {
            return;
        }

        final String selectedText = getEditorSelectedText(editor);

        if ((selectedText != null) && !selectedText.isEmpty()) {
            Application application = ApplicationManager.getApplication();

            if (application == null) {
                return;
            }

            application.runWriteAction(new Runnable() {
                @Override
                public void run() {
                    String encodeDecode = encodeDecode(selectedText);

                    if (encodeDecode != null) {
                        EditorModificationUtil.insertStringAtCaret(editor, encodeDecode, true, true);
                    }
                }
            });
        }
    }

    public abstract String encodeDecode(String selectedText);

    private String getEditorSelectedText(Editor editor) {
        if (editor == null) {
            return null;
        }

        SelectionModel selectionModel = editor.getSelectionModel();
        return selectionModel.getSelectedText();
    }

    private Editor getEditor(DataContext dataContext) {
        return (Editor) dataContext.getData(EDITOR);
    }

    @Override
    public void update(AnActionEvent anActionEvent) {
        Presentation presentation = anActionEvent.getPresentation();
        DataContext dataContext = anActionEvent.getDataContext();
        Editor editor = getEditor(dataContext);
        String selectedText = getEditorSelectedText(editor);
        boolean enabled = checkEnableCondition(selectedText);
        presentation.setEnabled(enabled);
    }

    public boolean checkEnableCondition(String selectedText) {
        return (selectedText != null) && !selectedText.isEmpty();
    }
}

@@ -54,59 +54,8 @@
 r;%0A%0A
-import com.intellij.openapi.actionSystem.AnAction;%0A
 impo
@@ -219,121 +219,8 @@
 on;%0A
-import com.intellij.openapi.application.Application;%0Aimport com.intellij.openapi.application.ApplicationManager;%0A
 impo
@@ -367,16 +367,152 @@
 onModel;
+%0Aimport com.intellij.openapi.editor.actionSystem.EditorAction;%0Aimport com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
 %0A%0A/**%0A *
@@ -581,18 +581,22 @@
 extends 
-An
+Editor
 Action %7B
@@ -605,54 +605,128 @@
    p
-ublic static final String EDITOR = %22editor%22;%0A%0A
+rotected AbstractEncoderDecoder() %7B%0A        super(null);%0A%0A        setupHandler(new EditorWriteActionHandler() %7B%0A        
     
@@ -727,32 +727,40 @@
       @Override%0A
+        
     public void 
@@ -763,176 +763,77 @@
 oid 
-actionPerformed(AnActionEvent anActionEvent) %7B%0A        DataContext dataContext = anActionEvent.getDataContext();%0A        final Editor editor = getEditor(dataContext);%0A%0A
+executeWriteAction(Editor editor, DataContext dataContext) %7B%0A        
     
@@ -862,32 +862,40 @@
 ) %7B%0A            
+        
 return;%0A        
@@ -886,35 +886,51 @@
 return;%0A        
+       
+ 
 %7D%0A%0A
+        
         final St
@@ -977,24 +977,32 @@
 t(editor);%0A%0A
+        
         if (
@@ -1058,280 +1058,8 @@
 ) %7B%0A
-            Application application = ApplicationManager.getApplication();%0A%0A            if (application == null) %7B%0A                return;%0A            %7D%0A%0A            application.runWriteAction(new Runnable() %7B%0A                @Override%0A                public void run() %7B%0A
     
@@ -1328,18 +1328,16 @@
        %7D
-);
 %0A       
@@ -1334,24 +1334,26 @@
  %7D%0A        %7D
+);
 %0A    %7D%0A%0A    
@@ -1473,74 +1473,8 @@
 ) %7B%0A
-        if (editor == null) %7B%0A            return null;%0A        %7D%0A%0A
     
@@ -1597,124 +1597,8 @@
  %7D%0A%0A
-    private Editor getEditor(DataContext dataContext) %7B%0A        return (Editor) dataContext.getData(EDITOR);%0A    %7D%0A%0A
     

modify implementation to support undo/redo in IDE editor