package com.wusong.mygobang.myview;

import com.wusong.mygobang.R;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

@SuppressLint("ClickableViewAccessibility")
public class GobangView extends View {

	private Activity mainActivity;

	protected static int GRID_SIZE = 15;
	protected static int GRID_WIDTH = 45; // 棋盘格的宽度
	protected static int CHESS_DIAMETER = 43; // 棋的直径
	protected static int mStartX;// 棋盘定位的左上角X
	protected static int mStartY;// 棋盘定位的左上角Y

	private Bitmap[] mChessBW; // 黑棋和白棋
	private static int[][] mGridArray; // 网格

	boolean key = false;

	int wbflag = 1; // 该下白棋了=2，该下黑棋了=1. 这里先下黑棋（黑棋以后设置为机器自动下的棋子）
	int mLevel = 1; // 游戏难度
	int mWinFlag = 0;

	private final int BLACK = 1;
	private final int WHITE = 2;

	int mGameState = GAMESTATE_RUN; // 游戏阶段：0=尚未游戏，1=正在进行游戏，2=游戏结束
	/** 游戏状态：准备阶段 */
	public static final int GAMESTATE_PRE = 0;
	/** 游戏状态：进行中 */
	public static final int GAMESTATE_RUN = 1;
	/** 游戏状态：暂停 */
	public static final int GAMESTATE_PAUSE = 2;
	/** 游戏状态：结束 */
	public static final int GAMESTATE_END = 3;

	private final Paint mPaint = new Paint();

	private Drawable bgPanel;

	CharSequence STRING_WIN = "白棋胜，点击确定重新开始！";
	CharSequence STRING_LOSE = "黑棋胜，点击确定重新开始！";
	CharSequence STRING_EQUAL = "不可思议，你们竟然平局，真是棋逢对手啊！点击确定重新开始！";

	public GobangView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public GobangView(Context context, AttributeSet attrs) { // 好像调用的是这个构造函数，为什么不是前面的呢
		super(context, attrs);

		this.setFocusable(true); // 20090530
		this.setFocusableInTouchMode(true);
		this.setBackgroundColor(0x000000);
		
		if (this.isInEditMode() == false) {
			init();
		} else {
			bgPanel = context.getResources().getDrawable(R.drawable.panel);
		}
	}

