/*
    Aqui vamos a hacer un programa que nos permita hacer mosdificaciones de tipo, cambiar el color de los circulos,
    cambiar el tamanio del radio y cambiar la cantidad de circulos.... utillizar listados para poder elegir valores
    determinados.
　　　　　Ahora tratar de ingresar a mano los valores de la radio y de la cantidad de circulos.

CONCLUSIONES: Este grafico tiene algunos conceptos a considerar.  Los numeros multiplos de 4, se concentran en el (400,530) y en (400,270)
que son los puntos extremos superior e inferior del circulo.  Estos puntos del radio se aproximan al cero, y no dibuja ningun circulo.

*/

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.Vector;

public class hunsui extends Applet
{


   miCanvas mc;
   Panel pnl_1;
   Panel pnl_2 = new Panel ();
   Panel pnl_3 = new Panel ();
   Panel pnl_4 = new Panel ();
   Panel pnl_5 = new Panel ();

   Label lbl_1 = new Label ("色");
   Label lbl_2 = new Label ("横幅（1〜7）");
   Label lbl_3 = new Label ("縦幅（1〜10）");
   Label lbl_4 = new Label ("種類");

   TextField tf_nro_circulo = new TextField ("5");
   TextField tf_valor_radio = new TextField ("5");

   Choice color_circulo = new Choice ();
   Choice type_circulo = new Choice ();
   Choice center_circulo = new Choice ();

   Button botonCirculo = new Button ("変える");
   Button botonRadio = new Button ("変える");

   int n = Integer.parseInt(tf_nro_circulo.getText());
   int radio = Integer.parseInt(tf_valor_radio.getText());

  public void init ()
  {
    setBackground (Color.white);  /*  Dar color de fondo  */

    setLayout (new BorderLayout ());  /*  Divide en secciones  */
    //lbl_1.setFont (new Font ("TimesRoman", Font.BOLD, 15));
    //lbl_2.setFont (new Font ("TimesRoman", Font.BOLD, 15));
    //lbl_3.setFont (new Font ("TimesRoman", Font.BOLD, 15));
    add ("Center", mc = new miCanvas ());
    add ("North", pnl_1 = new Panel ());
    pnl_1.setBackground (Color.pink);
    pnl_1.setLayout (new GridLayout (2, 3));
    pnl_2.add (lbl_1);
    color_circulo.add ("ウォーター");
    color_circulo.add ("フレイム");
    color_circulo.add ("イルミネーション（紫）");
    color_circulo.add ("イルミネーション（緑）");
    pnl_2.add (color_circulo);
    pnl_1.add (pnl_2);
    pnl_3.add (lbl_2);
    pnl_3.add(tf_nro_circulo);
    pnl_3.add(botonCirculo);
    pnl_1.add (pnl_3);
    pnl_4.add (lbl_3);
    pnl_4.add (tf_valor_radio);
    pnl_4.add(botonRadio);
    pnl_1.add(pnl_4);
    pnl_5.add (lbl_4);
    type_circulo.add ("点＋線（中央あり）");
    type_circulo.add ("点＋線なし（中央あり）");
    type_circulo.add ("点＋線");
    type_circulo.add ("点＋線なし");
    type_circulo.add ("線のみ");
    pnl_5.add (type_circulo);
    pnl_1.add (pnl_5);

// oidores de los colores
    color_circulo.addItemListener ( new java.awt.event.ItemListener ()
    {
		public void itemStateChanged (ItemEvent e)
        {
    		mc.cambiaColorCirculo (color_circulo.getSelectedIndex ());

		}
	});
	botonCirculo.addActionListener ( new java.awt.event.ActionListener ()
	{
		public void actionPerformed (ActionEvent e)
		{
			mc.cambiaCantCirculo( Integer.parseInt(tf_nro_circulo.getText()));
		}
	});
	botonRadio.addActionListener ( new java.awt.event.ActionListener ()
	{
		public void actionPerformed (ActionEvent e)
		{
		mc.cambiaValorRadio( Integer.parseInt(tf_valor_radio.getText()));
		}
	});
	type_circulo.addItemListener ( new java.awt.event.ItemListener ()
	{
		public void itemStateChanged (ItemEvent e)
		{
			mc.cambiaTypeCirculo (type_circulo.getSelectedIndex ());
		}
    });
  }
}

class miCanvas extends Canvas {


  int color_circulo = 0;   /*  Color del circulo inicial es negro  */
  int type_circulo = 0;
  int center_circulo = 0;
  int n=1;                /*  50 es la cantidad de circulos que se dibujara en primera instancia  */
  int s=2;
  int haba = 5;
  double t = 4.5;
  double radio=130;        /*  130 va a ser el tamanno inicial del radio de los circulos  */

