// Author: Alyce Brady
//
// License Information:
//   This class is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation.
//
//   This class is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.

import java.awt.Color;
import java.util.ArrayList;

import edu.kzoo.grid.ColorBlock;
import edu.kzoo.grid.Location;
import edu.kzoo.util.NamedColor;

/**
 *  Mouse in a Maze Program:<br>
 *      The Mouse class defines a mouse in a maze.
 *      The default Mouse does not move.  Subclasses may move in different
 *      ways.
 *
 *  @author  Alyce Brady
 *  @version 4 October 2025
 **/
public class Mouse extends ColorBlock
{
    // Instance Variables: Encapsulated data for EACH mouse
    private Maze theMaze;              // the maze in which this mouse moves
    private Location currentLocation;  // the location of this mouse
    private int stepCount;             // how many steps the mouse has taken
    private boolean amStuck;           // true if mouse cannot move

    /** Constructs a Mouse instance.
     **/
    public Mouse()
    {
        super(new NamedColor(Color.GRAY));
        this.stepCount = 0;
        this.amStuck = false;
    }

    /** Gets the maze in which this mouse runs.
     *  @return        the maze
     **/
    public Maze maze()
    {
        return (Maze) this.grid();
    }
    
    /** Gets the number of steps the mouse has taken.
     *  @return    the number of steps taken
     */
    public int getStepCount()
    {
        return this.stepCount;
    }

    /** Returns true if the mouse is stuck (cannot move), or false otherwise.
     */
    protected boolean isStuck()
    {
        return this.amStuck;
    }

    @Override
    public String toString()
    {
        return getClass().getName() + location().toString();
    }

    /** Moves this mouse. **/
    public void move()
    {
        // Determine where the mouse should move next.
        Location oldLocation = location();
        Location nextLocation = nextLocation();
        if ( nextLocation.equals(oldLocation) )
        {
            this.amStuck = true;
            return;
        }

        // If it is moving to the location with the cheese, it
        // should "eat" the cheese (remove it from the grid).
        if ( nextLocation.equals(maze().getFinishLoc()) &&
             ! maze().isEmpty(nextLocation) )
        {
            maze().remove(maze().objectAt(nextLocation));
        }

        // Change location and notify the environment.
        changeLocation(nextLocation);
        stepCount++;
    }

    /** Chooses a next location to move to, if possible.
     * (The base Mouse just returns the current location.)
     *  @return    a possible next location for the mouse
     **/
    protected Location nextLocation()
    {
        return this.location();
    }

}

