/*  
    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.   

*/

/* <applet code="ScarletMaple.class" width=800 height=800></applet> */

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.Vector;
import javax.swing.*;

public class ScarletMaple extends Applet {
	private static final int COLOR_CIRCULO = 0;	/*  Color del circulo inicial es negro  */
	public static final int MAPLE_N1 = 60, MAPLE_N2 = 4;	/*  50 es la cantidad de circulos que se dibujara en primera instancia  */
	private static final int RADIO = 100, SIZE = 100;	/*  100 va a ser el tamanno inicial del radio de los circulos  */ 
	private static final int LEAVES = 5, LEAVES_ANGLE = 240, STALK_RADIO = 8;
	
	miCanvas mc = new miCanvas();
	String[] szLbl = { null, "円の数", "円の幅", "大きさ", "葉の数", "角度幅", "茎の幅", null, null, null };
	Panel box = new Panel();
	Panel[] pnl = new Panel[szLbl.length];
	Label[] lbl = new Label[szLbl.length];
	
	TextField tf_nro_circulo = new TextField(Integer.toString(MAPLE_N1));
	TextField tf_valor_radio = new TextField(Integer.toString(RADIO));
	TextField tf_maple_size = new TextField(Integer.toString(SIZE));
	TextField tf_leaves = new TextField(Integer.toString(LEAVES));
	TextField tf_leavesAngle = new TextField(Integer.toString(LEAVES_ANGLE));
	TextField tf_stalkRadio = new TextField(Integer.toString(STALK_RADIO));
	
	Button color_circulo = new Button("色");
	Checkbox cbNotch = new Checkbox("弧", true), cbFill = new Checkbox("塗る", false);
	Button botonApply = new Button("変える");
	
	public ScarletMaple() {
		for (int n = 0; n < pnl.length; n++) pnl[n] = new Panel(new FlowLayout(FlowLayout.CENTER, 0, 0));
		for (int n = 0; n < lbl.length; n++) lbl[n] = new Label(szLbl[n]);
	}
	
	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(mc, BorderLayout.CENTER);
		add(box, BorderLayout.NORTH);
		
		box.setBackground(Color.pink);
		
		for (int n = 0; n < pnl.length; n++)
			pnl[n].add(lbl[n]);
		
		pnl[0].add(color_circulo);
		pnl[1].add(tf_nro_circulo);
		pnl[2].add(tf_valor_radio);
		pnl[3].add(tf_maple_size);
		pnl[4].add(tf_leaves);
		pnl[5].add(tf_leavesAngle);
		pnl[6].add(tf_stalkRadio);
		pnl[7].add(cbNotch);
		pnl[8].add(cbFill);
		pnl[9].add(botonApply);
		
		for (int n = 0; n < pnl.length; n++)
			box.add(pnl[n]);
		
		color_circulo.setBackground(Color.BLACK); color_circulo.setForeground(Color.WHITE);
		color_circulo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Color c = JColorChooser.showDialog(null, null, color_circulo.getBackground());
				if (c != null) color_circulo.setBackground(c);
			}
		});
		
		// oidores de los colores
		botonApply.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				applyParams();
				mc.apply();
			}
		});
		
		applyParams();
	}
	
	private void applyParams() {
		mc.cambiaColorCirculo(color_circulo.getBackground());
		mc.cambiaCantCirculo(Integer.parseInt(tf_nro_circulo.getText()));
		mc.cambiaValorRadio(Double.parseDouble(tf_valor_radio.getText()));
		mc.setSize(Double.parseDouble(tf_maple_size.getText()));
		mc.setLeaves(Integer.parseInt(tf_leaves.getText()));
		mc.setLeavesAngle(Double.parseDouble(tf_leavesAngle.getText()));
		mc.setStalkRadio(Double.parseDouble(tf_stalkRadio.getText()));
		mc.setStyle(cbNotch.getState(), cbFill.getState());
	}
}

class miCanvas extends Canvas {
	private Color color_circulo;
	private int mN1, mN2 = ScarletMaple.MAPLE_N2, leaves;
	private double radio, size, leavesAngle, stalkRadio;
	private boolean isNotch, isFill;
	private static final double D_RADIX = 2.0;
	
