package cisc181.mylab_6;

// Christopher Rasmussen
// CISC181, University of Delaware
// March, 2015

enum Direction { NORTH, SOUTH, EAST, WEST }

public class Turtle {

    static final int NUM_ROWS = 10;
    static final int NUM_COLS = 10;

    private int initial_row = NUM_ROWS / 2;
    private int initial_col = NUM_COLS / 2;
    private int row = initial_row;
    private int col = initial_col;
    private Direction direction = Direction.NORTH;
    private int forward = 1;
    private int lateral = 0;
    private int numSquaresTraveled = 0;

    // The default (no-argument) constructor should place the turtle initially at (NUM_ROWS / 2, NUM_COLS / 2), facing NORTH, with movement pattern (1, 0)

    Turtle() { }

    // A 3-argument constructor which sets the turtle's initial position and direction. The default movement pattern is used

    Turtle(int row, int col, Direction direction) {
        initial_row = row;
        initial_col = col;
        this.row = initial_row;
        this.col = initial_col;
        this.direction = direction;
    }

    // A 5-argument constructor which is like the 3-argument constructor, but adds the ability to set the movement pattern

    Turtle(int row, int col, Direction direction, int forward, int lateral) {
        this(row, col, direction);
        this.forward = forward;
        this.lateral = lateral;
    }

    // The turtle executes n counter-clockwise 90 degree turns

    void turn(int n) {

        for (int i = 0; i < n; i++) {
            switch (direction) {
                case NORTH:
                    direction = Direction.WEST;
                    break;
                case WEST:
                    direction = Direction.SOUTH;
                    break;
                case SOUTH:
                    direction = Direction.EAST;
                    break;
                case EAST:
                    direction = Direction.NORTH;
                    break;
            }
        }
    }

    // The turtle executes its current movement pattern n times. Any attempted movement that would land outside the grid is ignored
    // this version will execute moves *until* illegal then stop.  so it can do a "partial" move less than n

    void move(int n) {
        int new_row, new_col;

        for (int i = 0; i < n; i++) {

            // where turtle *would* be after this move

            switch (direction) {
                case NORTH:
                    new_row = row - forward;
                    new_col = col + lateral;
                    break;
                case WEST:
                    new_row = row - lateral;
                    new_col = col - forward;
                    break;
                case SOUTH:
                    new_row = row + forward;
                    new_col = col - lateral;
                    break;
                case EAST:
                    new_row = row + lateral;
                    new_col = col + forward;
                    break;
                default:
                    new_row = row;
                    new_col = col;
            }

            // if it's legal, allow it

            if (new_row >= 0 && new_row < NUM_ROWS && new_col >= 0 && new_col < NUM_COLS) {
                row = new_row;
                col = new_col;
                numSquaresTraveled += Math.abs(forward) + Math.abs(lateral);
            }

            // else illegal -> trying to leave grid!

            else {
                System.out.println("Trying to leave grid!");
                return;
            }
        }
    }

    // Negate forward and/or lateral component of movement pattern

    void flip(boolean doForward, boolean doLateral) {
        if (doForward) {
            forward = -forward;
        }
        if (doLateral) {
            lateral = -lateral;
        }
    }

    // accessors

    int getRow() { return row; }
    int getColumn() { return col; }
    Direction getDirection() { return direction; }

    // How many squares has the turtle moved forward and laterally since it was constructed?

    int squaresTraveled() {
        return numSquaresTraveled;
    }

    // double distanceToHome(): Euclidean distance from the turtle's current position to its initial position

    double distanceToHome() {
        return Math.hypot(row - initial_row, col - initial_col);
    }

}