	int x1, y1, x1r, y1r, x2r, y2r;
  	int oL1[] = {1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2};
  	int tL1[] =	{0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2};
  	int thL1[] = {2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,2,0};
  	int oL2[] = {0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1};
  	int tL2[] =	{2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1};
  	int thL2[] = {1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1};
  	int i, colnum;

	FireFlower[] fire = new FireFlower[n];
	BigRain [] rain = new BigRain[s];

	miCanvas ()
	{
		super ();
	}

public void paint(Graphics g){
	x1 = 400;
	y1 = 200;

	x1r = 400;
	y1r = 30;


	/*  --- Defino el Color de los circulos ---  */


	switch (color_circulo) {
		case 0 : colnum = 0;
			break;
		case 1 : colnum = 1;
			break;
		case 2 : colnum = 2;
			break;
	    case 3 : colnum = 3;
	        break;
    }


	for(i = 0; i < n; i++){
		fire[i] = new FireFlower(x1, y1, t, oL1, tL1, thL1, colnum, haba);
	}
	for(i = 0; i < s; i++){
		rain[i] = new BigRain(x1r, y1r);
	}

    g.setColor(new Color(0,0,0));
	g.fillRect(0,0,800,800);
	for(i = 0; i < n; i++){
		fire[i].draw(g, type_circulo);
	}
	for(i = 0; i < s; i++){
		rain[i].draw(g, type_circulo, colnum);
	}
}

/*   --- para actualizar los valores ingresados ---- */

public void cambiaColorCirculo (int c)
  {
    color_circulo = c;
    repaint ();
}

void cambiaCantCirculo (int d)
{
    if(d < 1) d = 1;
    if(d > 7) d = 7;
    haba = d;
    repaint ();
}

void cambiaValorRadio (int e)
{
	if(e < 1) e = 1;
	if(e > 10) e = 10;
	double p = (double)e / 10;
    t = 4.0 + p;
    repaint ();
}

public void cambiaTypeCirculo (int t)
{
	type_circulo = t;
	repaint ();
}

}

//クラスは新たな型と同じ。型は変数を持つ。最初に書くメンバ変数こそ、型の変数となるもの。
class FireFlower {
	int ln1 = 20, ln2 = 30, ln3 = 40;
	Ball oneLine[] = new Ball[ln1];
	Ball twoLine[] = new Ball[ln2];
	Ball threeLine[] = new Ball[ln3];
	int sX[] = new int[100];
	int sY[] = new int[100];
	static final int v1 = 10, v2 = 20,v3 = 30;
	double dx, dy;

	//FireFlowerの計算で、出始めの明確な座標を作る
	public FireFlower(int x, int y, double t, int oL[], int tL[], int thL[], int colnum, int haba) {
		for(int i = 0; i < ln1; i++) {
			dx = (haba*v1)*Math.cos(2*i*Math.PI/ln1);
			dy = (v1/3)*Math.sin(2*i*Math.PI/ln1);
			oneLine[i] = new Ball(dx,dy,x,y,t,oL[i],colnum);
		}

		for(int i = 0; i < ln2; i++) {
			dx = ((haba+1)*v2)*Math.cos(2*i*Math.PI/ln2);
			dy = (v2/3)*Math.sin(2*i*Math.PI/ln2);
			twoLine[i] = new Ball(dx,dy,x,y,t,tL[i],colnum);
		}

		for(int i = 0; i < ln3; i++) {
			dx = ((haba)*v3)*Math.cos(2*i*Math.PI/ln3);
			dy = (v3/3)*Math.sin(2*i*Math.PI/ln3);
			threeLine[i] = new Ball(dx,dy,x,y,t,thL[i],colnum);
		}
	}

	public void draw(Graphics g, int type) {
		for(int i = 0; i < ln1; i ++) {
			switch (type) {
				case 0 : oneLine[i].draw(g, 0, 0);
					break;
				case 1 :
					break;
				case 2 : oneLine[i].draw(g, 0, 0);
					break;
				case 3 :
					break;
				case 4 : oneLine[i].draw(g, 0, 0);
					break;
    		}
		}

		for(int i = 0; i < ln2; i ++) {
			switch (type) {
				case 0 : twoLine[i].draw(g, 0, 0);
					break;
				case 1 :
					break;
				case 2 : twoLine[i].draw(g, 0, 0);
					break;
				case 3 :
					break;
				case 4 : twoLine[i].draw(g, 0, 0);
					break;
    		}
		}

		for(int i = 0; i < ln3; i ++) {
			switch (type) {
				case 0 :
					for(int z = 0; z < 100; z ++) {
						threeLine[i].draw(g, z, 1);
					}
					break;
				case 1 :
					for(int z = 0; z < 100; z ++) {
						threeLine[i].draw(g, z, 1);
					}
					break;
				case 2 :
					for(int z = 0; z < 100; z ++) {
						threeLine[i].draw(g, z, 1);
					}
					break;
				case 3 :
					for(int z = 0; z < 100; z ++) {
						threeLine[i].draw(g, z, 1);
					}
					break;
				case 4 : threeLine[i].draw(g, 0, 0);
					break;
	   		}
		}
	}
}

