import java.awt.event.MouseEvent;

/******************************************************************************
 *  Compilation:  javac Balle.java
 *  Execution:    java Balle
 *  Dependences: StdDraw.java
 *
 * balle rebondissante avec gravité
 * De bonnes valeurs pour les paramètres v[0], v[1], elast --> 0.1 0.1 0.9
 ******************************************************************************/

public class Balle {

    public static void main(String[] args) {
		StdDraw.enableDoubleBuffering();
		// échelles de la fenêtre
		StdDraw.setXscale(-1.0, 1.0);
		StdDraw.setYscale(-1.0, 1.0);


		// valeurs initiales. Pas en constantes car on peut éventuellement les prendre en ligne de commande
		double radius = 0.05;
		// gravité
		double g = 0.003;
		// elasticité <==> perte d'énergie au rebond
		double elast = 0.9;

        double[] p = new double[2];
        double[] v = new double[2];

        dragMouse(p, v);

        StdDraw.setPenColor(StdDraw.BLACK);
        StdDraw.filledCircle(p[0], p[1], radius);


		while (true) {
			// rebond sur murs verticaux
			if (Math.abs(p[0] + v[0]) >= 1.0 - radius) {
				v[0] = -elast * v[0];
				v[1] = elast * v[1] - g;
			}
			//rebond sur murs horizontaux
			else if (Math.abs(p[1] + v[1]) >= 1.0 - radius) {
				v[0] = elast * v[0];
				v[1] = -elast * v[1] - g;
			} else {
				v[1] = v[1] - g;
			}
			// mise à jour position
			p[0] += v[0];
			p[1] += v[1];

			if (p[1] < -1.0 + radius) p[1] = -1.0 + radius;

			// effacer la fenêtre
			StdDraw.clear(StdDraw.GRAY);
			// dessiner la balle
			StdDraw.setPenColor(StdDraw.BLACK);
			StdDraw.filledCircle(p[0], p[1], radius);

			// rafraichissement chaque 20ms
			StdDraw.show();
			StdDraw.pause(20);
		}
	}

    /**
     * Methode pour gérer un drag'n drop avec les capacités rudimentaires de StdDraw
     * @param p tableau des coordonnées du point cliqué
     * @param d tableau des coordonnées du vecteur 'dragué'
     */
    public static void dragMouse(double[] p, double[] d){
        boolean isDragging = false;
		boolean endDragging = false;
        while (!endDragging) {
            // clic initial
            if (StdDraw.isMousePressed() && !isDragging) {
                p[0] = StdDraw.mouseX();
                p[1] = StdDraw.mouseY();
                isDragging = true;
            }

            // tire un segment avec la souris (dragging)
            else if (StdDraw.isMousePressed() && isDragging) {
                d[0] = StdDraw.mouseX() - p[0];
                d[1] = StdDraw.mouseY() - p[1];
                StdDraw.clear();
                StdDraw.line(p[0], p[1], StdDraw.mouseX(), StdDraw.mouseY());
                StdDraw.show();
                StdDraw.pause(50);
            }

            // relache la souris
            else if (!StdDraw.isMousePressed() && isDragging) {
                isDragging = false;
				endDragging = true;
            }
        }
    }

}
