import java.util.Random;

/**
 * Created by zulupero on 09/11/15.
 */
public class TimesTables {

    static final Random rand = new Random();

    /**
     * Calcule les coordonnées cartésiennes de n points
     * sur le cercle trigo et les enregistre dans le tableau passé en paramètre
     * @param point le tableau des coordonnées [i][0]-> abscisse [i][1]-> ordonnée
     * @param n nombre de points à placer
     */
    public static void preCalc(double[][] point, int n){
        double ang = 2*Math.PI/n ;
        for (int i=0; i<n; i++) {
            point[i][0] = Math.cos(i*ang);
            point[i][1] = Math.sin(i*ang);
            StdDraw.point(point[i][0], point[i][1]);
        }
    }

    /**
     * Dessine les segments reliant chacun des n points d'indice i
     * à son correspondant i x tt
     * @param n nombre de points sur le cercle
     * @param tt facteur multiplicatif
     * @param col couleur de tracé
     */
    public static void drawTT(int n, double tt, java.awt.Color col) {
        StdDraw.setPenColor(col);
        StdDraw.clear();
        StdDraw.setPenRadius(0.005);
        StdDraw.circle(0.0, 0.0, 1.0);
        double[][] tPoint = new double[n][2];
        preCalc(tPoint, n);
        if (n<35) repPoints(n, tPoint);
        for (int i = 0; i < n; i++) {
            StdDraw.line(tPoint[i][0], tPoint[i][1], tPoint[(int) Math.round(tt * i) % n][0], tPoint[(int) Math.round(tt * i) % n][1]);
            //StdDraw.save("vid/tt3nvar/imgTT_" + String.valueOf(i) + ".png");
        }
    }

    /**
     * Dessine les rayons incidents émis depuis le point 0
     * vers chacun des n points du cercle, ainsi que les rayons réfléchis
     * en ces points.
     * @param n nombres de points sur le cercle
     * @param col couleur de tracé
     */
    public static void rayTrace(int n, java.awt.Color col){
        int r = col.getRed();
        int v = col.getGreen();
        int b = col.getBlue();
        int cpt = 1 ;
        double[][] point = new double[n][2];
        preCalc(point,n);
        StdDraw.clear();
        StdDraw.setPenRadius(0.005);
        StdDraw.circle(0.0, 0.0, 1.0);
        StdDraw.setPenRadius();
        double[][] tPoint = new double[n][2];
        preCalc(tPoint, n);
        if (n<35) repPoints(n, point);
        for (int i=0; i<n; i++){
            StdDraw.setPenColor(col);
            StdDraw.line(point[0][0], point[0][1], point[i][0], point[i][1]);
            //StdDraw.save("vid/ray30/imgTT_" + String.valueOf(cpt) + ".jpg");
            cpt++;
            StdDraw.setPenColor((int)(r*0.6), (int) (v * 0.6), (int) (b * 0.6));
            StdDraw.line(point[i][0], point[i][1], point[(2 * i) % n][0], point[(2 * i) % n][1]);
            //StdDraw.save("vid/ray30/imgTT_" + String.valueOf(cpt) + ".jpg");
            cpt++;
        }
    }

    /**
     * Affiche les indices des points à l'extérieur du cercle
     * Lorsque le nombre de points est trop grand, les textes se mélangent.
     * @param n nombre de points sur le cercle
     * @param point tableau des coordonnées cartésiennes des points
     */
    public static void repPoints(int n, double point[][]){
        StdDraw.setPenRadius(0.02);
        for (int i = 0; i < n; i++) {
            StdDraw.point(point[i][0], point[i][1]);
            StdDraw.text(point[i][0] * 1.1, point[i][1] * 1.1, String.valueOf(i));
        }
        StdDraw.setPenRadius();
    }

    /**
     * Génére une animation par appel de la méthode drawTT avec
     * le paramètre n variant de nMin à nMax.
     * @param tt facteur multiplicatif
     * @param nMin valeur mini de n
     * @param nMax valeur maxi de n
     */
    public static void animTTn(double tt, int nMin, int nMax) {
        for (int n = 10; n < nMax; n++) {
            StdDraw.setPenColor(StdDraw.BLACK);
            StdDraw.clear();
            StdDraw.setPenRadius(0.005);
            StdDraw.circle(0.0, 0.0, 1.0);
            StdDraw.setPenRadius();
            java.awt.Color col = new java.awt.Color(0, 128, 255);

            String aff = String.format("x %.1f", tt);
            StdDraw.text(-1.0, 1.0, aff);
            drawTT(n, tt, col);
            StdDraw.show(100);
        }
    }

    /**
     * Génére une animation par appel de la méthode drawTT avec
     * le paramètre tt variant de ttMin à ttMax.
     * @param ttMin valeur mini de tt
     * @param ttMax valeur maxi de tt
     * @param n nombre de points sur le cercle
     */
    public static void animTTtt(double ttMin, double ttMax, int n) {
        for (double tt = ttMin; tt < ttMax; tt+=0.1){
            StdDraw.setPenColor(StdDraw.BLACK);
            StdDraw.clear();
            StdDraw.setPenRadius(0.005);
            StdDraw.circle(0.0, 0.0, 1.0);
            StdDraw.setPenRadius();
            java.awt.Color col = new java.awt.Color(0, 128, 255);

            String aff = String.format("x %.1f", tt);
            StdDraw.text(-1.0, 1.0, aff);
            drawTT(n, tt, col);
            StdDraw.show(100);
        }
    }


    /**
     * Commenter / décommenter les appels selon le tracé chosi
     * @param args
     */
    public static void main(String[] args) {
        StdDraw.setXscale(-1.2, 1.2);
        StdDraw.setYscale(-1.2, 1.2);
        int nMin = 20 ;
        int nMax = 200;
        double ttMin = 3.0 ;
        double ttMax = 60.0 ;

        java.awt.Color col = new java.awt.Color(0, 128, 255);

            /*
             * décorations et production des images pour les TT
             *
            String aff = String.format("x %.1f", tt);
            StdDraw.text(-1.0,1.0, aff);
            //drawTT(n, tt, col);
            //StdDraw.save("vid/ttxn200/imgTT_" + String.valueOf(cpt) + ".jpg");
            cpt++ ;
            */

            // Décommenter selon les tracés souhaités

            // TT simple
            //drawTT(nMin, ttMin, col);

            // TT n variable
            //animTTn(ttMin, nMin, nMax);

            // TT tt variable
            //animTTtt(ttMin, ttMax, nMax);

            // lancer de rayon + reflexion sur cercle
            //rayTrace(nMin, col);
    }
}
