/**
    Stack Annotator plugin for ImageJ.

    This plugin adds text annotations to a range of images in a stack.

    Author: Kang Li (kangli AT cs.cmu.edu)

    Installation:
      Download  Stack_Annotator.java   to  the   ImageJ  plugins   folder  or
      subfolder,  and  compile  and run  it  using  Plugins/Compile and  Run.
      Restart ImageJ and there will be a new "Stack Annotator" command in the
      Plugins menu or its submenu.

    History:
      2007/01/02: First version
*/

/**
Copyright (C) 2008 Kang Li. All rights reserved.

Permission to use, copy, modify, and distribute this software for any purpose
without fee is hereby granted,  provided that this entire notice  is included
in all copies of any software which is or includes a copy or modification  of
this software  and in  all copies  of the  supporting documentation  for such
software. Any for profit use of this software is expressly forbidden  without
first obtaining the explicit consent of the author.

THIS  SOFTWARE IS  BEING PROVIDED  "AS IS",  WITHOUT ANY  EXPRESS OR  IMPLIED
WARRANTY.  IN PARTICULAR,  THE AUTHOR  DOES NOT  MAKE ANY  REPRESENTATION OR
WARRANTY OF ANY KIND CONCERNING  THE MERCHANTABILITY OF THIS SOFTWARE  OR ITS
FITNESS FOR ANY PARTICULAR PURPOSE.
*/

import java.awt.*;
import ij.*;
import ij.process.*;
import ij.gui.*;
import ij.plugin.filter.*;

public class Stack_Annotator implements PlugInFilter {

    ImagePlus     imp = null;
    Font          font = null;
    boolean       canceled = false;
    int           firstFrame = 0;
    int           lastFrame = 0;
    int           frame = 0;
    String        text = "";
    static String fontName = "SansSerif";
    static int    fontStyle = Font.PLAIN;
    static int    fontSize = 12;
    static int    left = 5;
    static int    top = 5;


    public int setup(String arg, ImagePlus imp) {
        this.imp = imp;
        IJ.register(Stack_Annotator.class);
        if (imp != null) {
            frame = 0;
            firstFrame = 1;
            lastFrame = imp.getStackSize();
            text = imp.getTitle();
        }
        return DOES_ALL | DOES_STACKS | STACK_REQUIRED;
    }


    public void run(ImageProcessor ip) {
        ++frame;
        if (frame == 1) showDialog(ip);
        if (canceled || frame < firstFrame || frame > lastFrame)
            return;
        ip.setColor(Toolbar.getForegroundColor());
        ip.setFont(font);
        ip.moveTo(left, top + fontSize);
        ip.drawString(text);
        if (frame == lastFrame)
            imp.updateAndDraw();
    }


    int getFontStyle(String name) {
        int style = Font.PLAIN;
        if (name == "Bold")
            style = Font.BOLD;
        else if (name == "Italic")
            style = Font.ITALIC;
        else if (name == "Bold+Italic")
            style = Font.BOLD + Font.ITALIC;
        return style;
    }


    String getFontStyleName(int style) {
        String name = "Plain";
        if (style == Font.BOLD)
            name = "Bold";
        else if (style == Font.ITALIC)
            name = "Italic";
        else if (style == (Font.BOLD + Font.ITALIC))
            name = "Bold+Italic";
        return name;
    }


    void showDialog(ImageProcessor ip) {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        String[] fontNames = ge.getAvailableFontFamilyNames();
        final String[] fontStyleNames = { "Plain", "Bold", "Italic", "Bold+Italic" };

        Rectangle roi = ip.getRoi();
        if (roi.width < ip.getWidth() || roi.height < ip.getHeight()) {
            left = roi.x;
            top = roi.y + roi.height;
            fontSize = (int)((roi.height - 1.10526) / 0.934211);    
            if (fontSize < 7) fontSize = 7;
            else if (fontSize > 80) fontSize = 80;
        }
        GenericDialog gd = new GenericDialog("Stack Annotator");
        gd.addNumericField("Left:", left, 0);
        gd.addNumericField("Top:", top, 0);
        gd.addChoice("Font Name:", fontNames, fontName);
        gd.addChoice("Font Style:", fontStyleNames, getFontStyleName(fontStyle));
        gd.addNumericField("Font Size:", fontSize, 0);
        gd.addNumericField("First Frame:", firstFrame, 0);
        gd.addNumericField("Last Frame:", lastFrame, 0);
        gd.addStringField("Text:", text);
        gd.showDialog();
        if (gd.wasCanceled()) {
            canceled = true;
            return;
        }
        left = (int)gd.getNextNumber();
        top = (int)gd.getNextNumber();
        fontName = gd.getNextChoice();
        if (null == fontName || fontName.length() == 0)
            fontName = "SansSerif";
        fontStyle = getFontStyle(gd.getNextChoice());
        fontSize = (int)gd.getNextNumber();
        firstFrame = (int)gd.getNextNumber();
        lastFrame = (int)gd.getNextNumber();
        text = gd.getNextString();
        font = new Font(fontName, fontStyle, fontSize);
        ip.setFont(font);
        imp.startTiming();
    }
}

