//接受直播信息或研讨
function getBoardX0()
{
	return getPos(chessboardsrc, "Left") + 13; //本处偏移量与xpos相同
}

function getBoardY0()
{
	return getPos(chessboardsrc, "Top") + 13;
}

//座子数量
function getFixedKoNumber()
{
	return fixedKoNumber;
}

//初始化：根据棋步数组生成显示棋子。使用动态div显示每个棋子。
//生成当前棋步指示（十字）
function initBoard()
{
	for(var index = 0; index < GostepArray.length; index++) {
		var gostep = GostepArray[index];
		gostep["pdiv"] = mkchessman(index, gostep.x, gostep.y, gostep.c, gostep.lv);
		gostep["pnumber"] = mkchessmannumber(index, gostep.x, gostep.y, gostep.c);
	}
	pmark = mkCurrentChessmanMark();
	///////pCoordinates = mkCoordinate();
	pLetterList = mkLetterList();
	
	for(index = 0; index < getFixedKoNumber(); index ++) {
		nextstep();
	}
}


//显示下一步
function nextstep()
{
	if(chessmannumber >= GostepArray.length - 1) return;
	chessmannumber++;
	var gostep = GostepArray[chessmannumber];
	var pdiv = gostep.pdiv;
	var valid = (gostep.x < BoardSize && gostep.y < BoardSize) && (gostep.x >= 0 && gostep.y >= 0);
	if(valid) pdiv.style.display = "";
	happenEated(chessmannumber);
	var eating = gostep["eating"];
	setMark(chessmannumber);
	if(displayNumber != 0) gostep.pnumber.style.display = (valid ? "" : "none");
	if(displayNumber == 2) {
		var prevNnumber = chessmannumber - displayLastNumber;
		if(prevNnumber >= 0) GostepArray[prevNnumber].pnumber.style.display = "none";
	}
	form1.currentStep.value = (chessmannumber+1) + (!valid ? "：弃权一步" : ': ' + (gostep.c == 1 ? "B" : "W") + "[" + getLetter(gostep.x) + (19-gostep.y) + "]");
	setComment(chessmannumber);
	displayLB(chessmannumber);
}

//显示下十步
function nextstep10()
{
	for(var i = 0; i < 10; i++) nextstep();
}

function prevstep()
{
	if(chessmannumber < getFixedKoNumber()) return;
	
	var gostep = GostepArray[chessmannumber];
	var pdiv = gostep.pdiv;
	if(pdiv) pdiv.style.display = "none";
	var pnumber = gostep.pnumber;
	if(pnumber) pnumber.style.display = "none";
	
	chessmannumber--;
	
	backStep(chessmannumber + 1); //如果有本步吃子，则重新显示出来
	
	setMark(chessmannumber);
	setComment(chessmannumber);
	displayLB(chessmannumber);
	displayHandNumber(chessmannumber - displayLastNumber + 1);
	
	if(chessmannumber >= 0) {
		gostep = GostepArray[chessmannumber];

		var valid = (gostep.x < BoardSize && gostep.y < BoardSize);
		form1.currentStep.value = (chessmannumber+1) + (!valid ? "：弃权一步" : ': ' + (gostep.c == 1 ? "B" : "W") + "[" + getLetter(gostep.x) + (19-gostep.y)) + "]";
	}
	else {
		form1.currentStep.value = '0: ';
	}
}

function displayHandNumber(num)
{
	if(num < getFixedKoNumber() || num >= GostepArray.length) return;
	
	var stp = GostepArray[num];
	var eatedby = stp.eatedby;

	var valid1 = (displayNumber == 1 || displayNumber == 2 && num > chessmannumber - displayLastNumber);
	var valid2 = (stp.x < BoardSize && stp.y < BoardSize && stp.x >= 0 && stp.y >= 0);
	var valid3 = (eatedby == null || eatedby >= chessmannumber);
	//alert(valid1 + ' ' + valid2 + ' ' + valid3);
	if(valid1 && valid2 && valid3) {
		stp.pnumber.style.display = "";
	}
	else {
		stp.pnumber.style.display = "none";
	}
}

function prevstep10()
{
	for(var i = 0; i < 10; i++) prevstep();
}

function firststep()
{
	var num = chessmannumber;
	for(var i = getFixedKoNumber(); i < num; i++) {
		prevstep();
	}
}

function laststep1()
{
	var num = GostepArray.length - chessmannumber - 1;
	for(var i = 0; i < num; i++) {
		nextstep();
	}
}

function gotostep(num)
{
	if(num < getFixedKoNumber() || num > GostepArray.length - 1) return;
	if(num == chessmannumber) return;
	if(num < chessmannumber) {
		while(num < chessmannumber) prevstep();
	}
	else {
		while(num > chessmannumber) nextstep();
	}
}

var timerHandle = null;

function laststep()
{
	if(timerHandle) clearInterval(timerHandle);
	if(chessmannumber >= GostepArray.length - 1) return;
	timerHandle = setInterval("continueNextstep()", 1);
}

