import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.JPanel;

/**
 * Canvas is the panel where drawing is done
 * 
 * @author Joe Wanstrath. Created Mar 27, 2008.
 */
public class Canvas extends JPanel implements MouseListener,
		MouseMotionListener {

	/**
	 * array of shapes drawn
	 */
	public ArrayList<Tool> shapes = new ArrayList<Tool>();
	private ArrayList<Integer> xPositions = new ArrayList<Integer>();
	private ArrayList<Integer> yPositions = new ArrayList<Integer>();
	private ArrayList<Integer> xPoints = new ArrayList<Integer>();
	private ArrayList<Integer> yPoints = new ArrayList<Integer>();
	private Toolbar toolbar;
	private Colorbar colorbar;
	private Color active;
	private String tool;
	private Menubar menubar;
	private double xStart, yStart, xStop, yStop;

	/**
	 * 
	 * Painting panel
	 * 
	 */
	public Canvas() {
		this.setBackground(Color.WHITE);
		this.setLayout(new BorderLayout());
		Toolbar tools = new Toolbar();
		this.toolbar = tools;
		this.add(tools, BorderLayout.WEST);
		Colorbar colors = new Colorbar();
		this.colorbar = colors;
		this.active = this.colorbar.getActiveColor();
		this.add(this.colorbar, BorderLayout.SOUTH);
		Menubar menubar = new Menubar(this);
		this.menubar = menubar;
		this.add(this.menubar, BorderLayout.NORTH);
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
	}

	public void mouseClicked(MouseEvent e) {
		this.xPoints.add(e.getX());
		this.yPoints.add(e.getY());
		this.tool = this.toolbar.getActiveButton();
		if (this.tool.equals("Polygon")) {
			int[] x = new int[this.xPoints.toArray().length];
			int[] y = new int[this.xPoints.toArray().length];

			for (int i = 0; i < this.xPoints.size(); i++) {
				x[i] = this.xPoints.get(i);
				y[i] = this.yPoints.get(i);
			}
			if (x.length >= this.toolbar.getSides()) {
				paintPolygon p = new paintPolygon(x, y);
				p.setColor(this.active);
				this.shapes.add(p);
				this.xPoints = new ArrayList<Integer>();
				this.yPoints = new ArrayList<Integer>();
			}
		} else if (this.tool.equals("Text")) {
			Text t = new Text(e.getX(), e.getY(), this.active);
			this.shapes.add(t);
		}
		this.repaint();
	}

	public void mouseExited(MouseEvent e) {
		// empty
	}

	public void mousePressed(MouseEvent e) {
		this.active = this.colorbar.getActiveColor();
		this.tool = this.toolbar.getActiveButton();
		this.xStart = e.getX();
		this.yStart = e.getY();
	}

	public void mouseReleased(MouseEvent e) {
		this.xStop = e.getX();
		this.yStop = e.getY();
		double width = Math.abs(this.xStart - this.xStop);
		double height = Math.abs(this.yStart - this.yStop);
		if (this.tool.equals("Rectangle")) {
			if (this.xStart > this.xStop) {
				this.xStop = this.xStart;
				this.xStart = e.getX();
			}
			if (this.yStart > this.yStop) {
				this.yStop = this.yStart;
				this.yStart = e.getY();
			}

			Rectangle r = new Rectangle(this.xStart, this.yStart, width, height);
			r.setColor(this.active);
			this.shapes.add(r);

		} else if (this.tool.equals("Oval")) {
			if (this.xStart > this.xStop) {
				this.xStop = this.xStart;
				this.xStart = e.getX();
			}
			if (this.yStart > this.yStop) {
				this.yStop = this.yStart;
				this.yStart = e.getY();
			}

			Oval o = new Oval(this.xStart, this.yStart, width, height);
			o.setColor(this.active);
			this.shapes.add(o);

		} else if (this.tool.equals("Line")) {
			Line l = new Line(this.xStart, this.xStop, this.yStart, this.yStop);
			l.setColor(this.active);
			this.shapes.add(l);
		} else if (this.tool.equals("Pencil")) {
			for (int i = 1; i < this.xPositions.size() - 1; i++) {
				Pencil P = new Pencil(this.xPositions.get(i), this.yPositions
						.get(i), this.xPositions.get(i - 1), this.yPositions
						.get(i - 1));
				P.setColor(this.active);
				this.shapes.add(P);
			}
		} else if (this.tool.equals("Paintbrush")) {
			this.xPositions.trimToSize();
			this.yPositions.trimToSize();
			for (int i = 0; i < this.xPositions.size(); i++) {
				Paintbrush pb = new Paintbrush(this.xPositions.get(i),
						this.yPositions.get(i), 5,this.active);
				this.shapes.add(pb);
			}
		} else if (this.tool.equals("Eraser")) {
			this.xPositions.trimToSize();
			this.yPositions.trimToSize();
			for (int i = 0; i < this.xPositions.size(); i++) {
				Eraser E = new Eraser(this.xPositions.get(i), this.yPositions
						.get(i), 5);
				this.shapes.add(E);
			}
		}
		this.xPositions = new ArrayList<Integer>();
		this.yPositions = new ArrayList<Integer>();
		this.repaint();
	}

	public void mouseDragged(MouseEvent e) {
		this.xPositions.add(e.getX());
		this.yPositions.add(e.getY());
		if (this.tool.equals("Spraycan")) {
			double x = 5 * Math.random() - 5 * Math.random();
			double y = 5 * Math.random() - 5 * Math.random();
			Spraycan s = new Spraycan(e.getX() + x, e.getY() + y, this.active);
			this.shapes.add(s);
		}
	}

	public void mouseMoved(MouseEvent e) {
		// emmpty
	}

	public void mouseEntered(MouseEvent e) {
		// empty
	}

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;
		this.shapes.trimToSize();
		for (int i = 0; i < this.shapes.size(); i++) {
			g2.setColor(this.shapes.get(i).getColor());
			if (this.shapes.get(i) instanceof Paintbrush
					|| this.shapes.get(i) instanceof Eraser
					|| this.shapes.get(i) instanceof Spraycan) {
				Tool t = this.shapes.get(i);
				g2.fill(t);
			} else if (this.shapes.get(i) instanceof Text) {
				Text t = (Text) this.shapes.get(i);
				g2.drawString(t.getMessage(), t.getX(), t.getY());
			} else {
				g2.draw(this.shapes.get(i));
			}
		}
	}
}
