import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class sinyoujyu extends Applet {

    Button drawButton;
    Choice angleChoice, scaleChoice, timesChoice;
    int times = 3;		// 繰り返し回数の初期値
    int angle = 30;		// 枝の角度の回数
    double scale = 0.7;		// 枝の長さの比率初期値
    double length = 70.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 = 30; i <= 90; i += 10) {  // angleChoiceにアイテムの設定
	    angleChoice.addItem("" + i);
	}

	timesChoice = new Choice();  // チョイスtimesChoiceの生成
	for (int i = 1; i <= 15; 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(0);  // angleChoiceの選択初期値を0番目とする
	timesChoice.select(1);  // 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() * 10;
	    } 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);
	//g.setColor(Color.black);
	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;
		// 枝の終点のx座標を計算
	double y = len * Math.sin(radian * ang) + y0;
		// 枝の終点のy座標を計算
	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));
    }
	// 始点終点が与えられた枝の描画
	tree(g, n - 1, x, y, len * scale/2, ang - angle);
	// 右側の枝の描画 (再帰呼び出し)
     tree(g, n - 1, x, y, len * scale*1.4, ang );
	// 真ん中の枝の描画 (再帰呼び出し)
	tree(g, n - 1, x, y, len * scale/2, ang + angle);
	// 左側の枝の描画 (再帰呼び出し)
   }
}