function continueNextstep()
{
	if(chessmannumber >= GostepArray.length - 1) {
		clearInterval(timerHandle);
		timerHandle = null;
		return;
	}
	
	nextstep10();
}

function autostep()
{
	if(timerHandle) {
		clearInterval(timerHandle);
		timerHandle = null;
		return;
	}

	timerHandle = null;
	if(chessmannumber >= GostepArray.length - 1) {
		stopAutoStep();
		firststep();
		prevstep();
	}
	nextstep();
	var interval = form1.autostepvalue.value * 1000;
	timerHandle = setInterval("autoNextstep()", interval);
}

function autoNextstep()
{
	if(chessmannumber >= GostepArray.length - 1) {
		if(timerHandle) clearInterval(timerHandle);
		timerHandle = null;
		return;
	}
	nextstep();
}

function stopAutoStep()
{
	if(timerHandle) {
		clearInterval(timerHandle);
		timerHandle = null;
		return;
	}
}

//删除最后一步
function deletelaststep()
{
	if(GostepArray.length == 0) return;
	
	freshManual();
	prevstep();
	var num = GostepArray.length - 1
	pdiv = GostepArray[num].pdiv;
	pdiv.parentNode.removeChild(pdiv); 
	pdiv = GostepArray[num].pnumber;
	pdiv.parentNode.removeChild(pdiv); 
	
	GostepArray[num] = null;
	GostepArray.length --;
	table2.rows.item(5).cells.item(1).innerHTML = GostepArray.length + "手";
	for(var i = 0; i < GostepArray.length; i++) {
		gostep = GostepArray[i];
		if(gostep.eatedby != null && gostep.eatedby == num) gostep.eatedby = null;
	}
}

//删除所有参考步（未发布步）
function deleteallunstep()
{
	if(GostepArray.length == 0) return;
	for(var num = GostepArray.length - 1; num >= 0; num--) {
		var stp = GostepArray[num];
		if(stp.lv == 1) return;
		deletelaststep();
	}
}

//删除字母表最后一个字母或最后一个参考步（未发布步）
function deletelastunstep()
{
	if(GostepArray.length == 0) return;
	for(var num = GostepArray.length - 1; num >= 0; num--) {
		var stp = GostepArray[num];
		if(stp.lv == 1) return;
		deletelaststep();
	}
}

function freshManual()
{
	for(var i = chessmannumber + 1; i < GostepArray.length; i++) nextstep();
}

function setComment(num)
{
	if(num < 0 || num >= GostepArray.length) form1.Comment.value = "";
	else form1.Comment.value = GostepArray[num].comment;
}

//生成棋子，用于显示
function mkchessman(num, i, j, color, lv)
{
	var chessmanname = 'chessman_' + num;
	var pdiv = document.all[chessmanname];
	if(!pdiv) pdiv = document.createElement('div');

	var stp = GostepArray[num];
	//var newText = document.createTextNode('');
	pdiv.id = chessmanname;
	pdiv.className = chessmanname;
	pdiv.setAttribute('name', chessmanname);
	pdiv.style.width = xspace + 'px';
	pdiv.style.height = yspace + 'px';
	pdiv.style.left = rxpos + i * xspace + 8 + 'px';
	pdiv.style.top = rypos + j * yspace + 8 + 'px';
	pdiv.style.margin = '0 auto';
	pdiv.style.border = '0px solid #DDD';
	pdiv.style.position = 'absolute';//'relative';
	pdiv.style.zIndex = zpos + 1;
	pdiv.style.display = 'none';
	//pdiv.appendChild(newText);
	chessboardground.appendChild(pdiv);
	//document.body.appendChild(pdiv);
	setConfirmImg(pdiv, lv, color);

	return pdiv;
}

function setConfirmImg(pdiv, lv, color)
{
	if(color == "black" || color == "Black" || color == "b" || color == "B" || color == 1) {
		pdiv.innerHTML = lv == 1 ? div_black_img : div_black_img_un;
	}
	else {
		pdiv.innerHTML = lv == 1 ? div_white_img : div_white_img_un;
	}
}

function setConfirm(num)
{
	if(num >= GostepArray.length) return;

	var stp = GostepArray[num];
	setConfirmImg(stp.pdiv, stp.lv, stp.c);
}

//生成当前棋步指示
function mkCurrentChessmanMark()
{
	var pdiv = document.createElement('div');
	var newText = document.createTextNode('');
	pdiv.id = 'current_mark';
	pdiv.className = 'current_mark';
	pdiv.setAttribute('name', 'current_mark');
	pdiv.style.width = '12px';
	pdiv.style.height = '12px';
	pdiv.style.left = rxpos + 'px';
	pdiv.style.top = rypos + 'px';
	pdiv.style.margin = '0 auto'; 
	pdiv.style.border = '0px solid #DDD';
	pdiv.style.position = 'absolute';
	pdiv.style.zIndex = 102;
	pdiv.style.display = 'none';
	pdiv.appendChild(newText);
	//document.body.appendChild(pdiv);
	chessboardground.appendChild(pdiv);
	pdiv.innerHTML = "<img src='images/flash10.gif' border=0>";
	
	return pdiv;
}

