
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
//import java.util.*;

import javax.swing.*;

/*
<applet code="Bezier.class" width="620" height="500">
</applet>
*/

public class thunder2 extends Applet implements Runnable{
	////////////////////設定//////////////////////////////
	private static final int IMAGE_WIDTH = 680, //キャンバスのサイズ
								IMAGE_HEIGHT = 800,
								BOXW = 120; //コンテナの幅
	private static final int MAX_DOT = 172; //最大ベジェ曲線次元数 173以上でオーバーフロー
	private static final boolean MODIFY_DRAGGING_VANISH = true;//編集時、制御点移動中には制御点を不可視にする。
	/////////////////////////////////////////////////////
	private boolean PANIC = false;
	private int point_length = 0;
	private int point_num = 0; // 制御点の番号
	private int captured_point = -1; // つかんでいる制御点の番号
	private int artflag = 0; //曲線描写時のフラグ
	private static int mode = 0; //モード
	private static int WIDTH, HEIGHT; // 画面サイズ
	private static final int MODE_MODIFY = 0,
								MODE_ART = 1,
								MODE_MOVE = 2,
								MODE_DRAW = 3;
	private final String ST_MODIFY = "編集",
						   ST_ART  = "Bz曲線",
						   ST_MOVE = "移動",
						   ST_DRAW = "点描画（餌）",
						   ST_CLEAR = "消去",
						   ST_ALLCLEAR = "全消去",
						   ST_RANDAM = "更新";
	private Point point[][]; // 制御点
	private Point tmpP[]; //曲線描写時の一時データ
	private Point mtmpP[]; //曲線移動の一時マウス座標データ
	private boolean DRAGGING = false;
	private boolean heikyokusen = false;
	private Thread thread = new Thread(this);
	public DrawColorBar dcb = new DrawColorBar(this);
	public Label tf;
	public Scrollbar scr;
	public Graphics offg, backg, offg2,colorg; //曲線用の仮想画像//背景//書換え必要があるものの仮想画像
	public Image offi, backi, offi2, colori;
	public Button modify, arts, move, draw,clear,allclear,panic,randamB;
	public TextField randamT;
	public Label printmode;
	public Checkbox checkbox;
	public Box bx ; //たて
	public Box bx2 ; //よこ
	public Label randamL ; //ランダム
	public int EsaX = 0, EsaY = 0, rand=0;

