/**
   @version 1.30 2000-06-03
   @author Cay Horstmann
*/

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

public class MouseTestPerspective2
{
   public static void main(String[] args)
   {
      MouseFrame frame = new MouseFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.show();
   }
}

/**
   A frame containing a panel for testing mouse operations
*/
class MouseFrame extends JFrame
{
   public MouseFrame()
   {
      setTitle("MouseTest");
      setSize(500, 500);

      // add panel to frame

      MousePanel panel = new MousePanel();
      Container contentPane = getContentPane();
      contentPane.add(panel);
   }

   public static final int WIDTH = 500;
   public static final int HEIGHT = 500;
}

/**
   A panel with mouse operations for adding and removing squares.
*/
class MousePanel extends JPanel
{


   public MousePanel()
   {
      squares = new ArrayList();
      current = null;

      addMouseListener(new MouseHandler());
      addMouseMotionListener(new MouseMotionHandler());
   }

   public void paintComponent(Graphics g)
   {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D)g;

      // draw all squares
      for (int i = 0; i < squares.size(); i++){

         Rectangle3D r = (Rectangle3D)squares.get(i);
         r.disegna(g);
       }
   }

	public Point2D getCenter(){return new Point2D.Double(getWidth()/2, getHeight()/2);}


	public double distanza(double x1, double y1, double x2, double y2){
		double dx = (x2-x1)*(x2-x1);
		double dy = (y2-y1)*(y2-y1);
		return Math.sqrt(dx+dy);
	}
	public double distCentro(Point2D p){
		double dx = (getWidth()/2-(p.getX()))*(getWidth()/2-(p.getX()));
		double dy = (getHeight()/2 - (p.getY()))*(getHeight()/2-(p.getY()));
		return Math.sqrt(dx+dy);
	}

   /**
      Finds the first square containing a point.
      @param p a point
      @return the index of the first square that contains p
   */
   public Rectangle3D find(Point2D p)
   {
      for (int i = 0; i < squares.size(); i++)
      {
         Rectangle3D r = (Rectangle3D)squares.get(i);
         if (r.contains(p)) return r;
      }

      return null;
   }

   /**
      Adds a square to the collection.
      @param p the center of the square
   */
   public void add(Point2D p)
   {
      double x = p.getX();
      double y = p.getY();
	double dist = distanza(x - SIDELENGTH / 2, y - SIDELENGTH/2,getCenter().getX(),getCenter().getY());
	colore = new Color(0,0,(int)(dist/getCenter().getX()));
      current = new Rectangle3D(
         new Point2D.Double(x - SIDELENGTH / 2,
         y - SIDELENGTH / 2),
         SIDELENGTH,new Point2D.Double(getWidth()/2, getHeight()/2),
         colore);
      squares.add(current);
      repaint();
   }

   /**
      Removes a square from the collection.
      @param s the square to remove
   */
   public void remove(Rectangle3D s)
   {
      if (s == null) return;
      if (s == current) current = null;
      squares.remove(s);
      repaint();
   }


   private int SIDELENGTH = 20;
	private double DIST, dist, raggio, rMin=4;
private Color colore;
   private ArrayList squares;
   private Rectangle3D current;
   // the square containing the mouse cursor

   private class MouseHandler extends MouseAdapter
   {
      public void mousePressed(MouseEvent event)
      {
         // add a new square if the cursor isn't inside a square
         current = find(event.getPoint());
         if (current == null)
            add(event.getPoint());
      }

      public void mouseClicked(MouseEvent event)
      {
         // remove the current square if double clicked
         current = find(event.getPoint());
         if (current != null && event.getClickCount() >= 2)
            remove(current);
      }
   }

   private class MouseMotionHandler implements MouseMotionListener
   {
      public void mouseMoved(MouseEvent event)
      {
         // set the mouse cursor to cross hairs if it is inside
         // a rectangle

         if (find(event.getPoint()) == null)
            setCursor(Cursor.getDefaultCursor());
         else
            setCursor(Cursor.getPredefinedCursor
               (Cursor.CROSSHAIR_CURSOR));
      }

      public void mouseDragged(MouseEvent event)
      {
         if (current != null)
         {
            int x = event.getX();int y = event.getY();
            double dist = distanza(x - SIDELENGTH / 2, y - SIDELENGTH/2,getCenter().getX(),getCenter().getY());

            	DIST = distCentro(getCenter());
           // dist = distCentro(current.getCenter());
			raggio = ((SIDELENGTH)/getCenter().getX()*dist)+rMin;
			System.out.println(raggio);


		//	dim= (int)(SIDELENGTH/getCenter().getX()*dist);
            // drag the current rectangle to center it at (x, y)
            int sample = 255-(int)raggio*10;
            if (sample<0) sample =0;
		colore = new Color(sample,sample,sample );

         	current.sposta(x-raggio,y-raggio,(int)raggio);

            current.setColor(colore);
            squares.add(current);
            repaint();

            }
      }



   }
}


class Rectangle3D
{
	private Polygon[] rect3D = new Polygon[6];
	private Point2D CENTRO;
	private int[][] xPoint = new int[6][4],
					yPoint = new int[6][4];
	private Color colore;
	private int X, Y, BASE, ALTEZZA, nPoint = 4, R;