function setMark(chessmannumber)
{
	if(chessmannumber < 0 || chessmannumber >= GostepArray.length) {
		pmark.style.display = "none";
		return;
	}
	var gostep = GostepArray[chessmannumber];
	var i = gostep.x;
	var j = gostep.y;
	if(i < BoardSize && j < BoardSize) {
		pmark.style.left = (rxpos + i * xspace + 17) + "px";
		pmark.style.top = (rypos + j * yspace + 16) + "px";
		pmark.style.display = "";
	}
	else {
		pmark.style.display = "none";
	}
	//form1.Shell.value = "setMark:" + chessmannumber + ",(" + i + "," + j + "),(" + pmark.style.left + "," + pmark.style.left + ")";
}

//生成字母列表（围棋解说中提到的A,B,C等）
function mkLetterList()
{
	var LB = new Array();
	
	for(var i = 0; i < 20; i++) {
		var letter = getLetter(i).toLowerCase();

		var id = 'LB_' + letter;
		var pdiv = document.createElement('div');
		//var newText = document.createTextNode('');
		pdiv.id = id;
		pdiv.className = id;
		pdiv.setAttribute('name', id);
		//pdiv.style = 'background-color:#FFFFFF;filter:alpha(opacity=50,Style=0);';
		pdiv.style.width = '20px';
		pdiv.style.height = '20px';
		pdiv.style.left = rxpos + 'px';
		pdiv.style.top = rypos + 'px';
		pdiv.style.margin = '0 auto';
		pdiv.style.border = '0px solid #DDD';
		pdiv.style.position = "absolute";
		pdiv.style.zIndex = 103;
		pdiv.style.display = "none";
		//pdiv.appendChild(newText);
		//document.body.appendChild(pdiv);
		chessboardground.appendChild(pdiv);
		pdiv.innerHTML = "<span onclick='BoardClickedFunction()'><font size=5 color=112233><b>" + letter + "</b></font></span>";

		LB[i] = pdiv;
	}
	
	return LB;
}

var old_manualLB = null;

//显示字母列表
function displayLB(num)
{
	if(num < 0 || num >= GostepArray.length) return;
	
	manualLB = GostepArray[num].LB;
	var old_size = 0, size = manualLB.length;
	if(old_manualLB != null) old_size = old_manualLB.length;
	
	var number = size;
	if(number < old_size) number = old_size;
	for(var i = 0; i < number; i++) {
		var pLetter = pLetterList[i];
		if(i >= size) {
			pLetter.style.display = "none";
		}
		else {
			var pL = manualLB[i];
			pLetter.style.left = rxpos + pL.x * xspace + 25;
			pLetter.style.top = rypos + pL.y * yspace + 19;
			pLetter.style.display = "";
		}
	}
	
	old_manualLB = manualLB;
}

//隐藏字母列表，目前只用于删除字母时临时隐藏
function hideLB(num)
{
	if(num < 0 || num >= GostepArray.length) return;
	
	for(var i = 0; i < pLetterList.length; i++) {
		var pLetter = pLetterList[i];
		pLetter.style.display = "none";
	}
}

function getLetter(index)
{
	var letters = "ABCDEFGHJKLMNOPQRST"; //GNUGO不使用I
	return letters.substring(index, ++index);
}

//生成棋盘坐标
function mkCoordinate()
{
	var letters = "ABCDEFGHJKLMNOPQRST"; //GNUGO不使用I
	var obj = new Array();

	var index = 0;
	for(var i = 0; i < BoardSize; i++) { //上边
		var i1 = i; i1++;
		var letter = letters.substring(i, i1);
		obj[index++] = mkCoordinatePoint(xspace * i + 24, -4, letter);
	}

	for(var i = 0; i < BoardSize; i++) { //下边
		var i1 = i; i1++;
		var letter = letters.substring(i, i1);
		obj[index++] = mkCoordinatePoint(xspace * i + 24, boardheight + 9, letter);
	}
	
	for(var j = 0; j < BoardSize; j++) { //左边
		var j1 = BoardSize - j;
		obj[index++] = mkCoordinatePoint(-4 + (j1 < 10 ? 4 : 0), yspace * j + 20, j1);
	}

	for(var j = 0; j < BoardSize; j++) { //右边
		var j1 = BoardSize - j;
		obj[index++] = mkCoordinatePoint(10 + (j1 < 10 ? 4 : 0) + boardwidth, yspace * j + 18, j1);
	}
	
	return obj;
}

function mkCoordinatePoint(x, y, str)
{
	var cname = "CD_" + x + "_" + y;
	
	var pdiv = document.createElement('div');
	//var newText = document.createTextNode('');
	pdiv.id = cname;
	pdiv.className = cname;
	pdiv.setAttribute('name', cname);
	pdiv.style.width = '14px';
	pdiv.style.height = '14px';
	pdiv.style.left = rxpos + x + 'px';
	pdiv.style.top = rypos + y + 'px';
	pdiv.style.margin = '0 auto';
	pdiv.style.border = '0px solid #DDD';
	pdiv.style.position = "absolute";
	pdiv.style.zIndex = 99;
	pdiv.style.display = "none";
	//pdiv.appendChild(newText);
	//document.body.appendChild(pdiv);
	chessboardground.appendChild(pdiv);
	pdiv.innerHTML = "<font size=2>" + str + "</font>";

	return pdiv;
}

