/******************************************************************
 *						Author:	Zhou Yundong
 *						Time: 20080425 20:49
 ******************************************************************/
#include "Stdafx.h"
#include "Think.h"

int nowIdx;
bool bodyIdx[81];
bool edge[180];
int colorIdx; // 第8,9位是1:单色，第8,9位是0:多色 000000000 100000000 意义：在不丢失顺序的情况下，记录单色

void initialSosum()
{
	movePare('0', 'l'); // 0 to leftPare
	moveKilpare('0', 'l'); // 0 to killerPare
	moveExtra('0', 'l'); // 0 to leftExtra
	moveSaw('0', 'l'); // 0 to leftSaw
	editKind = 1;
	gameKind = 1;
}

void moveSum(char from, char to)
{
	int i;
	if(from == '0' && to == 'l')
	{
		for(i=0; i<81; i++)
		{
			leftSum[i] = 0;
		}
	}
	else if(from == '0' && to == 'r')
	{
		for(i=0; i<81; i++)
		{
			rightSum[i] = 0;
		}
	}
	else if(from == 'l' && to == 'r')
	{
		for(i=0; i<81; i++)
		{
			rightSum[i] = leftSum[i];
		}
	}
	else if(from == 'r' && to == 'l')
	{
		for(i=0; i<81; i++)
		{
			leftSum[i] = rightSum[i];
		}
	}
	else if(from == 'l' && to == 's')
	{
		for(i=0; i<81; i++)
		{
			sum[i] = leftSum[i];
		}
	}
}

void moveIdx(char from, char to)
{
	int i;
	if(from == '0' && to == 'l')
	{
		for(i=0; i<81; i++)
		{
			leftIdx[i] = 0;
		}
	}
	else if(from == '0' && to == 'r')
	{
		for(i=0; i<81; i++)
		{
			rightIdx[i] = 0;
		}
	}
	else if(from == 'l' && to == 'r')
	{
		for(i=0; i<81; i++)
		{
			rightIdx[i] = leftIdx[i];
		}
	}
	else if(from == 'r' && to == 'l')
	{
		for(i=0; i<81; i++)
		{
			leftIdx[i] = rightIdx[i];
		}
	}
	else if(from == 'l' && to == 'i')
	{
		for(i=0; i<81; i++)
		{
			idx[i] = leftIdx[i];
		}
	}
}

void moveHead(char from, char to)
{
	int i;
	if(from == '0' && to == 'l')
	{
		for(i=0; i<81; i++)
		{
			leftHead[i] = 0;
		}
	}
	else if(from == '0' && to == 'r')
	{
		for(i=0; i<81; i++)
		{
			rightHead[i] = 0;
		}
	}
	else if(from == 'l' && to == 'r')
	{
		for(i=0; i<81; i++)
		{
			rightHead[i] = leftHead[i];
		}
	}
	else if(from == 'r' && to == 'l')
	{
		for(i=0; i<81; i++)
		{
			leftHead[i] = rightHead[i];
		}
	}
}

void moveUniq(char from, char to)
{
	int i;
	if(from == '0' && to == 'l')
	{
		for(i=0; i<81; i++)
		{
			leftUniq[i] = false;
		}
	}
	else if(from == '0' && to == 'r')
	{
		for(i=0; i<81; i++)
		{
			rightUniq[i] = false;
		}
	}
	else if(from == 'l' && to == 'r')
	{
		for(i=0; i<81; i++)
		{
			rightUniq[i] = leftUniq[i];
		}
	}
	else if(from == 'r' && to == 'l')
	{
		for(i=0; i<81; i++)
		{
			leftUniq[i] = rightUniq[i];
		}
	}
}

void moveEndPoint(char from, char to)
{
	int i, j;
	if(from == 'l' && to == 'r')
	{
		pRightCircle = pCircle;
		for(i=0; i<pRightCircle; i++)
		{
			pRightEndPoints[i] = pEndPoints[i];
			for(j=0; j<pRightEndPoints[i]; j++)
			{
				rightEndPoints[i][j].x = endPoints[i][j].x + 471;
				rightEndPoints[i][j].y = endPoints[i][j].y;
			}
			rightColorGroup[i] = colorGroup[i];
		}
	}
}

