import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Block_Break extends Applet implements MouseListener,MouseMotionListener,Runnable{
	private Dimension d;
	private Image offscreen;
	private Graphics grf;
	private Image startbutton;
	private Image sankaku;
	private Image haikei;
	private Image haikei2;
	private Image [] itemImage;
	private AudioClip [] au;
	private MediaTracker mt;
	private boolean start = false;
	private Color backgroundColor;
	private Color frameColor;
	private Color [] blockColor = new Color[3];
	private Color mojiColor;
	private Color barColor;
	private Thread thread = null;
	private Thread thread2 = null;
	private Thread thread3 = null;
	private Thread thread4 = null;
	private Thread thread5 = null;
	private Thread thread6 = null;
	private Field field;
	private Judge judge;
	private Wait_count wc;
	private String st_mode[] = {"Ｆ","Ｒ"};
	private String sp_mode[] = {"１","２","３","４","５"};
	private int speed[] = {30,25,20,15,10};
	private int st_index = 0;
	private int sp_index = 0;
	private boolean newGame = true;
	public boolean waitflg = false;
	public void init(){
		d = getSize();
		offscreen = createImage(d.width,d.height);
		grf = offscreen.getGraphics();
		field = new Field(st_mode[st_index],this);
		judge = new Judge(field,this);
		au = new AudioClip[3];
		au[0] = getAudioClip(getDocumentBase(),"blockhit.wav");
		au[1] = getAudioClip(getDocumentBase(),"barhit.wav");
		au[2] = getAudioClip(getDocumentBase(),"miss.wav");
		startbutton = getImage(getCodeBase(),"startbutton.png");
		mt = new MediaTracker(this);
		mt.addImage(startbutton,0);
		sankaku = getImage(getCodeBase(),"sankaku.png");
		mt.addImage(sankaku,0);
		haikei = getImage(getCodeBase(),"haikei.png");
		mt.addImage(haikei,0);
		haikei2 = getImage(getCodeBase(),"haikei2.png");
		mt.addImage(haikei2,0);
		itemImage = new Image[4];
		itemImage[0] = getImage(getCodeBase(),"item_ballbig.png");
		mt.addImage(itemImage[0],0);
		itemImage[1] = getImage(getCodeBase(),"item_ballsmall.png");
		mt.addImage(itemImage[1],0);
		itemImage[2] = getImage(getCodeBase(),"item_barbig.png");
		mt.addImage(itemImage[2],0);
		itemImage[3] = getImage(getCodeBase(),"item_barsmall.png");
		mt.addImage(itemImage[3],0);
		frameColor = new Color(192,192,192);
		backgroundColor = new Color(0,210,210);
		blockColor[0] = new Color(255,0,0);
		blockColor[1] = new Color(0,255,0);
		blockColor[2] = new Color(0,0,255);
		mojiColor = new Color(0,0,0);
		barColor = new Color(255,255,0);
		if(newGame){
			addMouseListener(this);
			addMouseMotionListener(this);
			newGame = false;
		}
	}
	public void paint(Graphics g){
		update(g);
	}
	public void update(Graphics g){
		if(!mt.checkID(0)){
			g.setColor(Color.black);
			g.drawString("Please wait...",d.width / 4,d.height / 2);
			return;
		}
		grf.setColor(frameColor);
		grf.fillRect(0,0,d.width,d.height);
		grf.drawImage(haikei,5,5,this);
		for(int i = 0;i < 10;i++){
			for(int j = 0;j < 12;j++){
				Block_Field bf = field.getBlockField(i,j);
				if(bf != null){
					if(bf.getBlockLife() > 0){
						grf.setColor(blockColor[bf.getBlockLife() - 1]);
						grf.fillRect(bf.getBlockIndex_x(),bf.getBlockIndex_y(),20,12);
					}else{
						if(bf.getItem() != null){
							if(bf.getItem().getitemIndex_y() < 343){
								grf.drawImage(itemImage[bf.getItem().getitemNo()],bf.getItem().getitemIndex_x(),bf.getItem().getitemIndex_y(),this);
							}
						}
					}
				}
			}
		}
		Ball ball = field.getBall();
		grf.setColor(new Color(0,95,189));
		grf.fillOval(ball.getBallIndex_x(),ball.getBallIndex_y(),ball.getBallLength(),ball.getBallLength());
		Bar bar = field.getBar();
		grf.setColor(barColor);
		grf.fillRect(bar.getBarIndex_x(),bar.getBarIndex_y(),bar.getBarLength(),bar.getBarHeight());
		if(judge.gameOver()){
			grf.setColor(mojiColor);
			grf.setFont(new Font("TimesRoman",Font.PLAIN,18));
			grf.drawString("GameOver",95,170);
			double time = (double)(judge.getTime());
			time = time / 100.0;
			grf.drawString("Time："+time,130,270);
			grf.drawString("SCORE："+field.getScore(),130,320);
			start = false;
		}
		if(judge.gameClear()){
			grf.setColor(mojiColor);
			grf.setFont(new Font("TimesRoman",Font.PLAIN,18));
			grf.drawString("GameClear",130,170);
			double time = (double)(judge.getTime());
			time = time / 100.0;
			grf.drawString("Time："+time,130,270);
			grf.drawString("SCORE："+field.getScore(),130,320);
			start = false;
		}
		grf.setColor(backgroundColor);
		grf.fillRect(0,360,310,50);
		grf.drawImage(startbutton,5,368,this);
		grf.setFont(new Font("SanSerif",Font.PLAIN,12));
		grf.setColor(mojiColor);
		double time = (double)(judge.getTime());
		time = time / 100.0;
		grf.drawString("Time："+time,200,345);
		if(start){
			grf.drawString("ＳＣＯＲＥ = "+field.getScore(),80,394);
			grf.drawString("ＬＩＦＥ = "+field.getLife(),190,394);
		}else{
			grf.drawString("ＳＴＡＧＥ　ＭＯＤＥ",70,379);
			grf.drawImage(sankaku,200,368,this);
			grf.drawString("ＳＰＥＥＤ　ＬＶ",70,404);
			grf.drawImage(sankaku,200,393,this);
			grf.drawString(st_mode[st_index],230,379);
			grf.drawString(sp_mode[sp_index],230,404);
		}
		g.drawImage(offscreen,0,0,this);
	}
	public void musicPlay(int i){
		au[i].play();
	}
	public void mouseClicked(MouseEvent e) {
		// TODO 自動生成されたメソッド・スタブ
	}
	public void mousePressed(MouseEvent e) {
		// TODO 自動生成されたメソッド・スタブ
		int ix = e.getX();
		int iy = e.getY();
		if(ix >= 5 && ix <= 60 && iy >= 368 && iy <= 398){
			stop();
			start = true;
			init();
			waitflg = true;
			waitThread();
			while(waitflg){
			}
			moveThreadStart();
			timerThread();
			return;
		}
		if(ix >= 200 && ix <= 215 && iy >= 368 && iy <= 383){
			st_index++;
			if(st_index == st_mode.length){
				st_index = 0;
			}
			repaint();
			return;
		}
		if(ix >= 200 && ix <= 215 && iy >= 393 && iy <= 408){
			sp_index++;
			if(sp_index == sp_mode.length){
				sp_index = 0;
			}
			repaint();
			return;
		}
		
	}
	public void mouseReleased(MouseEvent e) {
		// TODO 自動生成されたメソッド・スタブ
	}
	public void mouseEntered(MouseEvent e) {
		// TODO 自動生成されたメソッド・スタブ
	}
	public void mouseExited(MouseEvent e) {
		// TODO 自動生成されたメソッド・スタブ
	}
	public void mouseDragged(MouseEvent e) {
		// TODO 自動生成されたメソッド・スタブ
		
	}
	public void mouseMoved(MouseEvent e) {
		// TODO 自動生成されたメソッド・スタブ
		if(start){
			int ix = e.getX();
			int iy = e.getY();
			field.setBarIndex(ix,iy);
			repaint();
		}
	}
	public void moveThreadStart(){
		Move_Thread mt = new Move_Thread(this,field,judge,speed[sp_index]);
		thread2 = new Thread(mt);
		thread2.start();
	}
	public void itemFalledStart(Item item){
		ItemFall_Thread ift = new ItemFall_Thread(this,field,item,speed[sp_index]);
		thread5 = new Thread(ift);
		thread5.start();
	}
	public void itemEffectThread(Item item){
		Item_EffectThread iet = new Item_EffectThread(this,field,item);
		thread6 = new Thread(iet);
		thread6.start();
	}
	public void setWaitFlg(boolean waitflg){
		this.waitflg = waitflg;
	}
	public boolean getWaitFlg(){
		return waitflg;
	}
	public void waitThread(){
		wc = new Wait_count(this,field);
		thread3 = new Thread(wc);
		thread3.start();
	}
	public void timerThread(){
		Timer_Thread tt = new Timer_Thread(judge,this);
		thread4 = new Thread(tt);
		thread4.start();
	}
	public void start(){
		if(thread == null){
			thread = new Thread(this);
			thread.start();
		}
	}
	public void stop(){
		if(thread != null){
			thread.stop();
			thread = null;
		}
		if(thread2 != null){
			thread2.stop();
			thread2 = null;
		}
		if(thread3 != null){
			thread3.stop();
			thread3 = null;
		}
		if(thread4 != null){
			thread4.stop();
			thread4 = null;
		}
		for(int i = 0;i < 3;i++){
			if(au[i] != null){
				au[i].stop();
				au[i] = null;
			}
		}
	}
	public void run(){
		try{
			mt.waitForID(0);
		}
		catch(InterruptedException e){
			return;
		}
		repaint();
	}
}
