/*
 * Created by IntelliJ IDEA.
 * User: lyon
 * Date: Feb 15, 2003
 * Time: 1:25:41 PM
 * To change template for new class use 
 * Code Style | Class Templates options (Tools | IDE Options).
 */
package ip.gui;

import java.awt.*;

public class GeometryUtils {
    private static void nextPointTest() {
        System.out.println(
                "input line:(0,10)->(100,100)" +
                " next point is:" + getNextPointOnLine(
                        new Point(0, 10), new Point(100, 100))
        );
    }

    public static void getNextDirectionTest() {
        System.out.println(
                "The points 1,1 and 23,23 have the next direction of:"
                + getNextDirection(new Point(1, 1), new Point(23, 23))
        );
    }

    /**
     *  getNextDirection returns an integer ranging from -1 to 8.
     *  -1 means it does not know the direction
     *  Here are the 8 directions
     *  6 7 8
     *  5   1
     *  4 3 2
     */
    public static int getNextDirection(Point startPoint, Point endPoint) {
        Point p2 = getNextPointOnLine(startPoint, endPoint);
        int x1 = startPoint.x;
        int y1 = startPoint.y;
        int x2 = p2.x;
        int y2 = p2.y;
        int dx = x2 - x1;
        int dy = y2 - y1;
        if (dx > 0 && dy < 0) return 2;
        if (dx == 0 && dy < 0) return 3;
        if (dx < 0 && dy < 0) return 4;
        if (dx < 0 && dy == 0) return 5;
        if (dx < 0 && dy > 0) return 6;
        if (dx == 0 && dy > 0) return 7;
        if (dx > 0 && dy > 0) return 8;
        if (dx > 0 && dy == 0) return 1;
        return -1;
    }

    /**
     * grabs a few points in the general direction
     */
    public static Points getNextPoints(Point p1, Point p2) {
        Point p0 = getNextPointOnLine(p1, p2);
        Points p = new Points();

        int dx = p0.x - p1.x;
        int dy = p0.y - p1.y;
        /**
         *  00,01,10,11
         */

        p.addPoint(p0);
        p.addPoint(new Point(p0.x + dx, p0.y));
        p.addPoint(new Point(p0.x, p0.y + dy));
        p.addPoint(new Point(p0.x + dx, p0.y + dy));
        return p;

    }

    /**
     *  Use Bresenham's algorithm to get the next point on a line.
     */

    public static Point getNextPointOnLine(Point p1, Point p2) {
        int x1 = p1.x;
        int y1 = p1.y;
        int x2 = p2.x;
        int y2 = p2.y;
        int x = x1;
        int y = y1;
        int d = 0;
        int dx = x2 - x1;
        int dy = y2 - y1;
        int c, m;
        int xInc = 1;
        int yInc = 1;

        if (dx < 0) {
            xInc = -1;
            dx = -dx;
        }

        if (dy < 0) {
            yInc = -1;
            dy = -dy;
        }

        if (dy <= dx) {
            c = 2 * dx;
            m = 2 * dy;

            x += xInc;

            d += m;

            if (d > dx) {
                y += yInc;
                d -= c;
            }
            return new Point(x, y);
        }

        c = 2 * dy;
        m = 2 * dx;
        y += yInc;

        d += m;

        if (d > dy) {
            x += xInc;
            d -= c;
        }
        return new Point(x, y);

    }

    static void drawLine(Graphics g, int x1, int y1, int x2, int y2) {
        int x = x1;
        int y = y1;
        int d = 0;
        int hx = x2 - x1;
        int hy = y2 - y1;
        int c, M;
        int xInc = 1;
        int yInc = 1;

        if (hx < 0) {
            xInc = -1;
            hx = -hx;
        }

        if (hy < 0) {
            yInc = -1;
            hy = -hy;
        }

        if (hy <= hx) {
            c = 2 * hx;
            M = 2 * hy;

            for (; ;) {
                ConvolutionUtils.drawPel(g, x, y);

                if (x == x2) break;

                x += xInc;

                d += M;

                if (d > hx) {
                    y += yInc;
                    d -= c;
                }

            }

        } else {
            c = 2 * hy;
            M = 2 * hx;

            for (; ;) {
                ConvolutionUtils.drawPel(g, x, y);

                if (y == y2) break;

                y += yInc;

                d += M;

                if (d > hy) {
                    x += xInc;
                    d -= c;
                }
            }
        }
    }
}