////////////////////////以下与画虚线框有关////////////////////////
int getDegree(int x, int y, int &flag)
{
	// 设置flag,求度数
	if(y >= 1 && edge[80+x+y*10])
	{
		flag |= 1;
	}
	if(x <= 8 && edge[x+y*9])
	{
		flag |= 2;
	}
	if(y <= 8 && edge[90+x+y*10])
	{
		flag |= 4;
	}
	if(x >= 1 && edge[x+y*9-1])
	{
		flag |= 8;
	}
	// 只有0度，1度，3度的情况，没有2度，4度
	if(flag == 7 || flag == 11 || flag == 13 || flag == 14) // 3度
	{
		flag = 15 - flag;
		if(flag == 1)
		{
			if(x >= 1 && y >= 1 && bodyIdx[x-1+mult9[y-1]])
			{
				flag = 8;
			}
			else
			{
				flag = 2;
			}
		}
		else if(flag == 2)
		{
			if(x <= 8 && y >= 1 && bodyIdx[x+mult9[y-1]])
			{
				flag = 1;
			}
			else
			{
				flag = 4;
			}
		}
		else if(flag == 4)
		{			
			if(x <= 8 && y <= 8 && bodyIdx[x+mult9[y]])
			{
				flag = 2;
			}
			else
			{
				flag = 8;
			}
		}
		else if(flag == 8)
		{
			if(x >= 1 && y <= 8 && bodyIdx[x-1+mult9[y]])
			{
				flag = 4;
			}
			else
			{
				flag = 1;
			}
		}
		return 3;
	}
	else if(flag == 0) // 0度
	{
		return 0;
	}
	else // 1度
	{
		return 1;
	}
}

void getEndPoint1(int i)
{
	int x, y;
	int flag = 2;
	int oldFlag = 4; // 向下
	// set first point
	endPoint[0].x = mod9[i];
	endPoint[0].y = divide9[i];
	cntEndPoint = 1;
	while(edge[i])
	{
		edge[i] = false;
		// 边求点
		if(oldFlag == flag)
		{
			cntEndPoint--;
		}
		if(flag == 1)
		{
			endPoint[cntEndPoint].x = (i-90)%10;
			endPoint[cntEndPoint].y = (i-90)/10;
		}
		else if(flag == 2)
		{
			endPoint[cntEndPoint].x = mod9[i] + 1;
			endPoint[cntEndPoint].y = divide9[i];
		}
		else if(flag == 4)
		{
			endPoint[cntEndPoint].x = (i-90)%10;
			endPoint[cntEndPoint].y = (i-90)/10+1;
		}
		else // must be 8
		{
			endPoint[cntEndPoint].x = mod9[i];
			endPoint[cntEndPoint].y = divide9[i];
		}
		cntEndPoint++;
		oldFlag = flag;
		// 点求边
		x = endPoint[cntEndPoint-1].x;
		y = endPoint[cntEndPoint-1].y;
		flag = 0;
		if(getDegree(x, y, flag) == 0)
		{
			edge[i] = false;
		}
		else // 1度或者3度
		{
			if(flag == 1)
			{
				i = 80+x+y*10;
			}
			else if(flag == 2)
			{
				i = x+y*9;
			}
			else if(flag == 4)
			{
				i = 90+x+y*10;
			}
			else if(flag == 8)
			{
				i = x+y*9-1;
			}
		}
	}
}

