package ij.plugin;
import java.awt.*;
import ij.*;
import ij.gui.*;
import ij.plugin.frame.Editor;
import ij.text.TextWindow;

/** This class creates a new macro or the Java source for a new plugin. */
public class NewPlugin implements PlugIn {

    public static final int MACRO=0, PLUGIN=1, PLUGIN_FILTER=2, PLUGIN_FRAME=3, TEXT_FILE=4, TABLE=5;
    
    private static int type = MACRO;
    private static String name = "Macro";
    private static String[] types = {"Macro", "Plugin", "Plugin Filter", "Plugin Frame", "Text File", "Table"};
    private static int rows = 16;
    private static int columns = 60;
    private static boolean monospaced;
    private boolean menuBar = true;
    private Editor ed;
    private int saveType = type;
    private String saveName = name;
    private int saveRows = rows;
    private int saveColumns = columns;
    private boolean saveMonospaced = monospaced;
    
    public void run(String arg) {
        if (arg.equals("")&&!showDialog())
            return;
        if (arg.equals("text")) {
            type = TEXT_FILE;
            arg = "";
        }
        if (arg.equals("")) {
            if (type==MACRO || type==TEXT_FILE) {
                if (type==TEXT_FILE && name.equals("Macro"))
                    name = "Untitled.txt";
                createMacro(name);
            } else if (type==TABLE) {
                createTextWindow();
            } else
                createPlugin(name, type, arg);
        } else
            createPlugin("Converted_Macro.java", PLUGIN, arg);
        if (IJ.macroRunning()) {
            type = saveType;
            name = saveName;
            rows = saveRows;
            columns = saveColumns;
            monospaced = saveMonospaced;
        }
        IJ.register(NewPlugin.class);
    }
    
    public void createMacro(String name) {
        int options = (monospaced?Editor.MONOSPACED:0)+(menuBar?Editor.MENU_BAR:0);
        ed = new Editor(rows, columns, 0, options);
        if (name.endsWith(".java"))
            name = name.substring(0, name.length()-5);
        //if (name.endsWith("_"))
        //  name = name.substring(0, name.length()-1);
        if (type==MACRO && !(name.endsWith(".txt")))
            name += ".txt";
        ed.create(name, "");
    }
    
    void createTextWindow() {
        String tableName = name;
        if (tableName.equals("Macro")) tableName = "Table";
        if (columns<128 || rows<75 )
            new TextWindow(tableName, "", 350, 250);
        else
            new TextWindow(tableName, "", columns, rows);
    }

    public void createPlugin(String name, int type, String methods) {
        ed = (Editor)IJ.runPlugIn("ij.plugin.frame.Editor", "");
        if (ed==null) return;
        if (name.equals("Macro") || name.equals("Macro.txt") || name.equals("Untitled.txt")) {
            switch (type) {
                case PLUGIN: name = "My_Plugin.java"; break;
                case PLUGIN_FILTER:  name = "Filter_Plugin.java"; break;
                case PLUGIN_FRAME:  name = "Plugin_Frame.java"; break;
            }
        }
        String pluginName = name;
        if (!(name.endsWith(".java") || name.endsWith(".JAVA"))) {
            if (pluginName.endsWith(".txt"))
                pluginName = pluginName.substring(0, pluginName.length()-4);
            pluginName += ".java";
        }
        //if (name.indexOf('_')==-1) {
        //  pluginName = pluginName.substring(0, pluginName.length()-5);
        //  pluginName = pluginName + "_.java";
        //}
        String className = pluginName.substring(0, pluginName.length()-5);
        String text = "";
        text += "import ij.*;\n";
        text += "import ij.process.*;\n";
        text += "import ij.gui.*;\n";
        text += "import java.awt.*;\n";
        switch (type) {
            case PLUGIN:
                text += "import ij.plugin.*;\n";
                text += "\n";
                text += "public class "+className+" implements PlugIn {\n";
                text += "\n";
                text += "\tpublic void run(String arg) {\n";
                if (methods.equals(""))
                    text += "\t\tIJ.showMessage(\""+className+"\",\"Hello world!\");\n";
                else
                    text += methods;
                text += "\t}\n";
                break;
            case PLUGIN_FILTER:
                text += "import ij.plugin.filter.*;\n";
                text += "\n";
                text += "public class "+className+" implements PlugInFilter {\n";
                text += "\tImagePlus imp;\n";
                text += "\n";
                text += "\tpublic int setup(String arg, ImagePlus imp) {\n";
                text += "\t\tthis.imp = imp;\n";
                text += "\t\treturn DOES_ALL;\n";
                text += "\t}\n";
                text += "\n";
                text += "\tpublic void run(ImageProcessor ip) {\n";
                text += "\t\tip.invert();\n";
                text += "\t\timp.updateAndDraw();\n";
                text += "\t\tIJ.wait(500);\n";
                text += "\t\tip.invert();\n";
                text += "\t\timp.updateAndDraw();\n";
                text += "\t}\n";
                break;
            case PLUGIN_FRAME:
                text += "import ij.plugin.frame.*;\n";
                text += "\n";
                text += "public class "+className+" extends PlugInFrame {\n";
                text += "\n";
                text += "\tpublic "+className+"() {\n";
                text += "\t\tsuper(\""+className+"\");\n";
                text += "\t\tTextArea ta = new TextArea(15, 50);\n";
                text += "\t\tadd(ta);\n";
                text += "\t\tpack();\n";
                text += "\t\tGUI.center(this);\n";
                text += "\t\tshow();\n";
                text += "\t}\n";
                break;
        }
        text += "\n";
        text += "}\n";
        ed.create(pluginName, text);
    }
    
    public boolean showDialog() {
        GenericDialog gd = new GenericDialog("New Text Window");
        gd.addStringField("Name:", name, 16);
        gd.addChoice("Type:", types, types[type]);
        gd.addMessage("");
        gd.addNumericField("Width:", columns, 0, 3, "characters");
        gd.addNumericField("Height:", rows, 0, 3, "lines");
        gd.setInsets(5, 30, 0);
        gd.addCheckbox("Menu Bar", menuBar);
        gd.setInsets(0, 30, 0);
        gd.addCheckbox("Monospaced Font", monospaced);
        gd.showDialog();
        if (gd.wasCanceled())
            return false;
        name = gd.getNextString();
        type = gd.getNextChoiceIndex();
        columns = (int)gd.getNextNumber();
        rows = (int)gd.getNextNumber();
        menuBar = gd.getNextBoolean();
        monospaced = gd.getNextBoolean();
        if (rows<1) rows = 1;
        if (type!=TABLE && rows>100) rows = 100;
        if (columns<1) columns = 1;
        if (type!=TABLE && columns>200) columns = 200;
        return true;
    }
    
    /** Returns the Editor the newly created macro or plugin was opened in. */
    public Editor getEditor() {
        return ed;
    }

}