/*
 * @(#)SelectAreaTracker.java 5.1
 *
 */

package CH.ifa.draw.standard;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.util.Vector;

import de.renew.draw.storables.ontology.Figure;
import de.renew.draw.storables.ontology.FigureEnumeration;
import de.renew.draw.ui.ontology.DrawingEditor;


/**
 * SelectAreaTracker implements a rubber band selection of an area.
 */
public class SelectAreaTracker extends AbstractTool {
    protected Rectangle fSelectGroup;

    // If we use some zooming factor, the draw selection rectangle doesn't match with the actual selection
    // Therefore we have to differentiate the two.
    private Rectangle _visualSelectGroup;
    private Point _visualAnchor;

    public SelectAreaTracker(DrawingEditor editor) {
        super(editor);
    }

    @Override
    public void mouseDown(MouseEvent e, int x, int y) {
        // use event coordinates to suppress any kind of
        // transformations like constraining points to a grid
        super.mouseDown(e, x, y);
        _visualAnchor = new Point(e.getX(), e.getY());
        visualRubberBand(_visualAnchor.x, _visualAnchor.y, _visualAnchor.x, _visualAnchor.y);

        selectionRubberBand(_anchorX, _anchorY, _anchorX, _anchorY);

    }

    @Override
    public void mouseDrag(MouseEvent e, int x, int y) {
        super.mouseDrag(e, x, y);
        eraseRubberBand();
        visualRubberBand(_visualAnchor.x, _visualAnchor.y, e.getX(), e.getY());
        selectionRubberBand(_anchorX, _anchorY, x, y);
    }

    @Override
    public void mouseUp(MouseEvent e, int x, int y) {
        super.mouseUp(e, x, y);
        eraseRubberBand();
        selectGroup(e.isShiftDown());
        fSelectGroup = null;
        _visualSelectGroup = null;
    }

    private void visualRubberBand(int x1, int y1, int x2, int y2) {
        _visualSelectGroup = new Rectangle(new Point(x1, y1));
        _visualSelectGroup.add(new Point(x2, y2));
        drawXORRect(_visualSelectGroup);
    }

    private void selectionRubberBand(int x1, int y1, int x2, int y2) {
        fSelectGroup = new Rectangle(new Point(x1, y1));
        fSelectGroup.add(new Point(x2, y2));

    }

    private void eraseRubberBand() {
        drawXORRect(_visualSelectGroup);
    }

    private void drawXORRect(Rectangle r) {
        Graphics g = view().getGraphics();
        drawXORRect(r, g);
    }

    private void drawXORRect(Rectangle r, Graphics g) {
        g.setXORMode(view().getBackground());
        g.setColor(Color.black);
        g.drawRect(r.x, r.y, r.width, r.height);
    }

    protected void selectGroup(boolean toggle) {
        FigureEnumeration k = drawing().figuresReverse();
        Vector<Figure> concernedFigures = new Vector<>();
        while (k.hasMoreElements()) {
            Figure figure = k.nextFigure();
            Rectangle r2 = figure.displayBox();
            if (fSelectGroup.contains(r2.x, r2.y)
                && fSelectGroup.contains(r2.x + r2.width, r2.y + r2.height)) {
                concernedFigures.addElement(figure);
            }
        }
        if (toggle) {
            view().toggleSelectionAll(concernedFigures);
        } else {
            view().addToSelectionAll(concernedFigures);
        }
    }

    /**
     * Refreshes the rubber band, if overdrawn by the repaint
     * event leading to this method call.
     **/
    @Override
    public void draw(Graphics g) {
        if (_visualSelectGroup != null) {
            drawXORRect(_visualSelectGroup, g);
        }
    }
}