/*
 * Copyright (c) 2007-2010 by The Broad Institute, Inc. and the Massachusetts Institute of Technology.
 * All Rights Reserved.
 *
 * This software is licensed under the terms of the GNU Lesser General Public License (LGPL), Version 2.1 which
 * is available at http://www.opensource.org/licenses/lgpl-2.1.php.
 *
 * THE SOFTWARE IS PROVIDED "AS IS." THE BROAD AND MIT MAKE NO REPRESENTATIONS OR WARRANTIES OF
 * ANY KIND CONCERNING THE SOFTWARE, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT
 * OR OTHER DEFECTS, WHETHER OR NOT DISCOVERABLE.  IN NO EVENT SHALL THE BROAD OR MIT, OR THEIR
 * RESPECTIVE TRUSTEES, DIRECTORS, OFFICERS, EMPLOYEES, AND AFFILIATES BE LIABLE FOR ANY DAMAGES OF
 * ANY KIND, INCLUDING, WITHOUT LIMITATION, INCIDENTAL OR CONSEQUENTIAL DAMAGES, ECONOMIC
 * DAMAGES OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF WHETHER THE BROAD OR MIT SHALL
 * BE ADVISED, SHALL HAVE OTHER REASON TO KNOW, OR IN FACT SHALL KNOW OF THE POSSIBILITY OF THE
 * FOREGOING.
 */

/*
 * RubberBand.java
 *
 * Created on November 17, 2007, 11:13 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package demos;

import java.applet.Applet;
import java.awt.*;
import java.util.Vector;

public class RubberBand extends Applet {

    int w = 200;
    int h = 200;
    Vector lines = new Vector();
    int np = 0;
    int x1, y1;
    int x2, y2;
    int xl, yl;
    Image offImg;
    Graphics offGra;
    Button btnClear, btnUndo;

    public void init() {

        setLayout(new FlowLayout());
        btnClear = new Button("Clear");
        btnUndo = new Button("Undo");
        add(btnClear);
        add(btnUndo);
        setBackground(new Color(0).black);
        setForeground(new Color(0).white);
    }

    public void Dragupdate(Graphics g) {
        /*
        ** rubber-band effect
        */
        g.setXORMode(getBackground());
        setForeground(new Color(0).blue);
        if (xl != -1) {
            // erase the old line
            g.drawLine(x1, y1, xl, yl);
            if (x2 != -1) {
                // draw the new one
                g.drawLine(x1, y1, x2, y2);
            }
        }
    }

    public void update(Graphics g) {

        // draw an offScreen drawing
        Dimension dim = getSize();
        if (offGra == null) {
            offImg = createImage(dim.width, dim.height);
            offGra = offImg.getGraphics();
        }
        offGra.setColor(new Color(0).black);
        offGra.fillRect(0, 0, dim.width, dim.height);
        offGra.setColor(new Color(0).white);
        offGra.setPaintMode();
        for (int i = 0; i < np; i++) {
            Rectangle p = (Rectangle) lines.elementAt(i);
            if (p.width != -1) {
                offGra.drawLine(p.x, p.y, p.width, p.height);
            }
        }
        // put the OffScreen image OnScreen
        g.drawImage(offImg, 0, 0, null);
    }

    public boolean handleEvent(Event e) {

        switch (e.id) {
            case Event.MOUSE_DOWN:
                // new starting point
                x1 = e.x;
                y1 = e.y;
                // begin an new drawing process
                x2 = -1;
                return true;
            case Event.MOUSE_UP:
                // end a drawing process
                lines.addElement(new Rectangle(x1, y1, e.x, e.y));
                np++;
                x2 = xl = -1;
                repaint();
                return true;
            case Event.MOUSE_DRAG:
                // xl yl line to be erased
                xl = x2;
                yl = y2;
                // x2 y2 last current point
                x2 = e.x;
                y2 = e.y;
                Dragupdate(getGraphics());
                return true;
        }
        return super.handleEvent(e);
    }

    public boolean action(Event e, Object o) {
        if (e.target == btnClear) resetDrawing();
        if (e.target == btnUndo) undo();
        return true;
    }

    public void undo() {
        if (np > 0) {
            lines.removeElementAt(np - 1);
            np--;
            repaint();
        }
    }

    public void resetDrawing() {
        lines.removeAllElements();
        np = 0;
        repaint();
    }
}