class Ball {
	int lX[] = new int[100];
	int lY[] = new int[100];
	int size = 1;
	double lT = 0;
	final static double grab = 8;
	Color col;

	//出始めの座標から、出先の座標までを描いて行く
	public Ball(double dx, double dy, int x, int y, double t, int c, int colnum) {
		if(c == 0) {
			switch (colnum) {
				case 0 : col = new Color(50, 50, 255);
					break;
				case 1 : col = new Color(255, 50, 50);
					break;
				case 2 : col = new Color(255, 0, 100);
					break;
			    case 3 : col = new Color(0, 255, 0);
			        break;
    		}

			for (int i = 99; i >= 0; i--) {
				if(t - 0.025*i < 0) {
					lT = 0;
				}else {
					lT = t - 0.025*i;	//線の長さ（上辺）
				}

				//ここをいじると、形そのものを変えられるということになる。
				lX[i] = x + (int) ((dx/2)*lT*Math.pow(0.9,lT));
				lY[i] = y + (int) ((dy*lT + (grab*lT*lT*lT)/2)/**Math.pow(0.9,lT)*/);	//後半は、線の長さ（下辺）　消せば最長になる
			}
		}else if(c == 1) {
			switch (colnum) {
				case 0 : col = new Color(150, 150, 255);
					break;
				case 1 : col = new Color(255, 150, 150);
					break;
				case 2 : col = new Color(255, 0, 150);
					break;
			    case 3 : col = new Color(0, 255, 100);
			        break;
    		}

			for (int i = 99; i >= 0; i--) {
				if(t - 0.020*i < 0) {
					lT = 0;
				}else {
					lT = t - 0.020*i;
				}
				lX[i] = (int) (x + (dx/2)*lT);
				lY[i] = (int) (y + dy*lT + (grab*lT*lT*lT)/2);
			}
		}else {
			switch (colnum) {
				case 0 : col = new Color(200, 200, 255);
					break;
				case 1 : col = new Color(255, 200, 200);
					break;
				case 2 : col = new Color(255, 0, 200);
					break;
			    case 3 : col = new Color(0, 255, 150);
			        break;
    		}

			for (int i = 99; i >= 0; i--) {
				if(t - 0.01*i < 0) {
					lT = 0;
				}else {
					lT = t - 0.01*i;
				}
				lX[i] = (int) (x + (dx/2)*lT);
				lY[i] = (int) (y + dy*lT + (grab*lT*lT*lT)/2);
			}
		}
	}

	public void draw(Graphics g, int z, int flag) {
		g.setColor(col);
		if(flag == 0){
			g.drawPolyline(lX, lY, 100);
		}else{
			if(z % 7 == 0){
				g.fillOval(lX[z], lY[z], size, size);
				size += 1;
			}
		}
	}
}

class BigRain {
	double dx, dy;

	//FireFlowerの計算で、出始めの明確な座標を作る
	public BigRain(int x, int y) {
		dx = x;
		dy = y;
	}

	public void draw(Graphics g, int type, int colnum) {
		double p=Math.PI;
		int i=0;
		int j=5;
		double gT = 1;
		double gS = 400;
		while(i<=15){

			double xR = (int) (dx - gT);
			double xL = (int) (dx + gT);
			double y = (int) (dy + gS);
			int XR = (int)Math.rint(xR);
			int XL = (int)Math.rint(xL);
			int Y = (int)Math.rint(y);

			switch (colnum) {
				case 0 : g.setColor(new Color(16*i,16*i,255));
					break;
				case 1 : g.setColor(new Color(255, 16*i,16*i));
					break;
				case 2 : g.setColor(new Color(255, 0, 16*i));
					break;
			    case 3 : g.setColor(new Color(0,255,13*i));
			        break;
    		}


			if(type == 0 || type == 1){
				g.fillOval(XR,Y,j,j);
				g.fillOval(XL,Y,j,j);
			}
			j=j+1;
			++i;
			gT = (gT * 1.2) + 0.5;
			gS = gS - (gS/10);
		}
	}
}
