// @topic T12912 Custom drawing using mouse
// @brief class DrawingBox2D extends JPanel (custom draw box)

package drawingDemo;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;

public class DrawingBox2D extends javax.swing.JPanel
        implements MouseListener, MouseMotionListener {

    //----------------------------------
    // constants
    //----------------------------------
    private static final int STATUS_SEGMENT_NONE = 0;
    private static final int STATUS_SEGMENT_MOUSE_DRAG = 1;
    //----------------------------------
    // data attributes
    //----------------------------------
    // coordinates of the current pixels under mouse position
    private int segmentX1 = 0;
    private int segmentY1 = 0;
    private int segmentX2 = 0;
    private int segmentY2 = 0;
    private int status = STATUS_SEGMENT_NONE;

    private FrameDemo2D window;

    // each segment is made up of four integers
    // (x1, y1, x2, y2)
    private ArrayList<Integer> segments;

    // index of x1 of the the user-selected segment:
    private int idxSelectedSegment = -1;

    boolean isCoordinateInsideRectangle(
            int x, int y, // point
            int x1, int y1, int x2, int y2 // rectangle
        )
    {
        // determine if point (x,y) is inside the rectangle
        if (Math.min(x1, x2) < x
                && x < Math.max(x1, x2)
                && Math.min(y1, y2) < y
                && y < Math.max(y1, y2)) {
            return true;
        }
        return false;
    }//isCoordinateInsideRectangle

    //----------------------------------
    // constructor
    //----------------------------------
    public DrawingBox2D(FrameDemo2D window) {
        this.window = window;
        segments = new ArrayList<Integer>();
        status = STATUS_SEGMENT_NONE;
        addMouseMotionListener(this);
        addMouseListener(this);
    }

    // operations
    @Override
    public void paintComponent(Graphics graph) {
        super.paintComponent(graph);

        Color defaultColor = graph.getColor();
        if (status == STATUS_SEGMENT_MOUSE_DRAG) {
            graph.setColor(Color.GREEN);
            graph.drawLine(
                    segmentX1,
                    segmentY1, segmentX2, segmentY2);
        }

        // draw existing segments
        int idx = 0;
        for (; idx < segments.size(); idx = idx + 4) {
            int x1 = segments.get(idx);
            int y1 = segments.get(idx + 1);
            int x2 = segments.get(idx + 2);
            int y2 = segments.get(idx + 3);

            if ( idx == idxSelectedSegment ) {
                graph.setColor(Color.ORANGE);
            } else {
                graph.setColor(Color.BLUE);
            }
            graph.drawLine(x1, y1, x2, y2);
        }

        graph.setColor(defaultColor);

        // add border:
        // A     B
        // 
        // D     C
        graph.drawLine(0, 0, this.getWidth() - 1, 0); // AB
        graph.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1, this.getHeight() - 1); // BC
        graph.drawLine(this.getWidth() - 1, this.getHeight() - 1, 0, this.getHeight() - 1); // CD
        graph.drawLine(0, 0, 0, this.getHeight() - 1); // AD

    }//paintComponent

    // MouseListener implementation
    @Override
    public void mousePressed(MouseEvent evt) {
        window.setStatus("mousePressed");
        if (evt.getButton() == MouseEvent.BUTTON1) {
            // use only left button to create segment
            status = STATUS_SEGMENT_MOUSE_DRAG;
            segmentX1 = evt.getX();
            segmentY1 = evt.getY();
            segmentX2 = evt.getX();
            segmentY2 = evt.getY();
        } else {
            // use second mouse button to select a drawing segment.
            // first, unselect and assume no selection:
            idxSelectedSegment = -1;
            int idx = 0;
            for (; idx < segments.size(); idx += 4) {
                if (
                    isCoordinateInsideRectangle(
                        evt.getX(), evt.getY(),
                        segments.get(idx),
                        segments.get(idx + 1),
                        segments.get(idx + 2),
                        segments.get(idx + 3)
                    )
                        )//if
                {
                    // clicking on a specific segment selects it:
                    // Set index of the selected segment:
                    idxSelectedSegment = idx;
                    // done!
                   break;
                }
            }
            // make sure the custom drawing area is updated!
            repaint();
        }
    }//mousePressed

    @Override
    public void mouseReleased(MouseEvent evt) {
        window.setStatus("mouseReleased");
        if (status == STATUS_SEGMENT_MOUSE_DRAG) {
            this.status = STATUS_SEGMENT_NONE;
            // remember this segment:
            segments.add(segmentX1);
            segments.add(segmentY1);
            segments.add(segmentX2);
            segments.add(segmentY2);
            repaint();
        }
    }//mouseReleased

    @Override
    public void mouseEntered(MouseEvent evt) {
    }

    @Override
    public void mouseExited(MouseEvent evt) {
    }

    @Override
    public void mouseClicked(MouseEvent evt) {
        // the mouse coordinates are
        // evt.getX()
        // evt.getY()
    }//mouseClicked

    // MouseMotionListener implementation
    @Override
    public void mouseMoved(MouseEvent evt) {
    }

    @Override
    public void mouseDragged(MouseEvent evt) {
        segmentX2 = evt.getX();
        segmentY2 = evt.getY();
        repaint();
    }//mouseDragged

}//class DrawingBox2D