void getEndPoint2()
{
	int i;
	int x, y;
	int flag; // 左上为1，右上为2，右下为3，左下为4
	POINT oldPoint;
	for(i=0; i<cntEndPoint; i++)
	{
		flag = 0;
		x = endPoint[i].x;
		y = endPoint[i].y;
		if(x >= 1 && y >= 1 && bodyIdx[x-1+mult9[y-1]])
		{
			flag |= 1;
		}
		if(x <= 8 && y >= 1 && bodyIdx[x+mult9[y-1]])
		{
			flag |= 2;
		}
		if(x <= 8 && y <= 8 && bodyIdx[x+mult9[y]])
		{
			flag |= 4;
		}
		if(x >= 1 && y <= 8 && bodyIdx[x-1+mult9[y]])
		{
			flag |= 8;
		}
		// 2个格子
		if(flag == 5 || flag == 10)
		{
			if(endPoint[i].x == oldPoint.x)
			{
				if(mult49[endPoint[i].x]-6 == endPoint[i-1].x)
				{
					if(endPoint[i].y > oldPoint.y)
					{
						flag = 1;
					}
					else
					{
						flag = 8;
					}
				}
				else
				{
					if(endPoint[i].y > oldPoint.y)
					{
						flag = 2;
					}
					else
					{
						flag = 4;
					}
				}
			}
			else
			{
				if(mult49[endPoint[i].y]-6 == endPoint[i-1].y)
				{
					if(endPoint[i].x > oldPoint.x)
					{
						flag = 1;
					}
					else
					{
						flag = 2;
					}
				}
				else
				{
					if(endPoint[i].x > oldPoint.x)
					{
						flag = 8;
					}
					else
					{
						flag = 4;
					}
				}
			}
		}
		else if(flag != 1 && flag != 2 && flag != 4 && flag != 8)
		{
			// 3个格子
			flag = 15 - flag;
			if(flag == 1 || flag == 2)
			{
				flag <<= 2;
			}
			else
			{
				flag >>= 2;
			}
		}
		oldPoint.x = endPoint[i].x;
		oldPoint.y = endPoint[i].y;
		if(flag == 1)
		{
			endPoint[i].x = mult49[x] - 6;
			endPoint[i].y = mult49[y] - 6;
		}
		else if(flag == 2)
		{
			endPoint[i].x = mult49[x] + 6;
			endPoint[i].y = mult49[y] - 6;
		}
		else if(flag == 4)
		{
			endPoint[i].x = mult49[x] + 6;
			endPoint[i].y = mult49[y] + 6;
		}
		else // must be 8
		{
			endPoint[i].x = mult49[x] - 6;
			endPoint[i].y = mult49[y] + 6;
		}
	}
}

void getEdge()
{
	int i;
	// set true when same idx
	for(i=0; i<81; i++)
	{
		if(bodyIdx[i])
		{
			edge[i] = true;
			edge[i+91+divide9[i]] = true;
			edge[i+9] = true;
			edge[i+90+divide9[i]] = true;
		}
	}
	// set false when nabour
	for(i=0; i<81; i++)
	{
		if(bodyIdx[i])
		{
			if(i >= 9 && bodyIdx[i-9])
			{
				edge[i] = false;
			}
			if(mod9[i] <= 7 && bodyIdx[i+1])
			{
				edge[i+91+divide9[i]] = false;
			}
			if(i <= 71 && bodyIdx[i+9])
			{
				edge[i+9] = false;
			}
			if(mod9[i] >= 1 && bodyIdx[i-1])
			{
				edge[i+90+divide9[i]] = false;
			}
		}
	}
}

void getEndPoint3()
{
	for(int i=0; i<cntEndPoint; i++)
	{
		endPoints[pCircle][i].x = endPoint[i].x;
		endPoints[pCircle][i].y = endPoint[i].y;
	}
	pEndPoints[pCircle] = cntEndPoint;
	if((colorIdx&0x100) == 0x100) // 第8位是1，黑色
	{
		colorGroup[pCircle] = 0;
	}
	else if((colorIdx&0x200) == 0x200) // 第9位是1，红色
	{
		colorGroup[pCircle] = MaxColorCircle - 1;
	}
	else
	{
		colorGroup[pCircle] = colorIdx;
	}
	pCircle++;
}

void getColorIdx()
{
	int count = 0;
	// 根据leftHead取得颜色信息
	if(selectIdx == nowIdx)
	{
		colorIdx &= 0x2FF; // 第8位置0
		colorIdx |= 0x200; // 第9位置1
		return;
	}
	for(int i=0; i<81; i++)
	{
		if(leftHead[i] == nowIdx)
		{
			count++;
			if(count == 1)
			{
				colorIdx &= 0x1FF; // 第9位置0
				colorIdx |= 0x100; // 第8位置1
			}
			else
			{
				colorIdx = (colorIdx&0xFF)+1;
				break;
			}
		}
	}
}

