import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Tetoris extends Applet implements KeyListener,MouseListener{
	//この部分に使用する変数を宣言//
	private Dimension d;
	private Image offscreen;
	private Image sankaku1;
	private Image sankaku2;
	private AudioClip ac;
	private Graphics grf;
	private boolean anglepush[] = {false,false,false};
	private boolean optionupdate[] = {false,false,false};
	private String optionstring[][] = {{"normal","hidden","stealth"},{"1x speed","2x speed"},{"30","15","10","7","6"}};
	private String optiontitlestring[] = {"visible option","speed option","I_LVUP"};
	private boolean ableclick = false;
	private boolean move = false;
	private boolean key1 = false;
	private boolean key2 = false;
	private boolean key3 = false;
	private boolean key4 = false;
	private boolean radio[][] = {{true,false,false},{true,false},{true,false,false,false,false}};
	private int bw = 10;
	private int bh = 10;
	private Color bgcolor;
	private Color block_kakutei_color;
	private Color block_rakka_color;
	private Color displaycolor;
	private Color panelcolor;
	private Color mojicolor;
	private Font  label_font;
	private Font  ten_level_font;
	private Font  title_font;
	private Field field;
	private FallMove fallmove;
	private TimeCounter timecounter;
	private Thread thread;
	private Thread thread2;
	public void init(){
		//下の３つの処理で表示するアプレット画面のコピーを用意する。//
		d = getSize();
		offscreen = createImage(d.width,d.height);
		grf = offscreen.getGraphics();
		//ここで最初にやっておきたい上記以外の処理を記述する//
		ac = getAudioClip(getDocumentBase(),"kya.wav");
		sankaku1 = getImage(getCodeBase(),"sankaku1.jpg");
		sankaku2 = getImage(getCodeBase(),"sankaku2.jpg");
		bgcolor = new Color(173,255,47);
		block_kakutei_color = Color.blue;
		block_rakka_color = Color.red;
		displaycolor = Color.white;
		panelcolor = new Color(176,224,230);
		mojicolor = Color.black;
		label_font = new Font("ＭＳ　ゴジック",Font.BOLD,14);
		ten_level_font = new Font("ＭＳ　ゴジック",Font.PLAIN,14);
		title_font = new Font("ＭＳ　ゴジック",Font.BOLD,18);
		field = new Field(this);
		field.blockInput();
		fallmove = new FallMove(field,this);
		timecounter = new TimeCounter(field,this);
		field.prepareNextPop();
		field.prepareBlockFall();
		field.prepareNextPop();
		addMouseListener(this);
		addKeyListener(this);
		requestFocus();
	}
	public void paint(Graphics g){
		update(g);
	}
	public void update(Graphics g){
	//ここでアプレット画面(コピー)に表示させる処理を記述する//
		
		if(key1){
			field.setPrev_y(-1);
			if(field.getPrev_x() >= 0){
				if(field.blockOutCheck() || field.blockPildCheck()){
					field.setPrev_y(1);
				}
			}else{
				field.setPrev_y(1);
			}
			key1 = false;
	    }
		if(key2){
			field.setPrev_y(1);
			if(field.getPrev_x() >= 0){
				if(field.blockOutCheck() || field.blockPildCheck()){
					field.setPrev_y(-1);
				}
			}else{
				field.setPrev_y(-1);
			}
			key2 = false;
		}
		if(key3){
			if(!field.getGameOver()){
				field.setPrev_x(1);
				if(field.getPrev_x() >= 0){
					if(field.blockOutCheck() || field.blockPildCheck()){
						field.setPrev_x(-1);
						field.blockDecide();
					}
				}else{
					if(field.blockPildCheck()){
						field.setPrev_x(-1);
						field.blockDecide();
					}
				}
			}
			key3 = false;
		}
		if(key4){
			field.blockAroundSet();
			key4 = false;
		}
		grf.setColor(bgcolor);
		grf.fillRect(0,0,d.width,d.height);
		grf.setColor(mojicolor);
		grf.setFont(title_font);
		grf.drawString("テトリス",110,30);
		grf.setColor(displaycolor);
		grf.fillRect(50,50,100,300);
		grf.setColor(panelcolor);
		grf.fillRect(180,63,60,60);
		grf.setColor(block_kakutei_color);
		
		for(int i = 0;i < 30;i++){
			for(int j = 0;j < 10;j++){
				if(field.specialGetMasuCheck(i,j)){
					grf.fillRect(50 + bw * j,50 + bh * i,bw,bh);
				}
			}
		}
		grf.setColor(block_rakka_color);
		if(!field.getStealthmode()){
			if(!(field.getHidden_mode() && field.getPrev_x() >= 15)){
				for(int i = 0;i < 4;i++){
					for(int j = 0;j < 4;j++){
						if(!field.masuOutCheck(field.getPrev_x() + i,field.getPrev_y() + j)){
							if(field.getPrev(i,j)){
								grf.fillRect(50 + bw * (field.getPrev_y() + j),50 + bh * (field.getPrev_x() + i),bw,bh);
							}
						}
					}
				}
			}
		}
		for(int i = 0;i < 4;i++){
			for(int j = 0;j < 4;j++){
				if(field.getNext(i,j)){
					grf.fillRect(180 + bw * (1 + j),63 + bh * (1 + i),bw,bh);
				}
			}
		}
		grf.setColor(panelcolor);
		grf.fillRect(160,155,76,20);
		grf.fillRect(160,185,76,20);
		grf.fillRect(160,215,76,20);
		grf.setColor(mojicolor);
		grf.setFont(label_font);
		grf.drawString("NEXT",190,60);
		grf.drawString("得点:",161,170);
		grf.setFont(ten_level_font);
		grf.drawString(""+ field.getTokuten(),195,170);
		grf.setFont(label_font);
		grf.drawString("レベル:",161,200);
		grf.setFont(ten_level_font);
		grf.drawString(""+ field.getLevel(),210,200);
		grf.setFont(label_font);
		grf.drawString("START",176,230);
		for(int i = 0;i < optiontitlestring.length;i++){
			grf.drawString(optiontitlestring[i],160,258 + 48 * i);
			if(anglepush[i]){
				grf.drawImage(sankaku2,160,265 + 48 * i,this);
			}else{
				grf.drawImage(sankaku1,160,265 + 48 * i,this);
			}
			if(optionupdate[i]){
				int j = getOptionSelectNumber(i);
				radio[i][j] = true;
				optionupdate[i] = false;
			}
			for(int j = 0;j < radio[i].length;j++){
				if(radio[i][j]){
					grf.drawString(optionstring[i][j],190,277 + 48 * i);
				}
			}
		}
		if(field.getGameOver()){
			grf.drawString("GAME OVER",110,210);
		}
		//下の処理で、アプレット画面(コピー)に書き込んだ内容をアプレット画面(本物)に移し、表示する。//
		g.drawImage(offscreen,0,0,this);
	}
	public void mousePressed(MouseEvent e){
		int mx = e.getX();
		int my = e.getY();
		for(int i = 0;i < optiontitlestring.length;i++){
			if(mx >= 160 && mx <= 176 && my >= 265 + 48 * i && my <= 281 + 48 * i){
				anglepush[i] = true;
			}
		}
		repaint();
	}
	public void mouseReleased(MouseEvent e){
		for(int i = 0;i < optiontitlestring.length;i++){
			if(anglepush[i]){
				optionupdate[i] = true;
				anglepush[i] = false;
				ac.play();
			}
		}
		repaint();
	}
	public void mouseExited(MouseEvent e){
	}
	public void mouseEntered(MouseEvent e){
	}
	public void mouseClicked(MouseEvent e){
		int mx = e.getX();
		int my = e.getY();
		if(mx >= 160 && mx <= 236 && my >= 215 && my <= 235){
			move = true;
			init();
			if(radio[0][0]){
				field.setStealthmode(false);
				field.setHidden_mode(false);
			}else{
				if(radio[0][1]){
					field.setStealthmode(false);
					field.setHidden_mode(true);
				}else{
					field.setStealthmode(true);
					field.setHidden_mode(false);
				}
			}
			if(radio[1][0]){
				field.setBaisokumode(false);
			}else{
				field.setBaisokumode(true);
			}
			for(int i = 0;i < radio[2].length;i++){
				if(radio[2][i]){
					int j = Integer.parseInt(optionstring[2][i]);
					timecounter.setLeveluptime(j);
				}
			}
			timeThreadstart();
		}
	}
	public void keyPressed(KeyEvent e){
	  if(move){
		int keycode = e.getKeyCode();
		if(keycode == 37){
			key1 = true;
		}
		if(keycode == 39){
			key2 = true;
		}
		if(keycode == 40){
			key3 = true;
		}
		if(keycode == 32){
			key4 = true;
		}
		repaint();
	  }
	}
	public void keyReleased(KeyEvent e){
	}
	public void keyTyped(KeyEvent e){
		
	}
	public void timeThreadstart(){
		if(thread != null){
			thread.stop();
		}
		if(thread2 != null){
			thread2.stop();
		}
		thread = new Thread(fallmove);
		thread.start();
		thread2 = new Thread(timecounter);
		thread2.start();
	}
	public void setSpeed(){
		fallmove.setSpeed();
	}
	public int getOptionSelectNumber(int option_number){
		int number = -1;
		for(int i = 0;i < radio[option_number].length;i++){
			if(radio[option_number][i]){
				number = i + 1;
				if(number == radio[option_number].length){
					number = 0;
				}
				radio[option_number][i] = false;
			}
		}
		return number;
	}
} 