function displayCoordinates()
{
	if(pCoordinates == null) return;
	for(var i = 0; i < pCoordinates.length; i++) {
		var Coordinate = pCoordinates[i];
		Coordinate.style.display = "";
	}
}

function hideCoordinates()
{
	if(pCoordinates == null) return;
	for(var i = 0; i < pCoordinates.length; i++) {
		var Coordinate = pCoordinates[i];
		Coordinate.style.display = "none";
	}
}

function viewCoordinate(visible)
{
	if(visible) displayCoordinates();
	else hideCoordinates();
}

//生成落子手数标记
function mkchessmannumber(num, i, j, color)
{
	var num1 = num - getFixedKoNumber();
	num1++;

	var dx = 0;
	if(num1 < 10) dx = 17;
	else if(num1 < 100) dx = 14;
	else dx = 11;

	var chessmanname = "cmnum_" + num1;
	
	var pdiv = document.createElement('div');
	//var newText = document.createTextNode('');
	pdiv.id = chessmanname;
	pdiv.className = chessmanname;
	pdiv.setAttribute('name', chessmanname);
	pdiv.style.width = xspace + 'px';
	pdiv.style.height = yspace + 'px';
	pdiv.style.left = rxpos + i * xspace + dx + 6 + 'px';
	pdiv.style.top = rypos + j * yspace + 18 + 'px';
	pdiv.style.margin = '0 auto';
	pdiv.style.border = '0px solid #DDD';
	pdiv.style.position = "absolute";
	pdiv.style.zIndex = 101;
	pdiv.style.display = "none";
	//pdiv.appendChild(newText);
	//document.body.appendChild(pdiv);
	chessboardground.appendChild(pdiv);
	pdiv.innerHTML = "<font size=2 color="+(color==1?"white":"black")+">" + num1 + "</font>";

	return pdiv;
}

function displayChessmanNumber()
{
	var dnumber = chessmannumber - displayLastNumber;
	for(var i = 0; i <= chessmannumber; i++) {
		var gostep = GostepArray[i];
		var pnumber = gostep.pnumber;
		var eatedby = gostep.eatedby;
		var valid = (gostep.x < BoardSize && gostep.y < BoardSize) && (gostep.x >= 0 && gostep.y >= 0);
		if((displayNumber == 1 || displayNumber == 2 && i > dnumber) && i >= getFixedKoNumber() && valid) {
			pnumber.style.display = "";
		}
		else {
			pnumber.style.display = "none";
		}
		if(eatedby != null && eatedby <= chessmannumber) pnumber.style.display = "none";
	}
}

function hideChessmanNumber()
{
	for(var i = 0; i <= chessmannumber; i++) {
		var gostep = GostepArray[i];
		gostep.pnumber.style.display = "none";
	}
}

function viewpnumber(visible)
{
	form1.pnumberN.checked = false;
	
	if(visible) displayNumber = 1; else displayNumber = 0;
	if(visible) displayChessmanNumber();
	else hideChessmanNumber();
}

function viewpnumberN(visible)
{
	form1.pnumber.checked = false;
	form1.pnumberN.checked = visible;
	
	if(visible) {
		displayNumber = 2;
	}
	else {
		displayNumber = 0;
	}
	
	if(visible) {
		displayChessmanNumber();
	}
	else {
		hideChessmanNumber();
	}
}

function getPos(el, ePro)    /// Get Absolute Position
{
	var ePos = 0;

	while(el != null) {
		ePos += el["offset" + ePro];
		el = el.offsetParent;
	}

	return ePos;
}

//读取棋谱
function getChessManual()
{
	var steps = jaxaction("getChessManualInlive", id);
	for(var i = 0; i < steps.length; i++) {
		stp = steps[i];
  		stp.lv = 1; //确定时为1
	}

	return steps;
}

//读取直播状态
function getMatchInliveState()
{
	var state = jaxaction("getMatchInliveState", id);

	if(state == 0) document.all["radio0"].checked = true;
	if(state == 1) document.all["radio1"].checked = true;
	if(state == 2) document.all["radio2"].checked = true;
	
	return state;
}

//读取直播信息
function getMatchInliveInfor()
{
	var mi = jaxaction("getMatchInliveInfor", id);

	var state = mi[0].state;
	if(state == 0) document.all["radio0"].checked = true;
	if(state == 1) document.all["radio1"].checked = true;
	if(state == 2) document.all["radio2"].checked = true;

	table2.rows.item(4).cells.item(1).innerHTML = mi[0].state == 0 ? mi[0].resultString : "...";
	
	return state;
}

//设置直播状态
function setMatchInliveState(state)
{
	var state = jaxaction("setMatchInliveState", id, state);
	getMatchInliveState();
}