	// 这里画棋子后来没有用图片画，而是直接画了圆。因为我做的图片不好看。
	// 初始化黑白棋的Bitmap
	public void init() {
		mGameState = 1; // 设置游戏为开始状态
		wbflag = BLACK; // 初始为先下黑棋
		mWinFlag = 0; // 清空输赢标志。
		mGridArray = new int[GRID_SIZE][GRID_SIZE];

		mChessBW = new Bitmap[2];

		Resources r = this.getContext().getResources();
		Bitmap bitmap1 = Bitmap.createBitmap(CHESS_DIAMETER, CHESS_DIAMETER,
				Bitmap.Config.ARGB_8888);
		Canvas canvas1 = new Canvas(bitmap1);
		Drawable tile1 = r.getDrawable(R.drawable.black);
		tile1.setBounds(0, 0, CHESS_DIAMETER, CHESS_DIAMETER);
		tile1.draw(canvas1);
		mChessBW[0] = bitmap1;

		Bitmap bitmap2 = Bitmap.createBitmap(CHESS_DIAMETER, CHESS_DIAMETER,
				Bitmap.Config.ARGB_8888);
		Canvas canvas2 = new Canvas(bitmap2);
		Drawable tile2 = r.getDrawable(R.drawable.white);
		tile2.setBounds(0, 0, CHESS_DIAMETER, CHESS_DIAMETER);
		tile2.draw(canvas2);
		mChessBW[1] = bitmap2;
		
		bgPanel = r.getDrawable(R.drawable.panel);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (mGameState) {
			case GAMESTATE_PRE:
				break;
			case GAMESTATE_RUN: {
				int x;
				int y;
				float x0 = GRID_WIDTH - (event.getX() - mStartX) % GRID_WIDTH;
				float y0 = GRID_WIDTH - (event.getY() - mStartY) % GRID_WIDTH;
				x = (int) ((event.getX() - mStartX) / GRID_WIDTH);
				if (x0 < GRID_WIDTH / 2) {
					x = (int) ((event.getX() - mStartX) / GRID_WIDTH);
				} else {
					x = (int) ((event.getX() - mStartX) / GRID_WIDTH) - 1;
				}
	
				y = (int) ((event.getY() - mStartY) / GRID_WIDTH);
				if (y0 < GRID_WIDTH / 2) {
					y = (int) ((event.getY() - mStartY) / GRID_WIDTH);
				} else {
					y = (int) ((event.getY() - mStartY) / GRID_WIDTH) - 1;
				}
				if ((x >= 0 && x < GRID_SIZE) && (y >= 0 && y < GRID_SIZE)) {
					if (mGridArray[x][y] == 0) {
						if (wbflag == BLACK) {
							putChess(x, y, BLACK);
							if (checkWin(BLACK)) { // 如果是黑棋赢了
								mGameState = GAMESTATE_END;
								showOverText(STRING_LOSE);
							} else if (checkFull()) {// 如果棋盘满了
								mGameState = GAMESTATE_END;
								showOverText(STRING_EQUAL);
							}
							wbflag = WHITE;
						} else if (wbflag == WHITE) {
							putChess(x, y, WHITE);
							if (checkWin(WHITE)) {
								mGameState = GAMESTATE_END;
								showOverText(STRING_WIN);
							} else if (checkFull()) {// 如果棋盘满了
								mGameState = GAMESTATE_END;
								showOverText(STRING_EQUAL);
							}
							wbflag = BLACK;
						}
					}
				}
			}
				break;
			case GAMESTATE_PAUSE:
				break;
			case GAMESTATE_END:
				break;
		}
		this.invalidate();
		return true;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent msg) {
		Log.e("KeyEvent.KEYCODE_DPAD_CENTER", " " + keyCode);

		if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
			switch (mGameState) {
			case GAMESTATE_PRE:
				break;
			case GAMESTATE_RUN:
				break;
			case GAMESTATE_PAUSE:
				break;
			case GAMESTATE_END:
				// 游戏结束后，按CENTER键继续
				reStartGame();
				break;
			}
		}
		return super.onKeyDown(keyCode, msg);
	}

	/**
	 * 重新开始游戏
	 */
	public void reStartGame() {
		mGameState = GAMESTATE_RUN;
		this.setVisibility(View.VISIBLE);
		this.init();
		this.invalidate();
	}

	@Override
	public void onDraw(Canvas canvas) {
		mStartX = (this.getWidth() - GRID_WIDTH * GRID_SIZE)/2;
		mStartY = (this.getHeight() - GRID_WIDTH * GRID_SIZE) - GRID_WIDTH / 2;
		if (this.isInEditMode() == false) {
			bgPanel.setBounds(mStartX,
							  mStartY,
					mStartX + GRID_WIDTH * GRID_SIZE,
					mStartY + GRID_WIDTH * GRID_SIZE);
			bgPanel.draw(canvas);
			mStartX = 0 - mStartX;
			mStartY = mStartY - GRID_WIDTH / 2;
			// 画棋子
			for (int i = 0; i < GRID_SIZE; i++) {
				for (int j = 0; j < GRID_SIZE; j++) {
					if (mGridArray[i][j] == BLACK) {
						// 通过图片来画
						canvas.drawBitmap(mChessBW[0], 
								mStartX + (i + 1) * GRID_WIDTH - CHESS_DIAMETER / 2, 
								mStartY + (j + 1) * GRID_WIDTH - CHESS_DIAMETER / 2,
								mPaint);
					} else if (mGridArray[i][j] == WHITE) {
						// 通过图片来画
						canvas.drawBitmap(mChessBW[1], 
								mStartX + (i + 1) * GRID_WIDTH - CHESS_DIAMETER / 2, 
								mStartY + (j + 1) * GRID_WIDTH - CHESS_DIAMETER / 2,
								mPaint);
					}
				}
			}
		} else {
			bgPanel.setBounds(mStartX,
							  mStartY,
					mStartX + GRID_WIDTH * GRID_SIZE,
					mStartY + GRID_WIDTH * GRID_SIZE);
			bgPanel.draw(canvas);
		}
	}

	/**
	 * 放置棋子
	 * @param x X坐标
	 * @param y Y坐标
	 * @param blackwhite 棋子类型
	 */
	public void putChess(int x, int y, int blackwhite) {
		mGridArray[x][y] = blackwhite;
	}

	public boolean checkWin(int wbflag) {
		for (int i = 0; i < GRID_SIZE; i++)
			// i表示列(根据宽度算出来的)
			for (int j = 0; j < GRID_SIZE; j++) {// i表示行(根据高度算出来的)
				// 检测横轴五个相连
				if (((i + 4) < (GRID_SIZE)) && (mGridArray[i][j] == wbflag)
						&& (mGridArray[i + 1][j] == wbflag)
						&& (mGridArray[i + 2][j] == wbflag)
						&& (mGridArray[i + 3][j] == wbflag)
						&& (mGridArray[i + 4][j] == wbflag)) {
					Log.e("check win or loss:", wbflag + " win");
					mWinFlag = wbflag;
				}

				// 纵轴5个相连
				if (((j + 4) < (GRID_SIZE)) && (mGridArray[i][j] == wbflag)
						&& (mGridArray[i][j + 1] == wbflag)
						&& (mGridArray[i][j + 2] == wbflag)
						&& (mGridArray[i][j + 3] == wbflag)
						&& (mGridArray[i][j + 4] == wbflag)) {
					Log.e("check win or loss:", wbflag + " win");
					mWinFlag = wbflag;
				}

				// 左上到右下5个相连
				if (((j + 4) < (GRID_SIZE)) && ((i + 4) < (GRID_SIZE))
						&& (mGridArray[i][j] == wbflag)
						&& (mGridArray[i + 1][j + 1] == wbflag)
						&& (mGridArray[i + 2][j + 2] == wbflag)
						&& (mGridArray[i + 3][j + 3] == wbflag)
						&& (mGridArray[i + 4][j + 4] == wbflag)) {
					Log.e("check win or loss:", wbflag + " win");
					mWinFlag = wbflag;
				}

				// 右上到左下5个相连
				if (((i - 4) >= 0) && ((j + 4) < (GRID_SIZE))
						&& (mGridArray[i][j] == wbflag)
						&& (mGridArray[i - 1][j + 1] == wbflag)
						&& (mGridArray[i - 2][j + 2] == wbflag)
						&& (mGridArray[i - 3][j + 3] == wbflag)
						&& (mGridArray[i - 4][j + 4] == wbflag)) {
					Log.e("check win or loss:", wbflag + " win");
					mWinFlag = wbflag;
				}
			}
		if (mWinFlag == wbflag) {
			return true;
		} else
			return false;

	}

	public boolean checkFull() {
		int mNotEmpty = 0;
		for (int i = 0; i < GRID_SIZE; i++)
			for (int j = 0; j < GRID_SIZE; j++) {
				if (mGridArray[i][j] != 0)
					mNotEmpty += 1;
			}

		if (mNotEmpty == GRID_SIZE*GRID_SIZE)
			return true;
		else
			return false;
	}

	public void showOverText(CharSequence mT) {

		AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity);
		builder.setIcon(android.R.drawable.ic_dialog_alert);
		builder.setTitle("游戏结束");
		builder.setMessage(mT);
		builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				// 这里添加点击确定后的逻辑
				reStartGame();
			}
		});
		builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				// 这里添加点击确定后的逻辑
				Toast.makeText(mainActivity, "单击返回按钮也可以重新开始", Toast.LENGTH_SHORT).show();
			}
		});
		builder.create().show();

	}

	public void setMainActivity(Activity mainActivity) {
		this.mainActivity = mainActivity;
	}

	/**
	 * @return 返回当前游戏状态
	 */
	public int getGameState() {
		return mGameState;
	}
}
