/**
 * ShuffleBoardPanel.java
 *
 * Caitlin Ross
 * 100735219
 */

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ShuffleBoardPanel extends JPanel implements MouseListener, MouseMotionListener, ActionListener{
	
	//public static int width;
	private Image fullShuffleBoard;
	private Weight player1[];
	private Weight player2[];
	//private Color player1Color;
	//private Color player2Color;
	private int numOfWeights = 4;
	private int speed;
	private Weight dragWeight;
	private ShuffleBoardFrame frame;
	private CollisionSet collisions = new CollisionSet();
	
	private int milliseconds = 2; //time between timer events
    private Timer timer = new Timer(milliseconds, this);
    
    private int leftWall;
    private int rightWall;
    private int top;
    private int bottom;
    
    private int startX;
    private int startY;

    public ShuffleBoardPanel(ShuffleBoardFrame aFrame) {
    	setLayout(null);
    	frame = aFrame;
    	fullShuffleBoard = Toolkit.getDefaultToolkit().createImage("fullShuffleBoard.JPG");
    	while ((fullShuffleBoard.getWidth(null) == -1) && (fullShuffleBoard.getHeight(null) == -1));
    	setPreferredSize(new Dimension(fullShuffleBoard.getWidth(null), fullShuffleBoard.getHeight(null)));
    	
    	leftWall = 0;
    	rightWall = fullShuffleBoard.getWidth(null);
    	top = 0;
    	bottom = fullShuffleBoard.getHeight(null);
    	
    	speed = 1;
    	
    	/*for(int i=0; i<3; i++){
    		player1[i] = newPlayer1[i];
    		player2[i] = newPlayer2[i];
    	}*/
    	player1 = new Weight[numOfWeights];
    	player2 = new Weight[numOfWeights];
    	dragWeight = null;
    	addEventHandlers();
    }
    
    //public static int getWidth(){return fullShuffleBoard.getWidth(null);}
    
    public void paintComponent(Graphics g){
    	super.paintComponent(g);
    	g.drawImage(fullShuffleBoard, 0, 0, null);
    	for(int i=0; i<numOfWeights; i++){
    		player1[i].drawWith(g);
    		player2[i].drawWith(g);
    	}
    	/*if(dragWeight!=null)
    		dragWeight.drawWith(g);*/
    	//System.out.println("Painting Board Panel:");
    	//System.out.println("\tPlayer 1: " + player1Color);
    	//System.out.println("\tPlayer 2: " + player2Color + "\n");
    }
    
    public void reset(Graphics g, Weight newPlayer1[], Weight newPlayer2[]){
    	/*super.paintComponent(g);
    	g.drawImage(fullShuffleBoard, 0, 0, null);*/
    	
    	for(int i=0; i<numOfWeights; i++){
    		player1[i] = newPlayer1[i];
    		//player1[i].setColor(player1Color);
    		player2[i] = newPlayer2[i];
    		//player2[i].setColor(player2Color);
    	}
    	//repaint();
    	addEventHandlers();
    	timer.start();
    	update();
    }
    
    public void setSpeed(int aSpeed){
    	if(aSpeed >=0 && aSpeed <=2)
    		speed = aSpeed;
    }
    
    public void setColors(Color color1, Color color2){
    		//player1Color = color1;
    		//player2Color = color2;
    		for(int i=0; i<numOfWeights; i++){
    			if(player1[i]!=null)
    				player1[i].setColor(color1);
    			if(player2[i]!=null)
    			player2[i].setColor(color2);
    		}
    		//System.out.println("Player 1: " + player1Color);
    		//System.out.println("Player 2: " + player2Color + "\n");
    }
    
	public void update() {
		removeEventHandlers();
		repaint();
		addEventHandlers();
    }
    
	public Weight weightAt(Point p) {
		/*for (Weight n:  nodes) {
			Point c = n.getLocation();
			int d = (p.x - c.x) * (p.x - c.x) + (p.y - c.y) * (p.y - c.y);
			if (d <= (15*15))  return n;
		}*/
		for(int i=0; i<numOfWeights; i++){
			Point c = player1[i].getLocation();
			int d = (p.x - c.x) * (p.x - c.x) + (p.y - c.y) * (p.y - c.y);
			if (d <= (player1[i].getRadius()*player1[i].getRadius())){
				//System.out.println("Weight: Player 1, weight # " + i); 
				return player1[i];
			}
			c = player2[i].getLocation();
			d = (p.x - c.x) * (p.x - c.x) + (p.y - c.y) * (p.y - c.y);
			if (d <= (player2[i].getRadius()*player2[i].getRadius())){
				//System.out.println("Weight: Player 2, weight # " + i); 
				return player2[i];
			}
		}
		//System.out.println("No Weight selected");
		return null;
	}
    
	public void addEventHandlers() {
		addMouseListener(this);
		addMouseMotionListener(this);
	}
	public void removeEventHandlers() {
		removeMouseListener(this);
		removeMouseMotionListener(this);
	}
	
	public void mouseClicked(MouseEvent event) { }
    public void mousePressed(MouseEvent event) {
		Weight   aWeight = weightAt(event.getPoint());
		if (aWeight != null && aWeight.isInBounds()) {
			//System.out.println("Weight selected");
			dragWeight = aWeight;
		}
	}
	public void mouseDragged(MouseEvent event){
		if (dragWeight != null){
			dragWeight.setLocation(event.getPoint());
			//System.out.println("Weight Dragged");
		}
		//System.out.println("No Weight selected");	
		update(); 
	}
    public void mouseReleased(MouseEvent event) {
    	if(dragWeight!=null)
    		startMotion(dragWeight, event.getX(), event.getY());
    	dragWeight = null;
    }
    public void mouseEntered(MouseEvent event) { }
    public void mouseExited(MouseEvent event) { }
    public void mouseMoved(MouseEvent event) { }
    
    public void actionPerformed(ActionEvent e){
		for(int i=0; i<numOfWeights; i++) {
            //Ball b = Balls.get(i);
			Weight w = player1[i];
			w.advance(milliseconds, 1);
			if(w.isMoving()){
				checkBounds(w);
				Weight t = WeightTouching(w);
				if(w!=null && t!=null) collisions.add(w,t);
			}
			collisions.removeOldCollisions();
			w = player2[i];
			w.advance(milliseconds, 1);
			if(w.isMoving()){
				checkBounds(w);
				Weight t = WeightTouching(w);
				if(w!=null && t!=null){
					collisions.add(w,t);
				}
			}
			collisions.removeOldCollisions();
		}
		update(); 
    }
    
    public void startMotion(Weight aWeight, int x, int y){
    	aWeight.setMoving(true);
    	aWeight.setvx((startX - x)/10);
    	aWeight.setvy((startY - y)/10);
    	startX = 0;
    	startY = 0;
    	update();
    }
    
	public void checkBounds(Weight w) {
		if(w.getLocationX() < leftWall){
			w.setMoving(false);
			w.setLocation(leftWall + w.getRadius(), w.getLocationY());
			w.stop();
			w.outOfBounds();
		}
		if (w.getLocationX() > rightWall) {
			w.setMoving(false);
			w.setLocation(rightWall - w.getRadius(), w.getLocationY());
			w.stop();
			w.outOfBounds();
		}
		if (w.getLocationY() < top) { 
			w.setMoving(false);
			w.setLocation(w.getLocationX(), top + w.getRadius());
			w.stop();
			w.outOfBounds();
		}
		if (w.getLocationY() > bottom) { 
			w.setMoving(false);
			w.setLocation(w.getLocationX(), bottom - w.getRadius());
			w.stop();
			w.outOfBounds();
		}            
	}
	
	public Weight WeightTouching(Weight s) {
          Point p = s.getLocation();
          for (int i=0; i<numOfWeights; i++) {
            Weight aWeight = player1[i];
            int distance = (p.x - aWeight.getLocation().x) * (p.x - aWeight.getLocation().x) +
                           (p.y - aWeight.getLocation().y) * (p.y - aWeight.getLocation().y);
            if ((distance <= 4*(aWeight.getRadius() * aWeight.getRadius())) && (aWeight != s) )
                return aWeight;
            
            aWeight = player2[i];
            distance = (p.x - aWeight.getLocation().x) * (p.x - aWeight.getLocation().x) +
                           (p.y - aWeight.getLocation().y) * (p.y - aWeight.getLocation().y);
            if ((distance <= 4*(aWeight.getRadius() * aWeight.getRadius())) && (aWeight != s) )
                return aWeight;
           }
           return null;
        }
	public void endTimer(){
		timer.stop();
	}
    
}