//处理回退中被吃子的重新显示
function backStep(num)
{
	var gostep = GostepArray[num];
	var eated = gostep["eating"];
	if(eated != null) {
		for(var i = 0; i < eated.length; i++) {
			var eatedstp = eated[i];
			eatedstp.pdiv.style.display = ""; //显示被吃子
			for(var j = 0; j < GostepArray.length; j++) {
				if(eatedstp === GostepArray[j]) break;
			}
			displayHandNumber(j);
			//if(displayNumber == 1) eatedstp.pnumber.style.display = "";
		}
	}
}

//处理落子吃子
var currentstep = 0;
function happenEated(n)
{
	var gostep = GostepArray[n];
	debuginfor("Step " + n + ": " + gostep.x + "," + gostep.y + "," + (gostep == 1 ? "Black" : "White") + "\r\n");

	var eated = gostep["eating"];
	eated = null;
	if(eated != null) {
		debuginforadd("eating 实现处理好\r\n");
		for(var i = 0; i < eated.length; i++) {
			var eatedstp = eated[i];
			eatedstp.pdiv.style.display = "none"; //隐藏被吃子
			eatedstp.pnumber.style.display = "none"; //隐藏被吃子
		}
		return;
	}

	currentstep = n;
	
	debuginforadd("获取被吃子的集合\r\n");
	//获取被吃子的集合
	var obj = processEated(gostep.x, gostep.y, gostep.c == 1 ? 2 : 1);
	if(obj == null) {
		debuginforadd("被吃子的集合为空\r\n");
		return;
	}
	
	eated = new Array();
	var mindex = 0;
	for(var prop in obj) {   //把被吃子集合转换成数组，把该数组赋给该落子
		var gstp = obj[prop];
		eated[mindex++] = gstp;
		gstp["eatedby"] = n; //在被吃子中记录被谁吃的
		gstp.pdiv.style.display = "none"; //隐藏被吃子
		gstp.pnumber.style.display = "none"; //隐藏被吃子
	}
	gostep["eating"] = eated;
}

//判断(i,j)处落一子后是否有棋子被吃
//c为与落子相反的颜色。即：落黑子后判断是否有白子被吃（注解以此为例）。
function processEated(i, j, c)
{
	var obj1 = new Object();
	var obj2 = new Object();
	var obj3 = new Object();
	var obj4 = new Object();

	var i1 = i, j1 = j
	i1++;
	j1++;

	if(i > 0) {
		collectChessman(obj1, i - 1, j, c); //收集左侧白色棋子集合
		debuginforadd("左侧：" + objtoString(obj1) + "\r\n");

		if(objHaveHole(obj1)) {
			obj1 = null;  //如果左侧白子棋子集合有气，则不被吃
			debuginforadd("左侧未吃。\r\n");
		}
	}
	if(j > 0) {
		collectChessman(obj2, i, j - 1, c); //上侧
		debuginforadd("上侧：" + objtoString(obj2) + "\r\n");
		if(objHaveHole(obj2)) {
			obj2 = null;
			debuginforadd("上侧未吃。\r\n");
		}
	}
	if(i < BoardSize - 1) {
		collectChessman(obj3, i1, j, c); //右侧
		debuginforadd("右侧：" + objtoString(obj3) + "\r\n");
		if(objHaveHole(obj3)) {
			obj3 = null;
			debuginforadd("右侧未吃。\r\n");
		}
	}
	if(j < BoardSize - 1) {
		collectChessman(obj4, i, j1, c); //下侧
		debuginforadd("下侧：" + objtoString(obj4) + "\r\n");
		if(objHaveHole(obj4)) {
			obj4 = null;
			debuginforadd("下侧未吃。\r\n");
		}
	}
	
	//debuginforadd(37 + " - " + steps[37].x + " " + steps[37].y + " " + steps[37].c);

	if(obj1 == null && obj2 == null && obj3 == null && obj4 == null) return null;
	
	var obj = new Object();

	if(obj1 != null) for(var prop in obj1) obj[prop] = obj1[prop];//把四个方向可能的没有气的白子集合合并成一个集合
	if(obj2 != null) for(var prop in obj2) obj[prop] = obj2[prop];
	if(obj3 != null) for(var prop in obj3) obj[prop] = obj3[prop];
	if(obj4 != null) for(var prop in obj4) obj[prop] = obj4[prop];
	
	return obj;
}

//以(i,j)为中心收集同色棋子，形成同色棋子集obj
//obj须在调用程序中以obj = new Object()生成
//(i,j)处必须落子(c)
function collectChessman(obj, i, j, c)
{
	var gostp = getGostep(i, j);
	if(gostp == null || gostp.c != c) return;
	obj[i+"_"+j] = gostp;

	var i1 = i, j1 = j; //3+1不等于4，等于31。害我浪费半天功夫
	i1++;
	j1++;

	if(i > 0) {
		if(obj[(i-1)+"_"+j] == null) collectChessman(obj, i - 1, j, c);
	}
	if(j > 0) {
		if(obj[i+"_"+(j-1)] == null) collectChessman(obj, i, j - 1, c);
	}
	if(i < BoardSize - 1) {
		if(obj[i1+"_"+j] == null) collectChessman(obj, i1, j, c);
	}
	if(j < BoardSize - 1) {
		if(obj[i+"_"+j1] == null) collectChessman(obj, i, j1, c);
	}
}

