package ij.gui;
import ij.*;
import java.awt.*;

/** Implements the ROI Brush tool.*/
class RoiBrush implements Runnable {
    static int ADD=0, SUBTRACT=1;
    static int leftClick=16, alt=9, shift=1;
    private Polygon poly;
    private Point previousP;
    private int mode = ADD;
 
    RoiBrush() {
        Thread thread = new Thread(this, "RoiBrush");
        thread.start();
    }

    public void run() {
        int size = Toolbar.getBrushSize();
        ImagePlus img = WindowManager.getCurrentImage();
        if (img==null) return;
        ImageCanvas ic = img.getCanvas();
        if (ic==null) return;
        Roi roi = img.getRoi();
        if (roi!=null && !roi.isArea())
            img.deleteRoi();
        Point p = ic.getCursorLoc();
        if (roi!=null && !roi.contains(p.x, p.y))
            mode = SUBTRACT;
        int flags;
        while (true) {
            p = ic.getCursorLoc();
            if (p.equals(previousP))
                {IJ.wait(1); continue;}
            previousP = p;
            flags = ic.getModifiers();
            if ((flags&leftClick)==0) return;
            if ((flags&shift)!=0)
                mode = ADD;
            else if ((flags&alt)!=0)
                mode = SUBTRACT;
            if (mode==ADD)
                addCircle(img, p.x, p.y, size);
            else
                subtractCircle(img, p.x, p.y, size);
        }
    }

    void addCircle(ImagePlus img, int x, int y, int width) {
        Roi roi = img.getRoi();
        Roi roi2 = roi;
        if (roi2!=null) {
            if (!(roi2 instanceof ShapeRoi))
                roi2 = new ShapeRoi(roi2);
            ((ShapeRoi)roi2).or(getCircularRoi(x, y, width));
            roi2.copyAttributes(roi);
        } else
            roi2 = new OvalRoi(x-width/2, y-width/2, width, width);
        img.setRoi(roi2);
    }

    void subtractCircle(ImagePlus img, int x, int y, int width) {
        Roi roi = img.getRoi();
        Roi roi2 = roi;
        if (roi2!=null) {
            if (!(roi2 instanceof ShapeRoi))
            roi2 = new ShapeRoi(roi2);
            ((ShapeRoi)roi2).not(getCircularRoi(x, y, width));
            roi2.copyAttributes(roi);
            img.setRoi(roi2);
        }
    }

    
    ShapeRoi getCircularRoi(int x, int y, int width) {
        if (poly==null) {
            Roi roi = new OvalRoi(x-width/2, y-width/2, width, width);
            poly = roi.getPolygon();
            for (int i=0; i<poly.npoints; i++) {
                poly.xpoints[i] -= x;
                poly.ypoints[i] -= y;
            }
        }
        return new ShapeRoi(x, y, poly);
    }

}