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

public class CircuitPanel extends JPanel {
    private Circuit circuit;
    private MouseListener currentMouseListener;
    private MouseMotionListener currentMouseMotionListener;
    public CircuitPanel() {
	setSize(400,300);
	currentMouseListener = null;
	currentMouseMotionListener = null;
    }
    public void setCircuit (Circuit cir) {
	circuit=cir;
    }
    
    public void paintComponent(Graphics g) 
    {
	super.paintComponent(g);
	Graphics2D g2d=(Graphics2D) g;
	
	circuit.paintComponents(g2d);
    }
    public void setRotarListeners(){
	changeMouseListener(new RotarMouseListener());
	changeMouseMotionListener(new RotarMouseMotionListener());
    }

    public void setMoverListener(){
	removeMouseListeners();
	changeMouseMotionListener(new MoverMouseMotionListener());	
    }

    public void changeMouseListener(MouseListener ml) {
	if (currentMouseListener != null) 
	    removeMouseListener(currentMouseListener);
	currentMouseListener = ml;
	addMouseListener(currentMouseListener);
    }

    public void changeMouseMotionListener(MouseMotionListener mml) {
	if (currentMouseMotionListener != null) {
	    removeMouseMotionListener(currentMouseMotionListener);
	}
	currentMouseMotionListener = mml;
	addMouseMotionListener(currentMouseMotionListener);
    }

    public void removeMouseListeners(){
	if (currentMouseListener != null) 
	    removeMouseListener(currentMouseListener);
	currentMouseListener=null;
	if (currentMouseMotionListener != null) 
	    removeMouseMotionListener(currentMouseMotionListener);
	currentMouseMotionListener = null;
    }

    class RotarMouseListener extends MouseAdapter {
	public void mouseClicked(MouseEvent event){
	    Component comp= circuit.find(event.getPoint());
	    if(comp!=null){ 
		comp.rotate(); repaint();
	    }
	}
    }
    
    class RotarMouseMotionListener extends MouseMotionAdapter {
	private Component colorComponent;
	public void mouseMoved(MouseEvent event) {
	    Component comp= circuit.find(event.getPoint());
	    if(comp!=null) {
		if (colorComponent!=null)
		    if (colorComponent==comp) return;
		    else colorComponent.unsetRed();
		comp.setRed();
		colorComponent=comp;
		repaint();
	    }
	    else if(colorComponent!=null) {
		colorComponent.unsetRed();
		colorComponent=null;
		repaint();
	    }
	}
    }  	
    class MoverMouseMotionListener extends MouseMotionAdapter {
	private Component colorComponent;
	private Point lastPoint;
	private boolean connected=false;
	public void mouseMoved(MouseEvent event) {
	    Component comp= circuit.find(event.getPoint());
	    lastPoint = event.getPoint();
	    if(comp!=null) {
		if (colorComponent!=null)
		    if (colorComponent==comp) return;
		    else colorComponent.unsetRed();
		comp.setRed();
		colorComponent=comp;
		repaint();
	    }
	    else if(colorComponent!=null) {
		colorComponent.unsetRed(); 
		colorComponent=null;
		repaint();
	    }
	}
	public void mouseDragged(MouseEvent event) {
	    Point newPoint = event.getPoint();
	    Point desplazamiento;
	    if(colorComponent!=null) {
		if (!connected) {
		    colorComponent.translate(newPoint.x-lastPoint.x, 
					     newPoint.y-lastPoint.y);
		    lastPoint=newPoint;
		    desplazamiento = circuit.findNearComponent(colorComponent);
		    if (desplazamiento != null) {
			colorComponent.translate(desplazamiento.x, //ajustar a otra.
						 desplazamiento.y);
			connected = true;
			lastPoint.translate(desplazamiento.x, desplazamiento.y);
		    }
		}
		else if (newPoint.distanceSq(lastPoint) > Circuit.UNION_DISTANCE){
		    colorComponent.translate(newPoint.x-lastPoint.x, 
					     newPoint.y-lastPoint.y);
		    lastPoint = newPoint;
		    connected = false;
		}
		repaint();
	    }
	}
    }  	
}