//判断某同色棋子集是否还有气：—如果有任意一子有气，则视为有气
function objHaveHole(obj)
{
	for(var prop in obj) { //prop的格式：3_5
		var gostp = obj[prop];
		var p = prop.indexOf("_");
		var i = prop.substring(0, p);
		var j = prop.substring(p + 1);
		if(manHasHole(i, j)) return true;
	}
	return false;
}

//判断某落点是否还有气：—如果周围全部有棋子则视为无气
function manHasHole(i, j)
{
	var i1 = i, j1 = j
	i1++; j1++;

	if(i > 0) {
		if(getGostepColor(i - 1, j) == 0) return true;
	}
	if(j > 0) {
		if(getGostepColor(i, j - 1) == 0) return true;
	}
	if(i < BoardSize - 1) {
		if(getGostepColor(i1, j) == 0) return true;
	}
	if(j < BoardSize - 1) {
		if(getGostepColor(i, j1) == 0) return true;
	}
	return false;
}


//************************************************************************
//以下函数判断落子合法性

//判断某落点是否还有气：—如果周围全部有棋子则视为无气，假设(i0,j0)处已有落子
function manHasHoleEx(i, j, i0, j0)
{
	var i1 = i, j1 = j
	i1++; j1++;

	if(i > 0) {
		if(i0 != i - 1 && j != j0 && getGostepColor(i - 1, j) == 0) return true;
	}
	if(j > 0) {
		if(i != i0 && j0 != j - 1 && getGostepColor(i, j - 1) == 0) return true;
	}
	if(i < BoardSize - 1) {
		if(i1 != i0 && j != j0 && getGostepColor(i1, j) == 0) return true;
	}
	if(j < BoardSize - 1) {
		if(i != i0 && j1 != j0 && getGostepColor(i, j1) == 0) return true;
	}
	return false;
}

//判断某同色棋子集是否还有气：—如果有任意一子有气，则视为有气
//假设(i0,j0)处已有落子
function objHaveHoleEx(obj, i0, j0)
{
	for(var prop in obj) { //prop的格式：3_5
		var gostp = obj[prop];
		var p = prop.indexOf("_");
		var i = prop.substring(0, p);
		var j = prop.substring(p + 1);
		if(manHasHoleEx(i, j, i0, j0)) return true;
	}
	return false;
}

//棋子集是否为空
function objEmpty(obj)
{
	for(var prop in obj) { //prop的格式：3_5
		return false;
	}
	return true;
}

//位置(i,j)处可否落子(颜色为c)，注解以c=1黑色为例
function canMove(i, j, c)
{
	var gostp = getGostep(i, j);
	if(gostp != null) return {result:false, msg:"该处已有落子"};
	
	if(manHasHole(i, j)) return {result:true, msg:"该处有气(c=" + c + ")"};
	
	var i1 = i, j1 = j
	i1++; j1++;
	
	var obj = new Object();
	if(i > 0) collectChessman(obj, i - 1, j, c); //收集左侧颜色为c的同色棋子集
	if(j > 0) collectChessman(obj, i, j - 1, c); //收集上侧颜色为c的同色棋子集
	if(i < BoardSize - 1) collectChessman(obj, i1, j, c); //收集右侧颜色为c的同色棋子集
	if(j > BoardSize - 1) collectChessman(obj, i, j1, c); //收集下册侧颜色为c的同色棋子集
	
	if(objHaveHoleEx(obj, i, j)) return {result:true, msg:"落子后己方（同色棋子集）还有气，可落"};
	
	var vc = 3 - c; //另一色，白色
	var vcs = vc == 1 ? "黑" : "白";
	if(i > 0) {
		obj = new Object();
		collectChessman(obj, i - 1, j, vc); //收集左侧白色的同色棋子集
		if(!objEmpty(obj) && !objHaveHoleEx(obj, i, j)) return {result:true, msg:"左侧"+vcs+"棋被杀，可落" + objtoString(obj)};
	}
	if(j > 0) {
		obj = new Object();
		collectChessman(obj, i, j - 1, vc); //收集上侧白色的同色棋子集
		if(!objEmpty(obj) && !objHaveHoleEx(obj, i, j)) return {result:true, msg:"上侧"+vcs+"棋被杀，可落" + objtoString(obj)};
	}
	if(i < BoardSize - 1) {
		obj = new Object();
		collectChessman(obj, i1, j, vc); //收集右侧白色的同色棋子集
		if(!objEmpty(obj) && !objHaveHoleEx(obj, i, j)) return {result:true, msg:"右侧"+vcs+"棋被杀，可落" + objtoString(obj)};
	}
	if(j < BoardSize - 1) {
		obj = new Object();
		collectChessman(obj, i, j1, vc); //收集右侧白色的同色棋子集
		if(!objEmpty(obj) && !objHaveHoleEx(obj, i, j)) return {result:true, msg:"下侧"+vcs+"棋被杀，可落" + objtoString(obj)};
	}
	return {result:false, msg:"无气，且不能杀"+vcs+"棋，非法"};
}
//*****************************************************************************



