public class Field {
	private int time;
	private int [] tokuten = {50,300,1000,1350};
	private String [] rank = {"F","E","D","C","B","A","S","SS"};
	private int [] rank_data = {50,100,200,300,400,600,800};
	private int stage;
	private Field_Hole [][] p_hole;
	private Field_Hole [][] r_hole;
	private Field_Hole [][] u_hole;
	private Field_Paneru f_p;
	private int f_p_no;
	private int [][][] stage_data = {{{7,1,4,6},{1,2,4,2},{2,3,9,1},{3,1,2,4},
		   {5,4,6,1},{4,3,2,4},{3,2,1,4},{2,3,4,8},
		   {3,7,1,8},{7,8,4,2},{8,3,4,6},{3,6,8,4},
		   {3,6,8,9},{6,4,2,8},{4,2,6,7},{2,3,4,5}},
		  {{9,3,4,0},{9,8,1,5},{8,0,5,4},{3,9,4,2},
		   {3,1,4,7},{1,8,2,8},{1,4,7,1},{0,6,8,4},
		   {8,3,7,0},{6,3,1,8},{7,1,0,7},{4,6,0,5},
		   {6,9,5,9},{7,7,9,6},{6,7,7,6},{9,8,6,7}},
		  {{6,2,0,8},{2,8,0,1},{6,0,8,1},{7,5,1,0},
		   {8,7,0,8},{8,6,7,0},{7,6,1,8},{5,8,8,0},
		   {4,6,7,8},{1,2,2,1},{8,4,8,7},{8,2,0,9},
		   {9,7,6,7},{2,9,2,8},{3,8,7,2},{2,8,9,8}},
		  {{1,5,4,0},{0,0,6,2},{5,2,2,4},{7,2,3,1},
		   {8,7,3,9},{2,0,8,3},{0,8,4,5},{4,4,7,3},
		   {3,4,2,4},{8,0,6,4},{5,5,4,6},{5,3,8,6},
		   {4,0,0,2},{0,5,4,8},{5,3,3,7},{0,6,7,3}},
		  {{8,3,1,0},{9,7,4,3},{4,3,2,0},{7,1,3,8},
		   {3,4,8,9},{7,8,5,6},{0,7,4,1},{1,3,6,2},
		   {9,9,2,4}
		  },
		  {{0,0,6,6},{7,2,1,6},{6,1,5,6},{8,6,7,1},
		   {7,6,7,7},{2,2,9,7},{2,7,5,7},{1,1,6,9},
		   {6,0,7,5}
		  },
		  {{9,7,2,4},{0,2,1,2},{2,3,3,8},{7,9,8,1},
		   {3,2,9,8},{4,7,8,5},{7,0,5,3},{2,5,1,2},
		   {2,7,4,3}
		  },
		  {{5,1,5,5},{1,9,2,5},{8,7,9,8},{6,0,5,6},
		   {4,0,4,8},{4,6,5,4},{0,5,3,9},{0,8,6,6},
		   {9,7,8,3}
		  },
		  {{4,3,1,5},{8,9,5,1},{9,8,6,4},{9,4,2,6}
		  },
		  {{7,0,5,9},{8,7,8,1},{8,7,1,5},{7,0,9,4}
		  },
		  {{5,2,3,9},{1,8,2,3},{2,2,8,4},{8,2,8,8}
		  },
		  {{2,5,4,6},{1,3,6,9},{5,1,6,4},{3,8,4,7}
		  }};
	private Tetravex tv;
	private Move_Field_Paneru mf_p = null;
	private int retu;
	public Field(Tetravex tv,int retu){
		this.retu = retu;
		this.tv = tv;
		f_p = null;
		p_hole = new Field_Hole[retu][retu];
		for(int i = 0;i < retu;i++){
			for(int j = 0;j < retu;j++){
				p_hole[i][j] = new Field_Hole(6+j*50,60+j*50);
			}
		}
		r_hole = new Field_Hole[4][2];
		for(int i = 0;i < 4;i++){
			for(int j = 0;j < 2;j++){
				r_hole[i][j] = new Field_Hole(228+j*50,60+i*50);
			}
		}
		u_hole = new Field_Hole[2][4];
		for(int i = 0;i < 2;i++){
			for(int j = 0;j < 4;j++){
				u_hole[i][j] = new Field_Hole(6+j*50,282+i*50);
			}
		}
		time = 0;
		stage = 1;
		stage_read(retu);
	}
	public boolean isComplete() {
		return false;
	}
	public void addTime() {
		time = time + 1;
	}
	public int getTime() {
		return time;
	}
	public void setTime(int time){
		this.time = time;
	}
	public int getRetu(){
		return retu;
	}
	public int getTokuten(int retu){
		int ten = tokuten[retu - 2] - (time / 100);
		if(ten < 0){
			return 0;
		}else{
			return ten;
		}
	}
	public void addStage(){
		stage = stage + 1;
	}
	public int getStage(){
		return stage;
	}
	public String getRank(int retu){
		int ten = getTokuten(retu);
		int rten = ten * 1000 / tokuten[retu - 2];
		if(rten >= 800){
			return rank[7];
		}else{
			int i = 0;
			while(rten > rank_data[i]){
				i = i + 1;
			}
			return rank[i];
		}
	}
	public void setMove_Field_Paneru(Move_Field_Paneru mf_p){
		this.mf_p = mf_p;
	}
	public Move_Field_Paneru getMove_Field_Paneru(){
		return mf_p;
	}
	public void stage_read(int retu){
		int [] flg = new int[16];
		for(int i = 0;i < 16;i++){
			flg[i] = 0;
		}
		int	r = (int)(Math.random() * 4) + (4 - retu) * 4;
		for(int i = 0;i < retu * retu;i++){
			Paneru p = new Paneru(stage_data[r][i][0],stage_data[r][i][1],stage_data[r][i][2],stage_data[r][i][3]);
			int r2 = (int)(Math.random()*16);
			while(flg[r2] == 1){
				r2 = (int)(Math.random()*16);
			}
			flg[r2] = 1;
			if(r2 <= 7){
				int x = r_hole[r2/2][r2%2].getHindex_x();
				int y = r_hole[r2/2][r2%2].getHindex_y();
				r_hole[r2/2][r2%2].setField_Paneru(new Field_Paneru(x,y,p));
			}else{
				int x = u_hole[(r2 - 8)/4][(r2 - 8)%4].getHindex_x();
				int y = u_hole[(r2 - 8)/4][(r2 - 8)%4].getHindex_y();
				u_hole[(r2- 8)/4][(r2 - 8)%4].setField_Paneru(new Field_Paneru(x,y,p));
			}
		}
	}
	public Field_Hole getP_hole(int x,int y){
		return p_hole[x][y];
	}
	public Field_Hole getR_hole(int x,int y){
		return r_hole[x][y];
	}
	public Field_Hole getU_hole(int x,int y){
		return u_hole[x][y];
	}
	public void moveIndex(int ix,int iy,int mouse_x,int mouse_y){
		int idx = mf_p.getf_p().getIndex_x();
		int idy = mf_p.getf_p().getIndex_y();
		mf_p.getf_p().setIndex_x(idx+ix-mouse_x);
		mf_p.getf_p().setIndex_y(idy+iy-mouse_y);
		tv.setMouse_x(ix);
		tv.setMouse_y(iy);
	}
	public void set_reverse(){
		Field_Paneru f_p = getMove_Field_Paneru().getf_p();
		int f_p_no = getMove_Field_Paneru().getf_p_no();
		String panel_kubun = getMove_Field_Paneru().getPanel_kubun();
		int base_x = getMove_Field_Paneru().getBase_x();
		int base_y = getMove_Field_Paneru().getBase_y();
		f_p.setIndex_x(base_x);
		f_p.setIndex_y(base_y);
		if(panel_kubun.equals("P")){
			getP_hole(f_p_no / retu,f_p_no % retu).setField_Paneru(f_p);
		}else{
			if(panel_kubun.equals("R")){
				getR_hole(f_p_no / 2,f_p_no % 2).setField_Paneru(f_p);
			}else{
				getU_hole(f_p_no / 4,f_p_no % 4).setField_Paneru(f_p);
			}
		}
	}
	public boolean existCheck(int i,int j,String kubun){
		if(kubun.equals("P")){
			if(p_hole[i][j].getField_Paneru()!=null){
				return true;
			}else{
				return false;
			}
		}else{
			if(kubun.equals("R")){
				if(r_hole[i][j].getField_Paneru()!=null){
					return true;
				}else{
					return false;
				}
			}else{
				if(u_hole[i][j].getField_Paneru()!=null){
					return true;
				}else{
					return false;
				}
			}
		}
	}
	public boolean upCheck(int i,int j){
		if(i == 0){
			return true;
		}else{
			if(p_hole[i - 1][j].getField_Paneru()!=null){
				int p_number = p_hole[i - 1][j].getField_Paneru().getPaneru().getDown();
				int m_number = mf_p.getf_p().getPaneru().getUp();
				if(p_number == m_number){
					return true;
				}
			}else{
				return true;
			}
		}
		return false;
	}
	public boolean downCheck(int i,int j){
		if(i == retu - 1){
			return true;
		}else{
			if(p_hole[i + 1][j].getField_Paneru()!=null){
				int p_number = p_hole[i + 1][j].getField_Paneru().getPaneru().getUp();
				int m_number = mf_p.getf_p().getPaneru().getDown();
				if(p_number == m_number){
					return true;
				}
			}else{
				return true;
			}
		}
		return false;
	}
	public boolean leftCheck(int i,int j){
		if(j == 0){
			return true;
		}else{
			if(p_hole[i][j - 1].getField_Paneru()!=null){
				int p_number = p_hole[i][j - 1].getField_Paneru().getPaneru().getRight();
				int m_number = mf_p.getf_p().getPaneru().getLeft();
				if(p_number == m_number){
					return true;
				}
			}else{
				return true;
			}
		}
		return false;
	}
	public boolean rightCheck(int i,int j){
		if(j == retu - 1){
			return true;
		}else{
			if(p_hole[i][j + 1].getField_Paneru()!=null){
				int p_number = p_hole[i][j + 1].getField_Paneru().getPaneru().getLeft();
				int m_number = mf_p.getf_p().getPaneru().getRight();
				if(p_number == m_number){
					return true;
				}
			}else{
				return true;
			}
		}
		return false;
	}
	public boolean gameClear(){
		for(int i = 0;i < retu;i++){
			for(int j = 0;j < retu;j++){
				if(p_hole[i][j].getField_Paneru()==null){
					return false;
				}
			}
		}
		return true;
	}
	public boolean gameOver(String stage_mode){
		if(stage_mode.equals("R")){
			if(time > tokuten[retu - 2] * 100){
				return true;
			}
		}
		if(stage_mode.equals("F")){
			if(time > 720000){
				return true;
			}
		}
		return false;
	}
}