	private static final int point_data[][][] = // 点情報
		{{{1000, 1000},},
			{{432,2},{443,21},{406,49},{429,55},},
			{{429,54},{406,61},{392,77},{436,74},{439,88},},
			{{439,88},{462,116},{449,100},{428,108},{436,115},},
			{{436,115},{412,120},{468,120},{421,136},{415,141},},
			{{415,141},{438,150},{374,139},{423,159},{435,165},},
			{{435,165},{408,175},{472,166},{429,185},{415,192},},
			{{415,190},{436,200},{402,193},{437,196},{417,205},},
			{{417,205},{412,211},{440,204},{419,218},{433,222},},
			{{433,222},{459,225},{406,226},{424,235},{416,237},},
			{{416,237},{396,237},{437,253},{364,244},{426,257},},
			{{422,255},{426,266},{453,259},{435,268},{453,275},},
			{{451,275},{438,277},{420,289},{412,276},{408,291},},
			{{408,291},{393,290},{394,300},{409,300},{390,305},},
			{{390,305},{375,308},{420,311},{390,316},{406,326},},
			{{406,326},{429,336},{363,338},{422,337},{400,362},},
			{{400,361},{374,366},{455,370},{407,377},{413,389},},
			{{413,389},{393,398},{431,391},{402,406},{400,419},},
			{{400,419},{404,431},{379,423},{399,431},{381,443},},
			{{381,443},{376,454},{382,462},{375,471},{375,479},},
			{{375,479},{356,493},{375,503},{344,497},{352,521},},
			{{351,520},{388,532},{339,542},{366,546},{364,554},},
			{{364,553},{392,566},{351,549},{380,578},{359,601},},

			//山
			{{697,539},{562,579},{398,516},{367,616},{115,730},},
			{{316,623},{277,617},{177,582},{108,609},{4,632},},

			//山の森
			{{0,614},{17,586},{57,576},{87,596},},
			{{80,594},{102,520},{134,501},{174,593},},
			{{171,586},{203,557},{258,560},{277,615},},
			{{699,526},{666,509},{634,525},{627,541},},
			{{631,542},{610,515},{573,522},{564,548},},
			{{563,547},{543,524},{512,523},{503,553},},
			{{505,553},{487,534},{457,537},{450,559},},
			{{449,559},{433,553},{413,562},{406,578},},

			//木の葉
			{{32,116},{44,136},{71,138},{79,116},},
			{{75,121},{90,123},{93,99},{107,81},},
			{{103,86},{115,89},{137,88},{149,56},},
			{{143,61},{157,66},{174,43},{170,23},},
			{{171,30},{193,25},{191,6},{183,2},},
			{{1,121},{13,128},{25,129},{34,122},},
			{{177,3},{179,13},{175,19},{165,19},},
			{{160,35},{160,48},{154,52},{145,50},},
			{{137,66},{130,78},{120,78},{109,79},},
			{{96,82},{95,96},{88,105},{80,112},},
			{{70,119},{51,127},{40,119},{39,110},},
			{{7,114},{14,120},{19,120},{28,113},},
			{{131,26},{135,47},{124,60},{112,58},},
			{{59,34},{41,51},{61,71},{76,63},},
			{{8,62},{5,88},{15,99},{31,97},},

			{{1,249},{15,249},{19,269},{15,279},},
			{{15,271},{25,260},{45,260},{52,282},},
			{{50,272},{78,286},{66,305},{52,316},},
			{{63,304},{68,317},{60,334},{37,332},},
			{{49,332},{47,345},{33,347},{21,332},},
			{{23,336},{14,344},{3,341},{0,331},},
			{{4,259},{7,264},{7,270},{4,277},},
			{{23,277},{30,268},{34,269},{37,273},},
			{{60,287},{60,295},{56,301},{53,306},},
			{{3,332},{13,333},{14,332},{19,331},},

			{{1,365},{12,363},{27,372},{27,383},},
			{{25,377},{47,368},{76,383},{81,406},},
			{{71,404},{92,405},{112,428},{109,447},},
			{{110,436},{132,457},{100,480},{76,482},},
			{{85,481},{64,502},{44,488},{23,474},},
			{{41,485},{19,501},{9,491},{0,485},},
			{{6,374},{19,377},{19,384},{19,392},},
			{{35,382},{44,382},{64,388},{66,399},},
			{{79,414},{89,418},{92,425},{99,441},},
			{{82,465},{98,465},{106,458},{103,449},},
			{{5,483},{17,488},{26,484},{27,480},},
			{{58,449},{35,469},{15,453},{10,436},},


			//太陽
			{{241,501},{239,525},{187,526},{197,488},{208,470},{241,468},{242,503},},

			//枝
			{{1,530},{81,500},{6,492},{65,456},{103,472},},
			{{36,508},{76,477},{31,470},{15,430},{76,418},},
			{{1,168},{27,147},{62,146},{63,172},{86,140},},
			{{86,141},{96,128},{123,153},{90,112},{138,108},},
			{{20,156},{9,85},{44,115},{48,98},{53,86},},
			{{51,87},{69,64},{81,99},{84,52},{133,21},},
			{{2,106},{25,97},{56,84},{23,33},{78,13},},

			//雷中
			{{429,55},{438,51},{466,80},{496,76},{528,71},},
			{{518,71},{538,86},{570,90},{625,79},{641,78},},
			{{409,66},{390,87},{405,109},{375,106},{368,121},},
			{{368,121},{383,154},{306,103},{369,159},{326,165},},
			{{445,93},{470,112},{491,102},{494,122},{529,119},},
			{{527,119},{533,154},{557,113},{581,153},{626,159},},
			{{436,114},{463,121},{444,141},{462,137},{468,141},},
			{{468,141},{463,175},{551,122},{505,193},{561,184},},
			{{409,147},{394,150},{392,166},{377,162},{374,177},},
			{{374,178},{353,171},{364,195},{336,181},{338,204},},
			{{337,203},{312,222},{290,194},{303,237},{271,233},},
			{{429,169},{421,186},{474,197},{395,213},{378,245},},
			{{422,194},{458,181},{426,237},{488,219},{481,253},},
			{{418,256},{420,267},{401,268},{397,291},{381,298},},
			{{382,297},{359,302},{382,321},{347,308},{345,333},},
			{{436,262},{510,265},{505,309},{543,290},{580,299},},
			{{398,299},{402,325},{450,311},{432,362},{471,376},},
			{{438,87},{388,107},{367,77},{339,111},{252,123},},

			//雷小
			{{475,71},{489,97},{510,105},{526,101},},
			{{525,101},{528,115},{559,106},{559,121},},
			{{558,119},{560,134},{611,118},{611,139},},
			{{491,73},{489,96},{496,104},{520,110},},
			{{520,110},{557,111},{606,97},{613,120},},
			{{502,73},{505,92},{545,74},{551,110},},
			{{550,97},{568,115},{590,108},{608,121},},
			{{569,85},{570,113},{584,101},{597,122},},
			{{582,83},{582,115},{623,94},{638,127},},
			{{638,77},{660,63},{674,69},{691,65},},
			{{638,76},{646,88},{673,83},{691,95},},
			{{641,75},{655,73},{665,71},{674,70},},
			{{637,78},{655,79},{667,76},{684,82},},
			{{533,76},{563,80},{591,77},{619,67},},
			{{394,99},{435,166},{411,122},{410,132},},
			{{409,131},{388,149},{413,154},{384,177},},
			{{384,175},{383,200},{318,213},{338,247},},
			{{328,164},{294,174},{281,201},{258,208},},
			{{283,116},{278,121},{284,126},{271,137},},
			{{266,120},{256,129},{239,135},{228,147},},
			{{363,95},{337,83},{314,101},{285,84},},
			{{349,98},{319,121},{337,139},{291,146},},
			{{338,101},{341,138},{314,146},{278,186},},
			{{320,108},{310,122},{296,122},{283,136},},
			{{298,114},{291,120},{275,122},{264,131},},
			{{388,95},{344,139},{415,127},{355,153},},
			{{356,152},{329,173},{364,191},{298,201},},
			{{417,114},{455,135},{423,167},{474,178},},
			{{491,113},{495,135},{522,126},{548,159},},
			{{529,126},{550,127},{569,117},{629,122},},
			{{568,138},{579,150},{583,171},{595,181},},
			{{606,154},{599,162},{596,176},{579,183},},
			{{615,157},{630,149},{652,167},{678,164},},
			{{587,147},{607,147},{616,139},{628,144},},
			{{467,141},{477,146},{503,143},{532,160},},
			{{531,159},{542,167},{557,164},{565,182},},
			{{467,140},{486,159},{489,186},{503,183},},
			{{502,183},{518,180},{520,201},{549,199},},
			{{436,125},{455,149},{457,164},{473,167},},
			{{399,160},{402,182},{385,198},{387,215},},
			{{385,176},{378,198},{403,215},{392,231},},
			{{383,161},{360,164},{338,174},{304,168},},
			{{351,186},{326,186},{306,194},{285,199},},
			{{359,181},{346,189},{345,201},{311,219},},
			{{335,202},{343,212},{352,221},{342,246},},
			{{341,140},{331,152},{318,157},{303,172},},
			{{359,131},{351,137},{354,145},{345,153},},
			{{435,188},{452,214},{508,189},{521,245},},
			{{423,199},{441,220},{505,207},{507,254},},
			{{431,204},{445,220},{501,201},{511,249},},
			{{436,193},{456,235},{484,206},{506,257},},
			{{437,189},{458,219},{481,198},{497,246},},
			{{440,197},{464,216},{499,203},{516,245},},
			{{439,194},{459,207},{490,200},{518,242},},
			{{435,189},{463,211},{503,187},{531,225},},
			{{434,184},{463,208},{497,186},{532,242},},
			{{433,184},{468,234},{502,175},{538,242},},
			{{433,205},{455,232},{434,245},{468,257},},
			{{383,236},{385,251},{366,255},{350,282},},
			{{384,233},{374,231},{362,249},{347,260},},
			{{425,282},{429,291},{420,304},{434,324},},
			{{417,284},{414,293},{419,307},{407,341},},
			{{430,328},{450,344},{470,348},{475,356},},
			{{438,337},{453,352},{461,352},{475,362},},
			{{473,269},{489,283},{499,298},{519,304},},
			{{485,274},{513,293},{535,299},{551,309},},
			{{477,271},{494,296},{523,299},{550,325},},
			{{475,272},{502,303},{534,295},{549,312},},
			{{449,211},{446,238},{481,236},{479,261},},
			{{433,332},{449,364},{483,360},{494,382},},
			{{395,281},{371,288},{348,293},{331,309},},
			{{395,281},{376,299},{365,296},{349,302},},
			{{395,280},{381,299},{344,306},{334,322},},

	};
	////////////////////スレッド用//////////////////////
	public void run() {
		while(thread == Thread.currentThread()){
			long time=0L;
			try{
				Thread.sleep(30);
			} catch(InterruptedException e){
				System.out.println(e);
			}

			if(PANIC){
				if(v == null){
					v = new Point[1024][];
					for(int j=0;v!=null&&j<v.length;j++){
						v[j] = new Point[MAX_DOT];
						for(int i=0;v[j]!=null&&i<v[j].length;i++){
							v[j][i] = new Point((int)(Math.random()*30)-15,(int)(Math.random()*30)-15);
						}
					}
				}
				//if(point_num!=0) gMove(point[point_num],point_num);
				for(int i=1;point[i]!=null;i++)gMove(point[i],i);
				repaint();
			}
		}
	}
	Point v[][];