//调试用
function objtoString(obj)
{
	var str = "";
	for(var i = 0; i < BoardSize; i++) {
		for(var j = 0; j < BoardSize; j++) {
			var gstp = obj[i+"_"+j];
			if(gstp != null) {
				str += "("+i+","+j+") ";
			}
		}
	}
	return str;
}

//获取指定坐标处的棋子。倒序:-考虑被吃的棋子。如果一个棋子下在已经提过棋子的位置，则应返回后者
function getGostep(i, j)
{
	for(var n = currentstep; n >= 0; n--) {
		var gostp = GostepArray[n];
		if(gostp.x == i && gostp.y == j) {
			var eatedgostp = gostp["eatedby"];
			if(eatedgostp != null && parseInt(eatedgostp) < currentstep) return null;
			return gostp;
		}
	}
	return null;
}

//获取指定坐标处棋子的颜色（黑白无）
function getGostepColor(i, j)
{
	for(var n = currentstep; n >= 0; n--) {
		var gostp = GostepArray[n];
		if(gostp.x == i && gostp.y == j) {
			var eatedgostp = gostp["eatedby"];
			if(eatedgostp != null && parseInt(eatedgostp) < currentstep) return 0;
			return gostp.c;
		}
	}
	return 0;
}

//左键点击棋盘后，相当于投下一子
//如果Ctrl-左键，则设置一个字母，用于解说引用
function BoardClickedFunction()
{
	var e;

	if(document.all) {
		cx = event.clientX;
		cy = event.clientY;
	}
	else {
		cx = evnt.clientX;
		cy = evnt.clientY;
	}
	
	var scrl = getPageScroll();
	cx += scrl.X;
	cy += scrl.Y;
	
	cx -= getBoardX0();
	cy -= getBoardY0();
	//alert(cx + "," + cy);
	
	var mx = Math.round(cx / xspace) - 1;
	var my = Math.round(cy / yspace) - 1;
	
	if(mouseDownWithCtrl(e)) { //Ctrl-鼠标左键
		if(chessmannumber < 0 || chessmannumber >= GostepArray.length) return;
		hideLB(chessmannumber);
		var stp = GostepArray[chessmannumber];
		var index = hasLetter(stp, mx, my);
		if(index > -1) {
			deleteLetter(stp, index);
		}
		else {
			registerLB(stp, mx, my);
		}
		displayLB(chessmannumber);
		//alert(GostepArray[chessmannumber].LB.length);
		return;
	}
	
	freshManual();
	currentstep = GostepArray.length - 1;
	var color = getGostepColor(mx, my);
	if(color != 0) return;
	
	//var laststp = GostepArray[GostepArray.length - 1];
	var mc = getLetter(mx) + getLetter(my);
	var stp = new Object();
	stp.c = GostepArray.length > 0 ? 3 - GostepArray[GostepArray.length - 1].c : 1;
	stp.x = mx;
	stp.y = my;
	stp.comment = '';
	stp.LB = new Array();
	stp.lv = 0;
	
	stp["pdiv"] = mkchessman(GostepArray.length, stp.x, stp.y, stp.c, stp.lv);
	stp["pnumber"] = mkchessmannumber(GostepArray.length, stp.x, stp.y, stp.c);

	var num = GostepArray.length;
	GostepArray[num] = stp;
	table2.rows.item(5).cells.item(1).innerHTML = GostepArray.length + "手";
	
	freshManual();
}

//判断指定位置是否有字母，并返回下标
function hasLetter(stp, mx, my)
{
	if(stp.LB == null) return -1;
	for(i = 0; i < stp.LB.length; i++) {
		if(stp.LB[i].x == mx && stp.LB[i].y == my) {
			return i;
		}
	}
	return -1;
}

//删除指定下标的字母。如果只有一个字母，则置LB为空
function deleteLetter(stp, index)
{
	if(stp.LB == null) return;
	if(stp.LB.length == 1 && index == 0) {
		stp.LB = new Array();
		return;
	}
	deleteItemFromArray(stp.LB, index);
	for(num = index; num < stp.LB.length; num++) {
		stp.LB[num].Letter = getLetter(num).toLowerCase();
	}
}

function registerLB(stp, mx, my)
{
	var L = new Object();
	L.x = mx;
	L.y = my;
	L.Letter = 'a';
	
	if(stp.LB == null) {
		stp.LB = new Array();
		stp.LB[0] = L;
		return;
	}
	
	L.Letter = getLetter(stp.LB.length).toLowerCase();
	stp.LB[stp.LB.length] = L;
}

function deleteItemFromArray(array, num)
{
	if(array.length == 0) return;
	
	for(var i = num; i < array.length - 1; i++) {
		array[i] = array[i + 1];
	}
	//array[array.length - 1] = null;
	array.length --;
}

