
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 m0104352_karugamo extends Applet implements Runnable{
	////////////////////設定//////////////////////////////
	private static final int IMAGE_WIDTH = 600, //キャンバスのサイズ
								IMAGE_HEIGHT = 600,
								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= "全消去";
	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;
	public Label printmode;
	public Checkbox checkbox;
	public Box bx ; //たて
	public Box bx2 ; //よこ
	private static final int point_data[][][] = // 点情報
		{{{1000, 1000},},
			{{78, 90},{76, 63},{84, 45},{110, 30},},
			{{110, 30},{140, 15},{160, 18},},
			{{78, 90},{80, 100},{80, 110},{70, 120},{60, 135},{55, 150},},
			{{55, 150},{48, 165},{70, 149},},
			{{70, 149},{84, 137},{91, 127},{99, 120},{113, 115},},
			{{60, 137},{67, 144},{64, 153},},
			{{78, 100},{88, 112},{95, 110},{113, 115},},
			{{113, 115},{125, 116},{143, 110},{150, 105},},
			{{150, 105},{170, 95},{173, 82},{168, 63},{145, 60},},
			{{127, 113},{115, 127},{90, 150},{70, 170},{65, 200},{75, 250},},

			{{160, 18},{185, 21},{200, 48},},
			{{200, 48},{215, 80},{205, 105},},
			{{205, 105},{195, 140},{160, 175},},
			{{160, 175},{225, 115},{320, 113},{350, 158},{415, 168},},
			{{415, 168},{445, 165},{450, 166},},
			{{450, 166},{445, 173},{433, 178},},
			{{415, 168},{440, 170},{410, 180},},
			{{410, 180},{447, 175},{450, 182},},
			{{450, 182},{440, 200},{365, 235},},
			{{450, 167},{480, 165},{500, 172},},

			{{450, 182},{490, 179},{520, 189},},
			{{500, 172},{487, 178},{465, 182},},
			{{520, 189},{450, 245},{365, 235},},
			{{431, 179},{395, 210},{325, 235},},
			{{290, 145},{330, 145},{350, 180},{415, 168},{375, 182},},
			{{410, 180},{399, 180},{385, 176},},
			{{282, 177},{313, 181},{347, 191},{342, 205},{323, 217},{255, 230},},
			{{333, 200},{352, 194},{375, 182},},
			{{249, 174},{287, 175},{320, 187},{295, 212},{263, 227},{235, 237},},
			{{260, 156},{295, 152},{300, 180},{375, 176},{322, 188},},

			{{75, 250},{95, 300},{180, 277},{220, 330},{310, 320},},
			{{310, 320},{360, 315},{440,305},{500, 268},},
			{{575, 230},{520, 270},{440, 285},},
			{{485, 213},{518, 227},{575, 230},},
			{{575, 230},{515, 248},{470, 250},},
			{{440, 285},{460, 265},{470, 250},},
			{{470, 250},{505, 242},{525, 224},},
			{{365, 235},{320, 255},{255, 268},},
			{{275, 227},{300, 237},{325, 235},},
			{{235, 237},{200, 245},{170, 245},{173, 225},{135, 220},},

			{{355, 240},{400, 260},{380, 290},{355, 315},},
			{{280, 262},{310, 300},{330, 260},{345, 315},},
			{{395, 236},{440, 255},{420, 285},{395, 307},},
			{{435, 231},{470, 245},{450, 275},},
			{{445, 283},{440, 291},{432, 297},},
			{{470, 250},{460, 239},{457, 225},},
			{{493, 242},{480, 232},{477, 216},},
			{{510, 234},{500, 230},{498, 218},},
			{{325, 250},{370, 268},{337, 296},},
			{{297, 258},{329, 269},{317, 281},},

			{{480, 182},{470, 203},{398, 236},},
			{{483, 190},{475, 203},{427, 228},},
			{{451, 190},{442, 203},{394, 228},},
			{{255, 268},{200, 277},{155, 262},},
			{{427, 256},{432, 280},{418, 290},},
			{{387, 264},{392, 288},{377, 299},},
			{{245, 269},{280, 320},{298, 285},{318, 320},},
			{{260, 320},{240, 290},{210,280},},
			{{220, 310},{200, 290},{170,280},},
			{{233, 174},{257, 175},{290, 187},{265, 212},{252, 215},{232, 223},},

			{{193, 165},{228, 175},{265, 187},{240, 208},{227, 213},{197, 223},},
			{{173, 173},{202, 182},{240, 190},{215, 208},{202, 213},{170, 221},},
			{{232, 238},{230, 225},{209,223},},
			{{202, 241},{200, 225},{179,221},},
			{{255, 230},{258, 224},{240, 222},},
			{{160, 175},{148, 190},{140, 203},},
			{{222, 149},{275, 162},{249, 172},},
			{{162, 185},{220, 200},{150, 215},},
			{{545, 242},{520, 260},{455, 276},},
			{{223, 239},{250, 255},{287, 261},},

			{{158, 227},{197, 265},{237, 270},},
			{{417, 183},{384, 210},{316, 232},},
			{{80, 231},{84, 268},{127, 275},},
			{{87, 211},{89, 268},{141, 268},},
			{{195, 105},{182, 140},{157, 165},},
			{{84, 310},{180, 390},{395, 390},{520, 310},},
			{{84, 360},{180, 440},{395, 440},{520, 360},},
			{{84, 410},{180, 490},{395, 490},{520, 410},},
			{{84, 460},{160, 510},{250, 510},},
			{{84, 510},{160, 560},{250, 555},},

			{{552, 230},{525, 238},{512, 239},},
			{{132, 56},{123, 48},{110, 50},{105, 66},},
			{{132, 56},{130, 68},{115, 73},{105, 66},},
			{{115, 52},{129, 48},{133, 67},{121, 68},},
			{{115, 52},{103, 58},{111, 71},{121, 68},},
			{{78, 95},{87, 65},{114, 52},},
			{{79, 103},{95, 77},{120, 69},},
			{{114, 52},{142, 43},{165, 45},},
			{{120, 69},{135, 55},{165, 45},},
			{{113, 115},{116, 83},{140, 69},},

			{{130, 113},{121, 90},{140, 69},},
			{{78, 85},{84, 63},{96, 47},{118, 37},},
			{{118, 37},{140, 28},{160, 30},},
			{{160, 30},{180, 28},{198, 44},},

	};
	////////////////////スレッド用//////////////////////
	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 panicMove(Point p[],int k){
		for(int i=0;i<p.length && p[i]!=null;i++){
			p[i].x += v[k][i].x;
			p[i].y += v[k][i].y;
			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].y*=-1;
			}
			if(IMAGE_WIDTH<p[i].x){
				p[i].x=IMAGE_WIDTH-1;
				v[k][i].x*=-1;
			}
			if(IMAGE_HEIGHT<p[i].y){
				p[i].y=IMAGE_HEIGHT-1;
				v[k][i].y*=-1;
			}
		}
	}
	public void gMove(Point p[],int k){
		double ex=0.99,ey=0.8; //跳ね返り係数
		//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;
			}

				p[i].x += v[k][i].x;
				p[i].y += v[k][i].y;
			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 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);
		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(150));
		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);
				}
			}

		});
		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);
			}
				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();
		}

	}

}