	public void gMove(Point p[],int k){
		double ex=0.99,ey=0.8; //跳ね返り係数
		//配列宣言と生成
		int[] amebaX = new int[p.length];
		int[] amebaY = new int[p.length];

		//if(k==1)System.out.println(v[k][0].y);
		for(int i=0;i<p.length && p[i]!=null;i++){
			if(checkStop(v[k][i].y)){
				v[k][i].y=0;
				continue;
			}

			if(EsaX != 0){
				amebaX[i] = EsaX - p[i].x;
				amebaY[i] = EsaY - p[i].y;
			}else{
				amebaX[i] = 0;
				amebaY[i] = 0;
			}

			if((int)(Math.round (Math.random () * 5) + 1) %2 == 0){
				p[i].x += (int)((Math.random()*2) + (amebaX[i]/70));
			}else{
				p[i].x -= (int)((Math.random()*2) + (amebaX[i]/70));
			}
			if((int)(Math.round (Math.random () * 5) + 1) %2 == 0){
				p[i].y += (int)((Math.random()*2) + (amebaY[i]/70));
			}else{
				p[i].y -= (int)((Math.random()*2) + (amebaY[i]/70));
			}
/*			if(p[i].x<0){
				p[i].x=0;
				v[k][i].x*=-1;
			}
			if(p[i].y<0){
				p[i].y=0;
				v[k][i].x*=ex;
				v[k][i].y*=-ey;
			}
			if(IMAGE_WIDTH<p[i].x){
				p[i].x=IMAGE_WIDTH;
				v[k][i].x*=-1;
			}
			if(IMAGE_HEIGHT<p[i].y){
				p[i].y=IMAGE_HEIGHT;
				v[k][i].x*=ex;
				v[k][i].y*=-ey;
			}

			v[k][i].y++;//加速度１*/
		}
	}
	public boolean checkStop(int y){
		return (-2<=y&&y<=0&&y==IMAGE_HEIGHT);
	}
	public void start() {
		super.start();
		if(thread == null){
			thread = new Thread(this);
			thread.start();
		}
	}
	public void stop() {
		super.stop();
		thread = null;
	}

