import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class m0104304_03 extends Applet
{
	Panel pnl_1;
	Label lbl01 = new Label("鼻の大きさ（浮動少数）");
	Label lbl02 = new Label("鼻の巻き回数（１〜５０まで,整数）");
	Label lbl03 = new Label("鼻の伸ばし具合（０以上、整数、小さいほど伸びる）");
	Label lbl04 = new Label("鼻の回転（浮動少数）");

	TextField tf_b01 = new TextField("10.0");//鼻の大きさ
	TextField tf_b02 = new TextField("50");//鼻の巻きの回数
	TextField tf_b03 = new TextField("20");//鼻の伸ばし具合
	TextField tf_b04 = new TextField("100.0");//鼻の回転数

	// Drawボタン
	Button botonDraw = new Button("Draw");

	double len = Double.parseDouble(tf_b01.getText());
	int n = Integer.parseInt(tf_b02.getText());
	int angle = Integer.parseInt(tf_b03.getText());
	double ang = Double.parseDouble(tf_b04.getText());


    static int WIDTH, HEIGHT;        // 画面サイズ
    Point point[][];                 // 制御点
    int point_num = 0;               // 制御点の番号
    int captured_point = -1;         // つかんでいる制御点の番号
                                     //（-1のときつかんでいない）
    boolean capture_mode_FLG;        // 線を制御できるかを表すフラグ
    double scale=0.9;
//	int n=50;
//	int angle=20;
	int w,h;
//	double ang=200.0;
//	double len=30.0;

    static final int point_data[][][] =    // 点情報
        {
		/*	{ {160,168}, {165,205}, {110,335}, },//胴体
			{ {160,168}, {155,135}, {135,165}, },
			{ {135,165}, {115,205}, {110,335}, },
*/
			{ {185,465}, {145,395}, {70,375}, },//羽
			{ {70,375}, {60,385}, {55,405}, },
			{ {55,405}, {60,435}, {55,450}, },
			{ {205,472}, {165,395}, {120,365}, },

			{ {120,365}, {105,360}, {105,390}, },


			{ {185,465}, {180,462}, {175,470}, },
			{ {185,465}, {205,470}, {225,482}, },//顔とはね
			{ {225,482}, {230,486}, {245,502}, },

			{ {245,502}, {240,507}, {225,502}, },//口
			{ {225,502}, {220,510}, {215,509}, },
			{ {215,509}, {190,534}, {175,524}, },
			{ {175,524}, {165,544}, {85,564}, },
			{ {85,564}, {70,560}, {55,545}, },
			{ {55,545}, {45,524}, {48,514}, },
			{ {48,514}, {45,504}, {40,494}, },
			{ {40,494}, {45,484}, {50,479}, },
			{ {50,479}, {40,469}, {40,465}, },
			{ {40,465}, {45,440}, {105,450}, },
			{ {105,450}, {115,440}, {175,470}, },
			{ {175,470}, {165,475}, {155,490}, },
			{ {155,490}, {165,505}, {175,524}, },

			/*{ {155,490}, {135,505}, {58,514}, },//模様
			{ {155,490}, {135,505}, {90,554}, },
			{ {155,490}, {115,475}, {70,545}, },
			{ {155,490}, {115,475}, {60,479}, },
			*/
			{ {85,564}, {80,575}, {90,554}, },//模様
			{ {90,554}, {80,535}, {70,545}, },
			{ {70,545}, {80,525}, {58,514}, },
			{ {58,514}, {80,505}, {60,479}, },
			{ {60,479}, {80,475}, {75,447}, },
			{ {70,447}, {90,425}, {85,379}, },

			{ {225,482}, {255,470}, {305,482}, },//触覚
			{ {225,482}, {255,460}, {295,472}, },

			//{ {215,509}, {190,534}, {225,544}, },//足
			//{ {215,509}, {190,534}, {225,554}, },
			{ {195,524}, {220,514}, {235,524}, },
			{ {235,524}, {238,544}, {255,574}, },
			{ {215,515}, {230,514}, {245,524}, },
			{ {245,524}, {250,544}, {255,564}, },
			{ {185,528}, {185,554}, {195,570}, },
			{ {185,528}, {165,544}, {175,564}, },

            { {630,318}, {655,255}, {695,240}, }, //hana
            { {645,335}, {645,260}, {695,240}, },
            { {695,240}, {715,230}, {700,255}, },
            { {645,320}, {680,260}, {720,260}, },
            { {720,260}, {705,310}, {680,325}, },
            { {710,290}, {730,270}, {760,260}, },
            { {760,260}, {760,280}, {740,310}, },
            { {680,360}, {735,305}, {785,285}, },
            { {760,325}, {765,305}, {785,285}, },
            { {760,325}, {745,355}, {715,370}, },
            { {765,285}, {800,275}, {785,285}, },
            { {745,235}, {710,235}, {685,270}, },
            { {745,235}, {735,240}, {715,260}, },
            { {745,235}, {750,235}, {740,250}, },
            { {755,245}, {730,250}, {720,260}, },
            { {755,245}, {750,260}, {740,270}, },
            { {755,245}, {755,255}, {750,265}, },
            { {775,245}, {760,250}, {755,255}, },
            { {775,245}, {775,280}, {760,295}, },
            };

    Label tf;

    Graphics offg, backg;
    Image    offi, backi;

    public void initialize()                   // 制御点の設定
    {
        int i;
        point = new Point[point_data.length][];

        for(i = 0; i < point.length; i++)
        {
            point[i] = new Point[point_data[i].length];
            for(int j = 0; j < point_data[i].length; j++)
                point[i][j] = new Point(point_data[i][j][0],
                                        point_data[i][j][1]);
        }
    }

    public void init()
    {
        Dimension d = getSize();
        WIDTH = 800; HEIGHT = 800;
        setBackground(Color.white);
       		setLayout(new BorderLayout());
				add("North", pnl_1 = new Panel());
				pnl_1.setLayout(new GridLayout(5, 5));

				pnl_1.setBackground(Color.white);

				pnl_1.add(lbl01);
				pnl_1.add(tf_b01);
				pnl_1.add(lbl02);
				pnl_1.add(tf_b02);
				pnl_1.add(lbl03);
				pnl_1.add(tf_b03);
				pnl_1.add(lbl04);



				pnl_1.add(tf_b04);
				pnl_1.add(botonDraw);

				botonDraw.addActionListener(new java.awt.event.ActionListener() {
					public void actionPerformed(ActionEvent e) {

						double len = Double.parseDouble(tf_b01.getText());
						int n = Integer.parseInt(tf_b02.getText());
						int angle = Integer.parseInt(tf_b03.getText());
						double ang = Double.parseDouble(tf_b04.getText());

						do_continuar(len, n, angle, ang);
					}
		});


        initialize();

        offi = createImage(WIDTH, HEIGHT);
        offg = offi.getGraphics();
        backi = createImage(WIDTH, HEIGHT);
        backg = backi.getGraphics();
        setBackImage(backg);


     }

    public void setBackImage(Graphics g)    // 背景の用意
    {
        g.setColor(Color.white);
        g.fillRect(0, 0, WIDTH, HEIGHT);
        g.setColor(Color.black);
        g.drawRect(0, 0, WIDTH-1, HEIGHT-1);  // 枠描画
    }

    public int kaijyo(int num)            // 階乗を計算
    {
        int total = 1;

        if(num == 0) return 1;

        for(; num > 1; num--)
            total *= num;
        return total;
    }

    public void BezierCurve(Graphics g, Color color, Point point[])  // 曲線描画
    {
        int i, j;
        double x1, x2, y1, y2;
        double bernstein[] = new double[point.length];
        x1 = point[0].x;
        y1 = point[0].y;

        g.setColor(color);

        for(double t = 0; t <= 1; t += 0.01)
        {
            for(i = 0; i < point.length; i++)        // bernstein関数を計算
            {
                bernstein[i] = (double)kaijyo(point.length-1)
                            / (kaijyo(i)*kaijyo(point.length-1-i));

                for(j = 1; j <= i; j++) bernstein[i] *= t;
                for(j = 1; j <= point.length-1-i; j++) bernstein[i] *= (1-t);
            }

            x2 = y2 = 0;
            for(i = 0; i < point.length; i++)
            {
                x2 += point[i].x * bernstein[i];
                y2 += point[i].y * bernstein[i];
            }

            g.drawLine((int)x1, (int)y1, (int)x2, (int)y2);
            g.fillOval(210,480,8,8);
            g.drawString("Flower", 620,370);
            g.drawString("Butterfly", 220,370);
            x1 = x2;
            y1 = y2;
        }
    }

    public void paint(Graphics g)
    {
        requestFocus();
        offg.drawImage(backi, 0, 0, this);  // 背景の描画

        if(capture_mode_FLG)           // 制御点の描画
        {
            offg.setColor(Color.red);
            for(int i = 0; i < point[point_num].length; i++)
            {
                offg.fillRect(point[point_num][i].x-3,
                              point[point_num][i].y-3, 7, 7);
                offg.drawString(Integer.toString(i+1),
                              point[point_num][i].x-3,
                              point[point_num][i].y-6);
            }
        }

        for(int i = 0; i < point.length; i++)     // 曲線描画
        {
            if(capture_mode_FLG && point_num == i)
                BezierCurve(offg, Color.blue, point[i]);
            else BezierCurve(offg, Color.black, point[i]);
        }

        g.drawImage(offi, 0, 0, this);
          w=800;
		  h=700;
		  double x0, y0;
		  x0=w/3;
		  y0=h/2-152;

		  int[]x={0,w,(int)(w-1.0/5.0*w),(int)(w-4.0/5.0*w)};
		  int[]y={w-20,h-20,(int)(h-1.0/5.0*h),(int)(h-1.0/5.0*h)};

		  g.setColor(new Color(145,42,42));
		  rtree(g,n,x0,y0,len/2,ang);
		  g.setColor(new Color(145,42,42));
		  g.drawLine(240,503,w/3,h/2+152);
    }
	public void rtree(Graphics g,int nn,double x0,double y0,double len,double ang){
	  if(nn<=0){
	    return;}
	    double x,y;
	    final double RAD=Math.PI/180.0;

	    x=len*Math.sin(RAD*ang)+x0;
	    y=len*Math.cos(RAD*ang)+y0;
		g.setColor(new Color (250-nn*3,0+nn*5,0));
	    g.drawLine((int)x0,(int)(h-y0),(int)x,(int)(h-y));

	    rtree(g,nn-1,x,y,len*scale,ang-angle);
	}
	void do_continuar(double c, int d, int f,double e) {

			len = c;
			n = d;
			ang = e;
			angle = f;
			repaint();

	}
    public void update(Graphics g)
    {
        paint(g);
    }
}