	public Rectangle3D(Point2D centro, int raggio, Point2D c, Color colore){
		CENTRO = c;
		R = raggio;
		this.colore = colore;

		crea(centro, raggio);

	}

	public void crea(Point2D centro, int raggio){
		xPoint[0][0] = (int)centro.getX()-raggio;	xPoint[0][1] = (int)centro.getX()+raggio;
		xPoint[0][2] = (int)centro.getX()+raggio;	xPoint[0][3] = (int)centro.getX()-raggio;
		yPoint[0][0] = (int)centro.getY()-raggio;	yPoint[0][1] = (int)centro.getY()-raggio;
		yPoint[0][2] = (int)centro.getY()+raggio;	yPoint[0][3] = (int)centro.getY()+raggio;
		makePrism(xPoint,yPoint,nPoint);
	}

	public Point2D puntoPros(int px, int py){
		double dx = (CENTRO.getX()-px)*(0.7/5.);
		double dy = (CENTRO.getY()-py)*(0.7/5.);
		double x = px + dx;
		double y = py + dy;

		return new Point2D.Double(x,y);
	}

	public void generaPunti(){

		xPoint[1][0] = xPoint[0][0];
		xPoint[1][1] = xPoint[0][1];
		xPoint[1][2] = (int)(puntoPros(xPoint[0][1],yPoint[0][1]).getX());
		xPoint[1][3] = (int)(puntoPros(xPoint[0][0],yPoint[0][0]).getX());
		yPoint[1][0] = yPoint[0][0];
		yPoint[1][1] = yPoint[0][1];
		yPoint[1][2] = (int)(puntoPros(xPoint[0][1],yPoint[0][1]).getY());
		yPoint[1][3] = (int)(puntoPros(xPoint[0][0],yPoint[0][0]).getY());

		xPoint[2][0] = xPoint[0][1];
		xPoint[2][1] = xPoint[0][2];
		xPoint[2][2] = (int)(puntoPros(xPoint[0][2],yPoint[0][2]).getX());
		xPoint[2][3] = (int)(puntoPros(xPoint[0][1],yPoint[0][1]).getX());
		yPoint[2][0] = yPoint[0][1];
		yPoint[2][1] = yPoint[0][2];
		yPoint[2][2] = (int)(puntoPros(xPoint[0][2],yPoint[0][2]).getY());
		yPoint[2][3] = (int)(puntoPros(xPoint[0][1],yPoint[0][1]).getY());

		xPoint[3][0] = xPoint[0][2];
		xPoint[3][1] = xPoint[0][3];
		xPoint[3][2] = (int)(puntoPros(xPoint[0][3],yPoint[0][3]).getX());
		xPoint[3][3] = (int)(puntoPros(xPoint[0][2],yPoint[0][2]).getX());
		yPoint[3][0] = yPoint[0][2];
		yPoint[3][1] = yPoint[0][3];
		yPoint[3][2] = (int)(puntoPros(xPoint[0][3],yPoint[0][3]).getY());
		yPoint[3][3] = (int)(puntoPros(xPoint[0][2],yPoint[0][2]).getY());

		xPoint[4][0] = xPoint[0][3];
		xPoint[4][1] = xPoint[0][0];
		xPoint[4][2] = (int)(puntoPros(xPoint[0][0],yPoint[0][0]).getX());
		xPoint[4][3] = (int)(puntoPros(xPoint[0][3],yPoint[0][3]).getX());
		yPoint[4][0] = yPoint[0][3];
		yPoint[4][1] = yPoint[0][0];
		yPoint[4][2] = (int)( puntoPros(xPoint[0][0],yPoint[0][0]).getY() );
		yPoint[4][3] = (int)(puntoPros(xPoint[0][3],yPoint[0][3]).getY());

		xPoint[5][0] = xPoint[1][2];
		xPoint[5][1] = xPoint[1][3];
		xPoint[5][2] = xPoint[3][2];
		xPoint[5][3] = xPoint[3][3];
		yPoint[5][0] = yPoint[1][2];
		yPoint[5][1] = yPoint[1][3];
		yPoint[5][2] = yPoint[3][2];
		yPoint[5][3] = yPoint[3][3];


	}

	public void makePrism(int[][] x, int[][] y, int n){
		generaPunti();
		for (int k = 0; k<rect3D.length; k++)
			rect3D[k] = new Polygon(x[k], y[k], n);
	}
	public void disegna(Graphics g){
		Graphics2D g2 = (Graphics2D) g;

		for(int k = rect3D.length-1; k >=0; k--){
			if (k>0) g2.setPaint(colore);
			else if (k==0) g2.setPaint(colore);

			g2.draw(rect3D[k]);
		}
	}

	public void setColor(Color c){
		colore = c;
	}

	public boolean contains(Point2D p){
		return rect3D[0].contains(p);
	}

	public Point2D getCenter(){
		return CENTRO;
	}

	public void sposta(double x, double y, int raggio){
		crea(new Point2D.Double(x, y), raggio);
	}
}