	public void randamZ(Point p[],int k,int randamP){
		for(int i=0;i<p.length && p[i]!=null;i++){
			if((int)(Math.round (Math.random() * 5) + 1) %2 == 0){
				p[i].x += (int)(Math.random()*(randamP+1));
			}else{
				p[i].x -= (int)(Math.random()*(randamP+1));
			}
			if((int)(Math.round (Math.random() * 5) + 1) %2 == 0){
				p[i].y += (int)(Math.random()*(randamP+1));
			}else{
				p[i].y -= (int)(Math.random()*(randamP+1));
			}
		}
	}

	//////////////////////////////////////////

	public void initialize() // 制御点の設定
	{
		int i;
		point = new Point[1024][];
		point_length = point_data.length-1;
		v=null;
		for (i = 0; i < point_data.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 addPoint(Point p[]) {
		point[point_length+1] = new Point[p.length];
		for (int i = 0; i < p.length; i++)
			point[point_length+1][i] = p[i];
		point_length++;
	}
	public void addhPoint(Point p[]) {
		point[point_length+1] = new Point[p.length + 1];
		for (int i = 0; i < p.length; i++)
			point[point_length+1][i] = p[i];
		point[point_length+1][p.length] = p[0];
		point_length++;
	}

	public void init() {
		resize(IMAGE_WIDTH + BOXW, IMAGE_HEIGHT);
		Dimension d = getSize();
		WIDTH = d.width;
		HEIGHT = d.height;
		initialize();
		bx = Box.createVerticalBox();
		bx2= Box.createHorizontalBox();
		modify = new Button(ST_MODIFY);
		arts = new Button(ST_ART);
		checkbox = new Checkbox("閉曲線");
		move = new Button(ST_MOVE);
		draw = new Button(ST_DRAW);
		clear = new Button(ST_CLEAR);
		allclear = new Button(ST_ALLCLEAR);
		panic = new Button("アメーバ変形");
		printmode = new Label("MODE", Label.CENTER);
		printmode.setBackground(Color.white);
		scr = new Scrollbar(Scrollbar.VERTICAL, 0, 30, 0, point_length + 30);
		scr.setBackground(Color.white);
		scr.setSize(200, 100);
		tf = new Label(Integer.toString(point_num), Label.RIGHT);
		tf.setBackground(Color.black);
		tf.setForeground(Color.white);
		randamT = new TextField ("0");
		randamL = new Label("ランダム値", Label.CENTER);
		randamB = new Button(ST_RANDAM);
		thread.start();
		/////////////////////////////////
		//コンテナ結合
		/////////////////////////////////
		add(bx2);
		bx2.add(bx);
		bx2.add(Box.createHorizontalStrut(2));
		bx2.add(scr);
		bx.add(printmode);
		bx.add(Box.createVerticalStrut(5));
		bx.add(modify);
		bx.add(move);
		bx.add(arts);
		bx.add(checkbox);
		bx.add(Box.createVerticalStrut(10));
		bx.add(draw);
		bx.add(dcb.getCpnt());
		bx.add(Box.createVerticalStrut(80));
		bx.add(randamL);
		bx.add(randamT);
		bx.add(randamB);
		bx.add(Box.createVerticalStrut(70));
		bx.add(tf);
		bx.add(Box.createVerticalStrut(5));
		bx.add(clear);
		bx.add(allclear);
		bx.add(panic);
		setLayout(new FlowLayout(FlowLayout.TRAILING));
		changeMode(MODE_ART);
		checkbox.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent arg0) {
				heikyokusen = checkbox.getState();
			}
		});
		scr.addAdjustmentListener(new AdjustmentListener() {
			public void adjustmentValueChanged(AdjustmentEvent e) {
				point_num = e.getValue();
				tf.setText(Integer.toString(point_num));
				repaint();
			}
		});
		modify.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				changeMode(MODE_MODIFY);
			}
		});
		arts.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				changeMode(MODE_ART);
			}
		});
		move.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				changeMode(MODE_MOVE);
			}
		});
		draw.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				changeMode(MODE_DRAW);
			}
		});
		clear.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				clear();
			}
		});
		allclear.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				allClear();
			}

		});
		panic.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				PANIC = !PANIC;
				if(PANIC){
					printmode.setBackground(Color.red);
					printmode.setText("アメーバ！");
					//printmode.setBackground(Color.white);
				}else{
					changeMode(mode);
				}
			}
		});
		randamB.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				rand = Integer.parseInt(randamT.getText());
				for(int i=1;point[i]!=null;i++){
					randamZ(point[i], i, rand);
				}
				repaint();
			}
		});


		class Mouse implements MouseListener, MouseMotionListener {
			int mX, mY;

			public void mousePressed(MouseEvent me) // 制御点をつかむ
			{
				int i = 0, mx = me.getX(), my = me.getY();
				mX = mx;
				mY = my;
				captured_point = -1;
				dragon();
				if (mx < 0 || IMAGE_WIDTH < mx || my < 0 ||IMAGE_HEIGHT < my)
					return;
				if (modeIs(MODE_MODIFY)) {
					for (i = 0; i < point[point_num].length; i++) {
						if (point[point_num][i].x - 3 <= mx
							&& point[point_num][i].x + 3 >= mx
							&& point[point_num][i].y - 3 <= my
							&& point[point_num][i].y + 3 >= my)
							break;
					}
					if (i < point[point_num].length)
						captured_point = i;
				} else if (modeIs(MODE_MOVE)) {
					for (i = 0; i <= point_length; i++) {
						if (point[i][point[i].length / 2].x - 3 <= mx
							&& point[i][point[i].length / 2].x + 3 >= mx
							&& point[i][point[i].length / 2].y - 3 <= my
							&& point[i][point[i].length / 2].y + 3 >= my) {
							mtmpP = new Point[point[i].length];
							for (int j = 0; j < point[i].length; j++)
								mtmpP[j] = new Point(point[i][j]);
							break;
						}
					}
					if (i <= point_length)
						captured_point = i;
				} else if (modeIs(MODE_ART)) {
					if (mx > IMAGE_WIDTH || my > IMAGE_HEIGHT)
						return;
					if (artflag > 0)
						for (i = 0; tmpP[i] != null; i++) {
							if (tmpP[i].x - 3 <= mx
								&& tmpP[i].x + 3 >= mx
								&& tmpP[i].y - 3 <= my
								&& tmpP[i].y + 3 >= my) {
								if (i < tmpP.length)
									captured_point = i;
								//System.out.println(captured_point);
								repaint();
								return;
							}
						}
					if (artflag == 0) {
						tmpP = new Point[MAX_DOT];
					}
					//System.out.println(artflag);
					tmpP[artflag] = new Point(mx, my);
					captured_point = artflag++;
					if (artflag >= MAX_DOT)
						artflag = 0;
				} else if (modeIs(MODE_DRAW)){
				colorg.setColor(dcb.getColor());
				drawCircle(mx,my,dcb.getW(),colorg);
				EsaX = mx;
				EsaY = my;
			}
				repaint();
			}
			public void mouseClicked(MouseEvent arg0) {
				if (modeIs(MODE_ART));
			}
			public void mouseEntered(MouseEvent arg0) {
				;
			}
			public void mouseExited(MouseEvent arg0) {
				;
			}
			public void mouseMoved(MouseEvent arg0) {
				;
			}
			public void mouseReleased(MouseEvent me) {
				captured_point = -1;
				dragoff();
				repaint();
			}
			public void mouseDragged(MouseEvent me) {
				int x = me.getX(), y = me.getY();
				if (x < 0)
					x = 0;
				if (IMAGE_WIDTH < x)
					x = IMAGE_WIDTH - 1;
				if (y < 0)
					y = 0;
				if (IMAGE_HEIGHT < y)
					y = IMAGE_HEIGHT - 1;
				if (modeIs(MODE_MODIFY)) {
					if (captured_point == -1)
						return;
					point[point_num][captured_point].setLocation(x, y);
				} else if (modeIs(MODE_MOVE)) {
					if (captured_point == -1){
						repaint();
						return;
					}
					for (int i = 0; i < point[captured_point].length; i++) {
						point[captured_point][i].setLocation(
							x - mX + mtmpP[i].x,
							y - mY + mtmpP[i].y);
					}
				} else if (modeIs(MODE_ART)) {
					if (captured_point != -1)
						for (int i = 0; i < tmpP.length; i++) {
							tmpP[captured_point].setLocation(x, y);
						}
				} else if (modeIs(MODE_DRAW)){
					colorg.setColor(dcb.getColor());
					drawCircle(x,y,dcb.getW(),colorg);
				}
				repaint();
			}
		};
		Mouse ms = new Mouse();
		addMouseListener(ms);
		addMouseMotionListener(ms);
		offi = createImage(WIDTH, HEIGHT);
		offg = offi.getGraphics();
		backi = createImage(WIDTH, HEIGHT);
		backg = backi.getGraphics();
		offi2 = createImage(WIDTH, HEIGHT);
		offg2 = offi2.getGraphics();
		colori = createImage(IMAGE_WIDTH-2, IMAGE_HEIGHT-3);
		colorg = colori.getGraphics();
		colorg.setColor(Color.white);
		colorg.fillRect(0,0,IMAGE_WIDTH-2, IMAGE_HEIGHT-3);
		setBackImage(backg);
		//puts(point_length);
		addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent ke) {
				int c = ke.getKeyCode();

				if (modeIs(MODE_ART)) {
					if (c == KeyEvent.VK_ENTER) {
						if (artflag <= 1)
							return;
						if (heikyokusen)
							addhPoint(getscfp(tmpP));
						else
							addPoint(getscfp(tmpP));
						artflag = 0;
						scr.setMaximum(point_length + 30);
						repaint();
					}
					else if (c == KeyEvent.VK_BACK_SPACE) {
						artflag = 0;
						repaint();
					}
				}

				if(c== 'R'){
					initialize();
					repaint();
				}

				if (c == 'P') {
					System.out.print("{");
					for (int i = 0; i < point[point_num].length; i++)
						System.out.print(
							"{"
								+ point[point_num][i].x
								+ ", "
								+ point[point_num][i].y
								+ "},");
					System.out.println("},");
				}
				if (c == 'N') {
					for (int i = 0; i <= point_length; i++) {
						System.out.print("{");
						for (int j = 0; j < point[i].length; j++)
							System.out.print(
								"{"
									+ point[i][j].x
									+ ", "
									+ point[i][j].y
									+ "},");
						System.out.println("},");
					}
				} else if (c == 'B') {
					repaint();
				}
			}
		});
	}
	public void drawCircle(int x,int y,int r,Graphics g){
		g.fillOval(x-r/2,y-r/2,r,r);
	}
	public Point[] getscfp(Point p[]) {
		int i = 0;
		while (p[i] != null && i < p.length) {
			i++;
		}
		Point[] point = new Point[i];
		for (i = 0; i < point.length; i++)
			point[i] = new Point(p[i]);
		return point;
	}
	public void setBackImage(Graphics g) // 背景の用意
	{
		g.setColor(Color.white);
		g.fillRect(5, 0, WIDTH, HEIGHT);
		g.setColor(Color.black);
		g.drawRect(5, 1, WIDTH - BOXW - 1, HEIGHT - 2); // 枠描画
		g.setColor(new Color(200, 200, 200));
		g.fillRect(WIDTH - BOXW - 1 + 10, 0, WIDTH - 1, HEIGHT - 1);
		g.setColor(Color.white);
		g.drawLine(
			WIDTH - BOXW - 1 + 10 + 2,
			0,
			WIDTH - BOXW - 1 + 10 + 2,
			HEIGHT - 1);
	}
	public void changeMode(int x) {
		mode = x;
		printmode.setBackground(Color.white);
		if (x == MODE_MODIFY) {
			printmode.setText(ST_MODIFY);
		} else if (x == MODE_ART) {
			printmode.setText(ST_ART);
		} else if (x == MODE_MOVE) {
			printmode.setText(ST_MOVE);
		} else if (x == MODE_DRAW) {
			printmode.setText(ST_DRAW);
		}
		repaint();
	}

	public double mathCombination(int m, int n) {
		double x = 1;
		for (int i = 0; i < n; i++)
			x *= m--;
		while (n > 1) {
			x /= n--;
		}
		return x;
	}
	public void allClear() {
		while(point_length!=0)
			clear();
		/*
		point = new Point[1024][];
		point[0] = new Point[1];
		point[0][0] = new Point(1000,1000);
		point_length = 0;
		scr.setMaximum(point_length + 30);
		puts(point_length);*/
		repaint();
		}
	public void clear(){
		if(point_length!=0)point[point_length] = null;

		if(point_length>0){
			if(point_num == point_length) point_num--;
			point_length--;
			//tf.setText(Integer.toString(point_num));
		}
		scr.setMaximum(point_length + 30);
		//puts(point_length);
		repaint();
	}
	public void puts(int n){
		//System.out.println(n);
	}
	public void BezierCurve(Graphics g, Color color, Point point[]) // 曲線描画
	{
		int i, j;
		double x1, x2=0, y1, y2=0;
		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.005) {
			for (i = 0; i < point.length; i++) // bernstein関数を計算
				{
				bernstein[i] = mathCombination(point.length - 1, 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);
			x1 = x2;
			y1 = y2;
		}
		g.drawLine((int) point[point.length-1].x, point[point.length-1].y, (int) x1, (int) y1);
	}
	public void drawBline(Graphics g, Color color, Point point[]) {
		g.setColor(color);
		for (int i = 0; i < point.length - 1; i++) {
			g.drawLine(point[i].x, point[i].y, point[i + 1].x, point[i + 1].y);
		}
	}
	public void paint(Graphics g) {
		requestFocus();
		if (!DRAGGING || modeIs(MODE_DRAW)){
			backg.drawImage(colori,6,2,this);
			offg.drawImage(backi, 0, 0, this);
			} // 背景の描画

		if (!(modeIs(MODE_MODIFY) && DRAGGING))
			for (int i = 0; i <= point_length; i++) // 曲線描画
				{
				if ((modeIs(MODE_MOVE)) && captured_point == i) {
					//BezierCurve(offg, Color.blue, point[i]);
				} else if (modeIs(MODE_MODIFY) && point_num == i) {
					;
				} else if (modeIs(MODE_MOVE) && i == point_num) {
					BezierCurve(offg, Color.red, point[i]);
					;
				} else
					BezierCurve(offg, Color.black, point[i]);
				//if(i==0)System.out.println("drawed just now.");
			}
		offg2.drawImage(backi, 0, 0, this); // 背景の描画
		offg2.drawImage(offi, 0, 0, this);

		if (modeIs(MODE_ART)) {
			Point[] tmp;
			if (artflag > 0) {
				tmp = getscfp(this.tmpP);
				BezierCurve(offg2, Color.red, getscfp(tmpP));
				for (int i = 0; i < tmp.length; i++) {
					offg2.setColor(Color.gray);
					offg2.fillRect(tmp[i].x - 3, tmp[i].y - 3, 7, 7);
					offg2.setColor(Color.black);
					offg2.drawRect(tmp[i].x - 3, tmp[i].y - 3, 7, 7);
					offg2.drawString(
						Integer.toString(i + 1),
						tmp[i].x - 3,
						tmp[i].y - 6);
				}
				drawBline(offg2, Color.blue, tmp);
			}
		}

		if (modeIs(MODE_MODIFY)) // 制御点の描画
			{
				if(point_length != 0){
					this.drawBline(offg2, Color.blue, point[point_num]);
				if(!DRAGGING && MODIFY_DRAGGING_VANISH)
					for (int i = 0; i < point[point_num].length; i++) {
						offg2.setColor(Color.gray);
						offg2.fillRect(
							point[point_num][i].x - 3,
							point[point_num][i].y - 3,
							7,
							7);
						offg2.setColor(Color.black);
						offg2.drawRect(
							point[point_num][i].x - 3,
							point[point_num][i].y - 3,
							7,
							7);
						offg2.drawString(
							Integer.toString(i + 1),
							point[point_num][i].x - 3,
							point[point_num][i].y - 6);
					}
					}
		}
		if (modeIs(MODE_MOVE) && !capturing()) { //
			offg2.setColor(Color.green);
			for (int i = 0; i <= point_length; i++) {
				if (i != point_num)
					offg2.setColor(Color.gray);
				else
					offg2.setColor(Color.red);
				offg2.fillRect(
					point[i][point[i].length / 2].x - 3,
					point[i][point[i].length / 2].y - 3,
					7,
					7);
				offg2.setColor(Color.black);
				offg2.drawRect(
					point[i][point[i].length / 2].x - 3,
					point[i][point[i].length / 2].y - 3,
					7,
					7);
			}
		}

		if (modeIs(MODE_MODIFY))
			BezierCurve(offg2, Color.red, point[point_num]);
		else if (modeIs(MODE_MOVE) && DRAGGING && capturing())
			BezierCurve(offg2, Color.red, point[captured_point]);
		g.drawImage(offi2, 0, 0, this);
	}
	public boolean capturing() {
		return (captured_point != -1);
	}
	public void update(Graphics g) {
		paint(g);
	}
	public boolean modeIs(int x) {
		return (mode == x);
	}
	public void dragon() {
		DRAGGING = true;
	}
	public void dragoff() {
		DRAGGING = false;
	}
}