void getBodyIdx(int grid)
{
	bodyIdx[grid] = true;
	if(grid >= 9 && leftIdx[grid-9] == nowIdx && bodyIdx[grid-9] == false)
	{
		getBodyIdx(grid-9);
	}
	if(mod9[grid] <= 7 && leftIdx[grid+1] == nowIdx && bodyIdx[grid+1] == false)
	{
		getBodyIdx(grid+1);
	}
	if(grid <= 71 && leftIdx[grid+9] == nowIdx && bodyIdx[grid+9] == false)
	{
		getBodyIdx(grid+9);
	}
	if(mod9[grid] >= 1 && leftIdx[grid-1] == nowIdx && bodyIdx[grid-1] == false)
	{
		getBodyIdx(grid-1);
	}
}

void getEndPoint()
{
	int i, j, k;
	// 处理每一个idx
	colorIdx = 0;
	pCircle = 0;
	// clear
	for(i=0; i<180; i++)
	{
		edge[i] = false;
	}
	for(i=1; i<=maxIdx; i++)
	{
		nowIdx = i;
		getColorIdx();
		// 处理每一个簇
		for(j=0; j<81; j++)
		{
			if(leftHead[j] == nowIdx)
			{
				// get bodyIdx based on leftIdx
				for(k=0; k<81; k++)
				{
					bodyIdx[k] = false;
				}
				getBodyIdx(j);
				// get edge based on bodyIdx
				getEdge();
				// 处理每一个环
				for(k=0; k<90; k++)
				{
					if(edge[k])
					{
						getEndPoint1(k); // k is the first edge
						getEndPoint2(); // arrange colorIdx, endPoint[] to endPoints[]
						getEndPoint3();
					}
				}
			}
		}
	}
}

////////////////////////以下与鼠标操作有关////////////////////////
int tempIdx[81];
static void clearNabour(int grid)
{
	tempIdx[grid] = 0;
	if(grid >= 9 && tempIdx[grid-9] == nowIdx)
	{
		clearNabour(grid-9);
	}
	if(mod9[grid] <= 7 && tempIdx[grid+1] == nowIdx)
	{
		clearNabour(grid+1);
	}
	if(grid <= 71 && tempIdx[grid+9] == nowIdx)
	{
		clearNabour(grid+9);
	}
	if(mod9[grid] >= 1 && tempIdx[grid-1] == nowIdx)
	{
		clearNabour(grid-1);
	}
}

void updateHeadUniq()
{
	int i, j;
	int bakSelectIdx;
	int temp2Idx[81];
	// get leftHead based on leftIdx
	for(i=0; i<81; i++)
	{
		tempIdx[i] = leftIdx[i];
		leftHead[i] = 0;
	}
	for(i=0; i<81; i++)
	{
		if(tempIdx[i] != 0)
		{
			nowIdx = tempIdx[i];
			leftHead[i] = nowIdx;
			clearNabour(i);
		}
	}
	// get leftUniq based on leftHead
	for(i=0; i<81; i++)
	{
		tempIdx[i] = leftHead[i];
	}
	for(i=0; i<81; i++)
	{
		if(tempIdx[i] != 0)
		{
			nowIdx = tempIdx[i];
			for(j=i+1; j<81; j++)
			{
				if(tempIdx[j] == nowIdx)
				{
					tempIdx[j] = 0;
				}
			}
		}
	}
	for(i=0; i<81; i++)
	{
		leftUniq[i] = tempIdx[i] != 0;
	}
	// get maxIdx and leastize idx
	maxIdx = 0;
	for(i=0; i<81; i++)
	{
		tempIdx[i] = 0;
		temp2Idx[i] = 0;
	}
	for(i=0; i<81; i++)
	{
		if(leftUniq[i])
		{
			nowIdx = leftIdx[i];
			maxIdx++;
			for(j=i; j<81; j++)
			{
				if(leftIdx[j] == nowIdx)
				{
					tempIdx[j] = maxIdx;
				}
				if(leftHead[j] == nowIdx)
				{
					temp2Idx[j] = maxIdx;
				}
			}
			if(selectIdx == nowIdx)
			{
				bakSelectIdx = maxIdx;
			}
		}
	}
	for(i=0; i<81; i++)
	{
		leftIdx[i] = tempIdx[i];
		leftHead[i] = temp2Idx[i];
	}
	// update selectIdx
	selectIdx = bakSelectIdx;
	for(i=0; i<81; i++)
	{
		if(editingIdx[i])
		{
			editingHead = i;
			break;
		}
	}
	if(i == 81)
	{
		selectIdx = 0;
		underSumEditing = false;
	}
}

