package com.haru.tetoru.parts;

import java.util.Random;

import com.haru.tetoru.parts.Mino.ROTATE_MINO_TYPE;


/* ネクスト */
class NextTable {

	/* ネクストの管理配列 */
	private int[] nextInfo;

	/* ネクスト表示用テーブル */
	private int[][] nextTable;

	/* ネクスト管理数 */
	private int num;

	/* ネクストの管理配列の次のミノの添字 */
	private int nextIdx;


	/* デバッグ */
	int debug = 1; /* 2にすると、numの2倍のネクストが見えるようになる */


	NextTable() {
		this(7);
	}

	NextTable(int num) {
		nextInfo = new int[7 * 2];
		nextTable = new int[4 * num * debug][5];
		this.num = num;		
		nextIdx = 0;
		
		/* 初期化 */
		initTable();
		
		/* ネクストの管理配列を適当に初期化 */
		nextInfo[0] = 3;
		nextInfo[1] = 4;
		nextInfo[2] = 5;
		nextInfo[3] = 6;
		nextInfo[4] = 7;
		nextInfo[5] = 1;
		nextInfo[6] = 2;
		nextInfo[7] = 1;
		nextInfo[8] = 2;
		nextInfo[9] = 3;
		nextInfo[10] = 4;
		nextInfo[11] = 5;
		nextInfo[12] = 6;
		nextInfo[13] = 7;

		/* 前方num個シャッフル */
		shuffle(0, num-1);
	}


	/* ネクストのミノを取得 */
	public int getNextType() {

//		Debug.println("getNextType() nextidx:" + nextIdx);

		int retType;

		/* ネクストのミノの種類を取得 */
		retType = nextInfo[nextIdx];

		/* num回に１回シャッフル */
		if (0 == nextIdx) {
			/* 後方num個シャッフル */
			shuffle(num, num*2-1);
		} else if (num == nextIdx) {
			/* 前方num個シャッフル */
			shuffle(0, num-1);
		}

		/* 添字の更新 */
		nextIdx = (nextIdx+ 1) % (num * 2);

		return retType;
	}

	/* シャッフル用の乱数生成器 */
	private Random r = new Random();

	/**
	 * シャッフル
	 * @param startIdx
	 * @param endIdx
	 */
	public void shuffle(int startIdx, int endIdx) {
		for (int i = startIdx; i < endIdx; i++) {
			/* 入れ替え対象取得((i + 1)〜 endIdxまで) */
			int idx = getRandom(startIdx, endIdx);
			
			/* i番目と入れ替え */
			int tmp = nextInfo[idx];
			nextInfo[idx] = nextInfo[i];
			nextInfo[i] = tmp;
		}
	}
	/* min以上max以下の乱数生成 */
	private int getRandom(int min, int max) {
		return r.nextInt(max+1-min) + min;
	}


	/* ネクストテーブルの初期化 */
	private void initTable() {
		for (int y = 0; y < nextTable.length; y++) {
			for (int x = 0; x < nextTable[y].length; x++) {
				nextTable[y][x] = Mino._;
			}
		}
	}

	/**
	 * 内部情報を文字列化(ネクスト表示用情報を作成
	 */
	public String toString() {
		/********************************/
		/* ネクスト表示テーブルを初期化 */
		/********************************/
		initTable();

		/********************************/
		/* ネクスト表示テーブルを作成 */
		/********************************/
		final int x = 2;	/* ミノ設定位置 */
		int y = 2;			/* ミノ設定位置 */

		for (int i = 0; i < num * debug; i++) {
			/* 取得する要素の添字 */
			int typeIdx = (i + nextIdx) % (num * 2);
			
			/* ネクストの種類を取得 */
			int type = nextInfo[typeIdx];
			
			/* ミノを作成 */
			Mino mino = new Mino(type, x, y);
			
			/* ミノをネクスト描画テーブルに設定 */
			setMino(mino);
			
			/* テーブルの設定位置を更新 */
			y += 3;
		}

		/********************************/
		/* ネクスト表示用情報を作成     */
		/********************************/
		StringBuilder builder = new StringBuilder();
		for (int[] yoko : nextTable) {
			for (int block : yoko) {
				builder.append(block);
			}
			builder.append(System.getProperty("line.separator"));
		}

		return builder.toString();
	}

	/********************************/
	/* ネクスト表示テーブル         */
	/********************************/
	/* ミノをテーブルに設定 */
	private void setMino(Mino mino) {
		int cnt;
		int type = mino.getType();
		int x = mino.getX();
		int y = mino.getY();
		int[][] info = mino.getInfo();

		/* 3点をテーブルに設定 */
		for (cnt = 0; cnt < info.length; cnt++) {
			int offsetX = info[cnt][0];
			int offsetY = info[cnt][1];
			
			nextTable[y + offsetY][x + offsetX] = type;
		}
		/* 中心をテーブルに設定 */
		nextTable[y][x] = type;
	}

}