class DrawColorBar {
	private int R, G, B, W=10;
	private final Applet app;
	private Scrollbar Rscr, Gscr, Bscr, Wscr;
	private Box box = Box.createHorizontalBox();
	private Box box2 = Box.createVerticalBox();
	private Label printcolor = new Label("",Label.CENTER);
	private Box lbx = Box.createVerticalBox();
	private Listener l = new Listener();
	DrawColorBar(Applet app) {
		R = G = B = 0;
		this.app = app;
		Rscr = new Scrollbar(Scrollbar.VERTICAL, 0, 30, 0, 256 + 30 - 1);
		Gscr = new Scrollbar(Scrollbar.VERTICAL, 0, 30, 0, 256 + 30 - 1);
		Bscr = new Scrollbar(Scrollbar.VERTICAL, 0, 30, 0, 256 + 30 - 1);
		Wscr = new Scrollbar(Scrollbar.VERTICAL);
		Wscr.setMaximum(110);
		setLabelColor();
		box.add(Rscr);
		box.add(Gscr);
		box.add(Bscr);
		box.add(Box.createHorizontalStrut(20));
		box.add(Wscr);
		lbx.add(Box.createVerticalStrut(70));
		box.add(lbx);
		Rscr.addAdjustmentListener(l);
		Gscr.addAdjustmentListener(l);
		Bscr.addAdjustmentListener(l);
		Wscr.addAdjustmentListener(l);
		box2.add(printcolor);
		box2.add(box);
		Rscr.setBackground(getColor());
		Gscr.setBackground(getColor());
		Bscr.setBackground(getColor());
	}
	public void setColor(int R, int G, int B) {
		this.R = R;
		this.G = G;
		this.B = B;
	}
	public Color getColor() {
		return new Color(R, G, B);
	}
	public int getW(){
		return W;
	}
	public Component getCpnt() {
		return box2;
	}
	public void setLabelColor() {
		printcolor.setText(
			Integer.toHexString(R).toUpperCase()+ ","
				+ Integer.toHexString(G).toUpperCase()+ ","
				+ Integer.toHexString(B).toUpperCase()+ ","
				+ W);
	}
	class Listener implements AdjustmentListener {
		public void adjustmentValueChanged(AdjustmentEvent e) {
			// point_num = e.getValue();
			if (e.getAdjustable().equals(Rscr)) {
				R = e.getValue();
			}
			else if (e.getAdjustable().equals(Gscr)) {
				G = e.getValue();
			}
			else if (e.getAdjustable().equals(Bscr)) {
				B = e.getValue();
			}
			else if (e.getAdjustable().equals(Wscr)) {
				W = e.getValue();
			}
			Rscr.setBackground(getColor());
			Gscr.setBackground(getColor());
			Bscr.setBackground(getColor());
			setLabelColor();
		}

	}

}