//点击事件是否按下Ctrl键
function mouseDownWithCtrl(e)
{
	if(parseInt(navigator.appVersion)>3) {   
	    if(navigator.appName=="Netscape") {   
			var mString = (e.modifiers + 32).toString(2).substring(3, 6);
			return (mString.charAt(1) == "1");
		}
		else {
			return event.ctrlKey;   
		}   
	}
	return false;
}

//点击事件是否按下Shift键
function mouseDownWithShift(e)
{
	if(parseInt(navigator.appVersion) > 3) {
	    if(navigator.appName == "Netscape") {
			var mString = (e.modifiers + 32).toString(2).substring(3, 6);
			return (mString.charAt(0) == "1");
		}
		else {
			return event.shiftKey;
		}
	}
	return false;
}

//点击事件是否按下Alt键
function mouseDownWithAlt(e)
{
	if(parseInt(navigator.appVersion) > 3) {
	    if(navigator.appName == "Netscape") {
			var mString = (e.modifiers + 32).toString(2).substring(3, 6);
			return (mString.charAt(2) == "1");
		}
		else {
			return event.altKey;
		}
	}
	return false;
}

//解说框变更时保存
function CommentChangedFunction()
{
	if(chessmannumber < 0 && chessmannumber >= GostepArray.length) return;
	GostepArray[chessmannumber].comment = form1.Comment.value;
}

//保存并发布，完成直播
function saveManual()
{
	var manual = new Gobject();
	var manualString = JSON.stringify(manual);
	var result = jaxaction("updateInlive", "<%=id%>", manualString, "<%=user.getID()%>");

	if(result == "OK") {
	alert("[" + result + "]");
		for(var i = 0; i < GostepArray.length; i++) {
			var stp = GostepArray[i];
			if(stp.lv == 1) continue;
			stp.lv = 1;
			setConfirmImg(stp.pdiv, 1, stp.color)
		}
	}
}

//由saveManual调用，用于生成棋步数据字符串:-只保留最需要的数据
function Gobject()
{
	for(var i = 0; i < GostepArray.length; i++) {
		this[i] = new Object();
		this[i].x = GostepArray[i].x;
		this[i].y = GostepArray[i].y;
		this[i].c = GostepArray[i].c;
		this[i].comment = GostepArray[i].comment;
		this[i].LB = GostepArray[i].LB;
	}
}

function debuginfor(infor)
{
	if(!debuginfordisplay) return;
	form1.Content.value = infor;
}

function debuginforadd(infor)
{
	if(!debuginfordisplay) return;
	form1.Content.value += infor;
}

//直播棋局状态设定
function setMatchstate()
{
	var state0 = document.all["radio0"].checked;
	var state1 = document.all["radio1"].checked;
	var state2 = document.all["radio2"].checked;
	var state = state0 ? 0 : (state1 ? 1 : 2);
	setMatchInliveState(state);
	if(state1) {
		form1.deletelaststepb.disabled = false;
		form1.deleteallunstepb.disabled = false;
		//form1.updateInlive.disabled = false;
	}
	else {
		form1.deletelaststepb.disabled = true;
		form1.deleteallunstepb.disabled = true;
		//form1.updateInlive.disabled = true;
	}
}

function turninlive(lv)
{
	isinlive = lv;
	form1.inlive.checked = lv;
	if(lv) refreshManual();
}

function turnoffinlive()
{
	isinlive = false;
	form1.inlive.checked = false;
}


function refreshManual()
{
	getMatchInliveInfor();
	if(!isinlive) return;
	
	var steps = getChessManual();
	var num = steps.length;
	if(num < GostepArray.length) {
		while(num < GostepArray.length) {
			deletelaststep();
		}
	}
	
	for(var i = 0; i < GostepArray.length; i++) {
		var stp1 = GostepArray[i];
		var stp2 = steps[i];
		if(stp1.c != stp2.c || stp1.x != stp2.x || stp1.y != stp2.y) {
			break;
		}
	}
	
	while(i < GostepArray.length) deletelaststep();
	for(i = GostepArray.length; i < num; i++) {
		var stp = steps[i];
		stp.lv = 1;
		stp["pdiv"] = mkchessman(i, stp.x, stp.y, stp.c, stp.lv);
		stp["pnumber"] = mkchessmannumber(i, stp.x, stp.y, stp.c);

		GostepArray[i] = stp;
		table2.rows.item(5).cells.item(1).innerHTML = GostepArray.length + "手";
	}
	gotostep(num - 1);
}

function getPageScroll() 
{
	var x, y;
	if(window.pageYOffset)
	{    // all except IE
		y = window.pageYOffset;   
		x = window.pageXOffset;
	}
	else if(document.documentElement && document.documentElement.scrollTop)
	{    // IE 6 Strict
		y = document.documentElement.scrollTop;   
		x = document.documentElement.scrollLeft;
	}
	else if(document.body) {    // all other IE    
		y = document.body.scrollTop;
		x = document.body.scrollLeft;
	}
	return {X:x, Y:y};
}