/*****************************************************
 * 按住shift点选已经选中的格点时，取消此格点
 * 点选没有idx的格点时，选中此格点(第一次选和非第一次选)
 * 点选idx的格点时，选中所有idx的格点
 * 窍门：跟着别人跑
 *****************************************************/
void updateIdxShift(int grid, bool flagIntoEditing)
{
	int i;
	int nowSum;
	// 已知leftUniq, leftHead, leftIdx, editingIdx
	if(editingIdx[grid])
	{
		editingIdx[grid] = false;
		leftIdx[grid] = 0;
	}
	else if(leftIdx[grid] == 0)
	{
		if(selectIdx == 0)
		{
			selectIdx = ++maxIdx;
			editingIdx[grid] = true;
			leftIdx[grid] = selectIdx;
		}
		else
		{
			editingIdx[grid] = true;
			leftIdx[grid] = selectIdx;
		}
	}
	else // leftIdx[grid] != 0
	{
		if(selectIdx == 0)
		{
			selectIdx = leftIdx[grid];
			nowIdx = selectIdx;
		}
		else
		{
			nowIdx = selectIdx;
			selectIdx = leftIdx[grid];
		}
		for(i=0; i<81; i++)
		{
			if(leftIdx[i] == selectIdx)
			{
				editingIdx[i] = true;
			}
			else if(leftIdx[i] == nowIdx) // 相等的时候下面无意义
			{
				leftIdx[i] = selectIdx;
			}
		}
	}
	// 根据leftIdx求leftHead，leftUniq
	nowSum = leftSum[editingHead];
	updateHeadUniq();
	if(!flagIntoEditing)
	{
		leftSum[editingHead] = nowSum;
		if(editingHead != grid)
		{
			leftSum[grid] = 0;
		}
	}
}

/*****************************************************
 * 按住ctrl点选已经选中的格点时，取消此格点
 * 点选没有idx的格点时，选中此格点(第一次选和非第一次选)
 * 点选idx的格点时，选中idx的格点
 * 窍门：跟着自己跑
 *****************************************************/
void updateIdxCtrl(int grid, bool flagIntoEditing)
{
	int nowSum;
	// 已知leftUniq, leftHead, leftIdx, editingIdx
	if(editingIdx[grid])
	{
		editingIdx[grid] = false;
		leftIdx[grid] = 0;
	}
	else
	{
		if(selectIdx == 0)
		{
			selectIdx = ++maxIdx;
		}
		editingIdx[grid] = true;
		leftIdx[grid] = selectIdx;
	}
	// 根据leftIdx求leftHead，leftUniq
	nowSum = leftSum[editingHead];
	updateHeadUniq();
	if(!flagIntoEditing)
	{
		leftSum[editingHead] = nowSum;
		if(editingHead != grid)
		{
			leftSum[grid] = 0;
		}
	}
}

/*****************************************************
 * 处于编辑数和状态时，按下回车或者鼠标左键点一下等
 *****************************************************/
void terminateSumEdit()
{
	int i;
	selectIdx = 0;
	for(i=0; i<81; i++)
	{
		editingIdx[i] = false;
	}
	underSumEditing = false;
}

void flushSosumLeft()
{
	terminateSumEdit();
	updateHeadUniq();
	getEndPoint();
}
