package ij.plugin;
import java.awt.*;
import ij.*;
import ij.gui.*;
import ij.plugin.frame.Editor;
import ij.text.TextWindow;
import ij.io.SaveDialog;
import ij.util.Tools;

/** 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, JAVASCRIPT=1, PLUGIN=2, PLUGIN_FILTER=3, PLUGIN_FRAME=4,
        TEXT_FILE=5, TABLE=6, MACRO_TOOL=7, PLUGIN_TOOL=8, TEMPLATE=9;
    private static int rows = 24;
    private static int columns = 80;
    private static int tableWidth = 350;
    private static int tableHeight = 250;
    private int type = MACRO;
    private String name = "Macro.ijm";
    private boolean monospaced;
    private boolean menuBar = true;
    private Editor ed;
    
    public void run(String arg) {
        type = -1;
        if (arg.startsWith("text")||arg.equals("")) {
            type = TEXT_FILE;
            if (IJ.altKeyDown())
                name = "Untitled.ijm";
            else
                name = "Untitled.txt";
        } else if (arg.equals("macro")) {
            type = MACRO;
            name = "Macro.ijm";
        } else if (arg.equals("macro-tool")) {
            type = TEMPLATE;
            name = "Circle_Tool.txt";
        } else if (arg.equals("javascript")) {
            type = JAVASCRIPT;
            name = "Script.js";
        } else if (arg.equals("plugin")) {
            type = TEMPLATE;
            name = "My_Plugin.src";
        } else if (arg.equals("frame")) {
            type = TEMPLATE;
            name = "Plugin_Frame.src";
        } else if (arg.equals("plugin-tool")) {
            type = TEMPLATE;
            name = "Prototype_Tool.src";
        } else if (arg.equals("filter")) {
            type = TEMPLATE;
            name = "Filter_Plugin.src";
        } else if (arg.equals("table")) {
            String options = Macro.getOptions();
            if  (IJ.isMacro() && options!=null && options.indexOf("[Text File]")!=-1) {
                type = TEXT_FILE;
                name = "Untitled.txt";
                arg = "text+dialog";
            } else {
                type = TABLE;
                name = "Table";
            }
        }
        menuBar = true;
        if (arg.equals("text+dialog") || type==TABLE) {
            if (!showDialog()) return;
        }
        if (type==-1)
            createPlugin("Converted_Macro.java", PLUGIN, arg);
        else if (type==TEMPLATE || type==MACRO || type==TEXT_FILE || type==JAVASCRIPT) {
            if (type==TEXT_FILE && name.equals("Macro"))
                name = "Untitled.txt";
            createMacro(name);
        } else if (type==TABLE)
            createTable();
        else
            createPlugin(name, type, arg);
    }
    
    public void createMacro(String name) {
        int options = (monospaced?Editor.MONOSPACED:0)+(menuBar?Editor.MENU_BAR:0);
        if (name.endsWith(".ijm") || name.endsWith(".js"))
            options |= Editor.RUN_BAR;
        if (name.endsWith(".ijm"))
            options |= Editor.INSTALL_BUTTON;
        String text = "";
        ed = new Editor(rows, columns, 0, options);
        if (type==TEMPLATE)
            text = Tools.openFromIJJarAsString("/macros/"+name);
        if (name.endsWith(".src"))
            name = name.substring(0,name.length()-4) + ".java";
        if (type==MACRO && !name.endsWith(".ijm"))
            name = SaveDialog.setExtension(name, ".ijm");
        else if (type==JAVASCRIPT && !name.endsWith(".js")) {
            if (name.equals("Macro")) name = "script";
            name = SaveDialog.setExtension(name, ".js");
        }
        if (text!=null)
            ed.create(name, text);
    }
    
    void createTable() {
            new TextWindow(name, "", tableWidth, tableHeight);
    }

    public void createPlugin(String name, int type, String methods) {
        ed = (Editor)IJ.runPlugIn("ij.plugin.frame.Editor", "");
        if (ed==null) return;
        String pluginName = name;
        if (!(name.endsWith(".java") || name.endsWith(".JAVA")))
            name = SaveDialog.setExtension(name, ".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";
        text += "import ij.plugin.*;\n";
        text += "\n";
        text += "public class "+className+" implements PlugIn {\n";
        text += "\n";
        text += "\tpublic void run(String arg) {\n";
        text += methods;
        text += "\t}\n";
        text += "\n";
        text += "}\n";
        text = text.replaceAll("\\t","    ");
        ed.create(pluginName, text);
    }
    
    public boolean showDialog() {
        String title;
        String widthUnit, heightUnit;
        int width, height;
        if (type==TABLE) {
            title = "New Table";
            name = "Table";
            width = tableWidth;
            height = tableHeight;
            widthUnit = "pixels";
            heightUnit = "pixels";
        } else {
            title = "New Text Window";
            name = "Untitled";
            width = columns;
            height = rows;
            widthUnit = "characters";
            heightUnit = "lines";
        }
        GenericDialog gd = new GenericDialog(title);
        gd.addStringField("Name:", name, 16);
        gd.addMessage("");
        gd.addNumericField("Width:", width, 0, 3, widthUnit);
        gd.addNumericField("Height:", height, 0, 3, heightUnit);
        if (type!=TABLE) {
            gd.setInsets(5, 30, 0);
            gd.addCheckbox("Menu Bar", true);
            gd.setInsets(0, 30, 0);
            gd.addCheckbox("Monospaced Font", monospaced);
        }
        gd.showDialog();
        if (gd.wasCanceled())
            return false;
        name = gd.getNextString();
        width = (int)gd.getNextNumber();
        height = (int)gd.getNextNumber();
        if (width<1) width = 1;
        if (height<1) height = 1;
        if (type!=TABLE) {
            menuBar = gd.getNextBoolean();
            monospaced = gd.getNextBoolean();
            columns = width;
            rows = height;
            if (rows>100) rows = 100;
            if (columns>200) columns = 200;
        } else {
            tableWidth = width;
            tableHeight = height;
            if (tableWidth<128) tableWidth = 128;
            if (tableHeight<75) tableHeight = 75;
        }
        return true;
    }
    
    /** Returns the Editor the newly created macro or plugin was opened in. */
    public Editor getEditor() {
        return ed;
    }

}