import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class kouyoujyu extends Applet {

    Button drawButton;
    Choice angleChoice, scaleChoice, timesChoice;
    int times = 3;		// 繰り返し回数の初期値
    int angle = 20;		// 枝の角度の回数
    double scale = 0.7;		// 枝の長さの比率初期値
    double length = 60.0;	// 幹の長さ
    int initAngle = 90;		// 幹の角度
    int width, height;
    double radian;


    public void init() {

	width = getSize().width;    // 表示領域の幅を取得
	height = getSize().height;  // 表示領域の高さを取得
	radian  = Math.PI / 180.0;  // 1度に対するラジアンの値の計算

	drawButton = new Button("draw");  // ボタンdrawの生成

	//RGB を 0F-1.0F で指定
	Color bgc = new Color(0.2F,0.2F,0.5F);
	//RGB をフィールドで指定
	Color fgc = Color.white;

	scaleChoice = new Choice();  // チョイスscaleChoiceの生成
	for (int i = 70; i >= 40; i -= 5) {  // scaleChoiceにアイテムの設定
	    scaleChoice.addItem("" + (i / 100.0));
	}

	angleChoice = new Choice();  // チョイスangleChoiceの生成
	for (int i = 15; i <= 30; i += 5) {  // angleChoiceにアイテムの設定
	    angleChoice.addItem("" + i);
	}

	timesChoice = new Choice();  // チョイスtimesChoiceの生成
	for (int i = 1; i <= 10; i++) {  // timesChoiceにアイテムの設定
	    timesChoice.addItem("" + i);
	}

	add(drawButton);	  // drawButtonをアプレットに追加
	add(scaleChoice);         // scaleChoiceをアプレットに追加
	add(new Label("scale"));  // ラベルscaleをアプレットに追加
	add(angleChoice);	  // angleChoiceをアプレットに追加
	add(new Label("angle"));  // ラベルangleをアプレットに追加
	add(timesChoice);         // timesChoiceをアプレットに追加
	add(new Label("times"));  // ラベルtimesをアプレットに追加

	drawButton.addActionListener(new ActionAdp());
		// drawButtonにActionAdp()をアクションリスナーとして登録
	scaleChoice.addItemListener(new ItemAdp());
		// scaleChoiceにItemAdpをアイテムリスナーとして登録
	angleChoice.addItemListener(new ItemAdp());
		// angleChoiceにItemAdpをアイテムリスナーとして登録
	timesChoice.addItemListener(new ItemAdp());
		// timesChoiceにItemAdpをアイテムリスナーとして登録

	scaleChoice.select(0);  // scaleChoiceの選択初期値を0番目とする
	angleChoice.select(1);  // angleChoiceの選択初期値を0番目とする
	timesChoice.select(2);  // timesChoiceの選択初期値を1番目とする

    }

    /* アクションリスナーの実装クラス */
    class ActionAdp implements ActionListener {
	public void actionPerformed(ActionEvent e) {
	    if (e.getSource() == drawButton) {  // drawButtonの場合
		repaint();
	    }
	}
    }

    /* アイテムリスナーの実装クラス */
    class ItemAdp implements ItemListener {
	public void itemStateChanged(ItemEvent e) {
	    Object source = e.getSource();
	    if (source == scaleChoice) {         // scaleChoiceの場合
		scale = 0.7 - scaleChoice.getSelectedIndex() * 0.05;
	    } else if (source == angleChoice) {  // angleChoiceの場合
		angle = 30 + angleChoice.getSelectedIndex() * 5;
	    } else if (source == timesChoice) {  // timesChoiceの場合
		times = timesChoice.getSelectedIndex() + 2;
	    }
	}
    }

    /* 描画メソッド */
    public void paint(Graphics g) {
	double x = width / 2;	// 樹木曲線の基点のx座標
	double y = 0;		// 樹木曲線の基点のy座標
	g.setColor(Color.white);
	g.fillRect(0, 30, width, height - 30);
	tree(g, times, x, y, length, initAngle);  // 樹木曲線の描画メソッド呼び出し
    }

    /* ***************************** */
    /* 樹木曲線の描画メソッド tree() */
    /* 引数の説明                    */
    /* g: Graphicsオブジェクト       */
    /* n: 繰り返し数                 */
    /* x0: 書き出し点のx座標         */
    /* y0: 書き出し点のy座標         */
    /* len: 枝の長さ                 */
    /* ang: 角度                     */
    /* ***************************** */

    public void tree(Graphics g, int n, double x0, double y0,
			double len, double ang) {
	if (n <= 0) { return; }
	double x = len * Math.cos(radian * ang) + x0;
	double y = len * Math.sin(radian * ang) + y0;
	if (n < 2) {
		//葉
		g.setColor(new Color(2, 201, 17));
		g.drawLine((int) x0, (int) (height - y0), (int) x, (int) (height - y));
	  }
	 else{
		//幹・枝
				g.setColor(new Color(130, 92, 31));
			g.drawLine((int) x0, (int) (height - y0), (int) x, (int) (height - y));
      }
	 int angleR = (int) (Math.random() * angle);// 角度をランダムに決定する
	 tree(g, n - 1, x, y, len * scale*1.2, ang+angleR/2);
	 // 枝1
	 angleR = (int) (Math.random() * angle);// 角度をランダムに決定する
	 tree(g, n - 1, x, y, len * scale*1.2, ang-angleR/2);
	 // 枝2
	 angleR = (int) (Math.random() * angle);// 角度をランダムに決定する
	 tree(g, n - 1, x, y, len * scale, ang+angleR*2);
	 // 枝3
	 angleR = (int) (Math.random() * angle);// 角度をランダムに決定する
	 tree(g, n - 1, x, y, len * scale, ang-angleR*2);
	 // 枝4
    }

}

