import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.*;
import java.util.ArrayList;

/**
 * A WorldPanel displays its associated World and the Shapes in that World.
 *
 * @author Matt Drosos and Colin DeClue.
 * started work 4/7/08
 */
public class WorldPanel extends JPanel implements MouseListener, MouseMotionListener {



	private ToolPanel toolPanel;
	private ArrayList<Shape> shapes;
	private Graphics2D graphics;
	private Dimension size;
	private ArrayList<Boolean> fill;
	private ArrayList<Color> colors;
	private boolean notDrawn;
	private int goTo;

	/**
	 * Makes this panel respond to mouse actions
	 * and repeatedly repaint itself.
	 *
	 * Also sets the size of this panel to the given size and
	 * associates this WorldPanel with the given World,
	 *
	 * @param size size of this panel.
	 * @param color Background color for this WorldPanel.
	 * @param toolPanel allows communication between ToolPanel and WorldPanel
	 * @param shapes an ArrayList of shapes drawn to the worldPanel
	 * @param fill an ArrayList of booleans telling whether to fill the shape or not
	 * @param colors an ArrayList of colors for each corresponding shape
	 * @param world the World associated with this WorldPanel.
	 */
	public WorldPanel(Dimension size, Color color, ToolPanel toolPanel, ArrayList<Shape> shapes, ArrayList<Boolean> fill, ArrayList<Color> colors) {
		
		this.setPreferredSize(size);
		this.size=size;
		this.colors = colors;
		this.setForeground(color);
		this.toolPanel = toolPanel;
		this.shapes = shapes;
		this.setVisible(true);
		this.notDrawn = true;
		this.goTo = 0;
		this.repaint();
		this.validate();
		this.fill = fill;
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		
		
	}

	/**
	 * Draws the World and all the shapes it contains
	 *
	 * @param g the Graphics object onto which to draw.
	 */
	@Override
	public void paintComponent(Graphics g) {
		if (this.notDrawn)
		{
			super.paintComponent(g);
		}
		this.graphics = (Graphics2D) g;
		if (this.notDrawn)
		{
			this.graphics.fill(new Rectangle(new Point(0,0), this.size));
			this.notDrawn = false;
		}
		this.graphics.setColor(Color.BLACK);
		for (int i =this.goTo; i < this.shapes.size(); i++)
		{
			this.graphics.setColor(this.colors.get(i));
			if (this.fill.get(i))
			{
				this.graphics.fill(this.shapes.get(i));
			}
			this.graphics.draw(this.shapes.get(i));
			this.goTo = i;
		}
	}
	
	/**
	 * resets the window
	 *
	 */
	public void reset()
	{
		this.shapes.clear();
		this.colors.clear();
		this.fill.clear();
		this.notDrawn = true;
		this.goTo = 0;
		this.repaint();
	}

	/**
	 * performs an action to the world panel based on the tool
	 *
	 * @param event The MouseEvent that caused this method to be invoked.
	 */
	public void mousePressed(MouseEvent event) {
		this.toolPanel.getCurrentTool().pressed(event);
		this.repaint();
	}

	/**
	 * performs an action to the world panel based on the tool
	 *
	 * @param event The MouseEvent that caused this method to be invoked.
	 */
	public void mouseReleased(MouseEvent event) {
		this.toolPanel.getCurrentTool().release(event);
		this.repaint();
	}

	/**
	 * Does nothing.
	 *
	 * @param event The MouseEvent that caused this method to be invoked.
	 */
	public void mouseEntered(MouseEvent event) {
		// Does nothing
	}

	/**
	 * Does nothing.
	 *
	 * @param event The MouseEvent that caused this method to be invoked.
	 */
	public void mouseExited(MouseEvent event) {
		// Does nothing
	}

	/**
	 * performs an action to the world panel based on what tool is selected
	 *
	 * @param event The MouseEvent that caused this method to be invoked.
	 */
	public void mouseClicked(MouseEvent event) {
		this.toolPanel.getCurrentTool().clicked(event);
		this.repaint();
	}

	/**
	 * For the selected Tool, draws the tool to the window at the current mouse point
	 *
	 * @param event The MouseEvent that caused this method to be invoked.
	 */
	public void mouseDragged(MouseEvent event) {
		this.toolPanel.getCurrentTool().dragged(event);
		this.repaint();
	}

	/**
	 * Does nothing.
	 *
	 * @param event The MouseEvent that caused this method to be invoked.
	 */
	public void mouseMoved(MouseEvent event) {
		//does nothing
	}


	/**
	 * resets the shapes index when button is clicked
	 *
	 */
	public void resetShapesIndex() {
		this.goTo=0;
		this.notDrawn = true;
		this.repaint();
	}
	
}