	public void paint(Graphics g) {
		int i = 0;
		double radio1;
		double dt = 2.0 * Math.PI / mN1;
		double h = radio * Math.cos(dt);
		double x = 400;
		double y = 400;
		
		double x1, y1, x2, y2;
		double r, q, q360, d;
		int nc, leavesM1 = (int) Math.max(1, leaves - 1);
		
		g.setColor(color_circulo);
		
		for (int l = 0; l < leaves; l++) {
			q360 = (-90 + (180 - leavesAngle) / 2) + leavesAngle * l / leavesM1;
			q = Math.PI * 2.0 * q360 / 360; nc = 0;
			d = (D_RADIX * leavesM1 - Math.abs(leavesM1 / 2.0 - l)) / (D_RADIX * leavesM1);
			for (double t = 0; t < Math.PI; nc++, t += (1.0 / (mN1 / 2) - (0.95 / (mN1 / 2)) * t / Math.PI) * Math.PI) {
				x2 = x;
				y2 = -size * d * 0.8 * (t + Math.pow(t, 7.5) * 0.00025) + y;
				r = Math.abs(size * radio * Math.sin(t) / 100);
				
				x1 = (x2 - x) * Math.cos(q) - (y2 - y) * Math.sin(q) + x;
				y1 = (x2 - x) * Math.sin(q) + (y2 - y) * Math.cos(q) + y;
				
				drawOval(g, x1 - r / 2, y1 - r / 2, r, r);
				
				if (nc % (mN1 / 2 / mN2) == 0) {
					double r2 = r * 1.2;
					drawArc(g, x1 - r2 / 2, y1 - r2 / 2, r2, r2, 0 + (t / Math.PI - 0.05) * 30 - q360, -180 - (t / Math.PI - 0.05) * 60);
					
					//g.drawLine((int) x, (int) (y1 + (y - y1) / 8.0), (int) (x + r / 2 * 1.2), (int) y1);
					//g.drawLine((int) (x + r / 2 * 1.2), (int) y1, (int) x, (int) y);
					//g.drawLine((int) x, (int) (y1 + (y - y1) / 8.0), (int) (x - r / 2 * 1.2), (int) y1);
					//g.drawLine((int) (x - r / 2 * 1.2), (int) y1, (int) x, (int) y);
				}
			}
		}
		
		//for (double t = 0; t < Math.PI; t += (1.0 / mN1 - (0.95 / mN1) * t / Math.PI) * Math.PI) {
		for (double t = 0; t < Math.PI; t += Math.PI / mN1) {
			x1 = x;
			y1 = 100.0 * (t - Math.pow(t, 7.5) * 0.00025) + y;
			r = stalkRadio + Math.abs(stalkRadio * Math.sin(t));
			
			drawOval(g, x1 - r / 2, y1 - r / 2, r, r);
		}
		
		/*    --- Aqui dibuja el primer circulo central ---    */
	}
	
	/*   --- para actualizar los valores ingresados ---- */ 
	
	public void cambiaColorCirculo(Color c) {
	    color_circulo = c;
	}
	
	public void cambiaCantCirculo(int d) {
	    mN1 = d;
	}
	
	public void cambiaValorRadio(double e) {
	    radio = e;
	}
	
	public void setSize(double e) { size = e; }
	public void setLeaves(int e) { leaves = e; }
	public void setLeavesAngle(double r) { leavesAngle = r; }
	public void setStalkRadio(double e) { stalkRadio = e; }
	public void setStyle(boolean n, boolean f) { isNotch = n; isFill = f; }
	
	public void apply() { repaint(); }
	
	private void drawOval(Graphics g, double x, double y, double r0, double r1) {
		if (isFill) g.fillOval((int) x, (int) y, (int) r0, (int) r1);
		else g.drawOval((int) x, (int) y, (int) r0, (int) r1);
	}
	
	private void drawArc(Graphics g, double x, double y, double r0, double r1, double a0, double a1) {
		if (!isNotch) return;
		if (isFill) g.fillArc((int) x, (int) y, (int) r0, (int) r1, (int) a0, (int) a1);
		else g.drawArc((int) x, (int) y, (int) r0, (int) r1, (int) a0, (int) a1);
	}

}