
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 Bezier extends Applet implements Runnable{
	////////////////////設定//////////////////////////////
	private static final int IMAGE_WIDTH = 500, //キャンバスのサイズ
								IMAGE_HEIGHT = 500, 
								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},},
			{{233, 339},{153, 339},{114, 271},{114, 217},},
			{{233, 339},{296, 337},{354, 300},{357, 213},},
			{{114, 219},{113, 145},{146, 92},{232, 93},},
			{{232, 93},{311, 99},{356, 143},{357, 216},},
			{{141, 127},{168, 101},{211, 119},{208, 144},},
			{{209, 144},{214, 172},{192, 199},{174, 199},},
			{{176, 198},{136, 212},{116, 168},{138, 130},},
			{{319, 133},{344, 154},{351, 183},{325, 205},},
			{{325, 205},{290, 225},{277, 213},{260, 196},},
			{{261, 197},{243, 172},{261, 113},{319, 132},},
			{{119, 251},{155, 255},{180, 234},{202, 232},{225, 241},},
			{{225, 240},{259, 257},{272, 291},{301, 297},{325, 299},},
			{{158, 245},{192, 298},{227, 297},{263, 271},},
			{{143, 135},{201, 159},},
			{{199, 158},{138, 168},},
			{{327, 154},{262, 166},{262, 166},},
			{{319, 194},{263, 165},},
			{{295, 110},{314, 87},{376, 76},},
			{{376, 74},{392, 121},{350, 170},},
			{{125, 150},{112, 109},{122, 72},},
			{{121, 70},{151, 71},{186, 99},},
			{{304, 113},{326, 95},{367, 86},},
			{{368, 86},{379, 119},{346, 160},},
			{{130, 147},{120, 116},{126, 78},},
			{{125, 79},{153, 83},{174, 101},},
			{{374, 130},{361, 164},{352, 179},},
			{{292, 324},{318, 352},{339, 361},},
			{{320, 306},{362, 342},{385, 331},{394, 322},},
			{{392, 324},{462, 290},{499, 337},{481, 358},{474, 373},},
			{{475, 370},{462, 411},{395, 394},{340, 362},},
			{{185, 97},{252, 66},{294, 109},},
			{{124, 150},{77, 221},{40, 244},},
			{{40, 244},{66, 285},{88, 304},},
			{{88, 304},{111, 286},{120, 259},},
			{{353, 175},{384, 265},{399, 289},},
			{{325, 302},{335, 317},{344, 317},},
			{{400, 290},{397, 306},{345, 316},},

	};
	////////////////////スレッド用//////////////////////
	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();
		}

	}

}
