#include "stdinc.h"
#include "cTearsBoard.h"
#include "cArray2D.cpp"
#include "cList.cpp"

cTearsBoard::cTearsBoard(){
	Create(BOARD_HEIGHT, BOARD_WIDTH);
}

cTearsBoard::~cTearsBoard(){
	int y, x;
	cTear *pTear;

	TearList.SetSelect();
	while(TearList.Get(&pTear)){
		delete pTear;
		TearList.DeleteThis();
	}

	if(Elements){
		for(y = 0; y < Height; y ++){
			for(x = 0; x < Width; x ++){
				if(Get(y, x)){
					delete Get(y, x);
				}
			}
		}
	}

	Destroy();

}

int cTearsBoard::Act(){
	int y, x;
	cTear *pTear;

	TearList.SetSelect();
	while(TearList.Get(&pTear)){
		if(pTear->Act() == TAR_REMOVE){
			delete pTear;
			TearList.DeleteThis();
		}else{
			TearList.SelectNext();
		}
	}
	for(y = 0; y < Height; y ++){
		for(x = 0; x < Width; x ++){
			if(Get(y, x)){
				Get(y, x)->Act();
			}
		}
	}

	return 0;
}


void cTearsBoard::Clear(cTear *p){
	int y, x;

	for(y = 0; y < Height; y ++){
		for(x = 0; x < Width; x ++){
			Set(y, x, p);
		}
	}
}

void cTearsBoard::SetTear(cTear *pTear){
	Set(TPToBP(pTear->y), TPToBP(pTear->x), pTear);
	pTear->SetState(TS_SET);
	pTear->y = BPToTP(TPToBP(pTear->y + PPToTP(16)));
	pTear->x = BPToTP(TPToBP(pTear->x + PPToTP(16)));
}

void cTearsBoard::Show(cPicture *pDestPic, int Left, int Top){
	cTear *pTear;
	int x, y;
//	SetRect(&rcDest, Left, Top, Left + Width * 32, Top + Height * 32);
//	pDestPic->Blt(&rcDest, pBackPicture, NULL, DDBLT_WAIT, NULL);

	for(y = 0; y < Height; y ++){
		for(x = 0; x < Width; x ++){
			pTear = Get(y, x);
			if(!pTear) continue;
			pTear->Show(pDestPic, Left, Top);
		}
	}
}

void cTearsBoard::BreakAll(){
	int y, x;

	for(y = 0; y < Height; y ++){
		for(x = 0; x < Width; x ++){
			if(Get(y, x) != NULL){
				TearList.Add(Get(y, x));
				Get(y, x)->cVector3D<int>::Set(PPToTP(x * 32 + 180), PPToTP(y * 32 + 40), 0);
				Get(y, x)->SetState(TS_BREAKING);
				Set(y, x, NULL);
			}
		}
	}
}



int cTearsBoard::EraseTears(){
	int MatchCount;
	int y, x;

	MatchCount = 0;

	// 완성된 3개를 찾는다.
	Check(1, 0); // ---
	Check(0, 1); // |
	Check(1, 1); // ~-_
	Check(-1, 1); // /

	// 속성이 변화한 놈들은 없에 버린다.
	for(y = 0; y < Height; y ++){
		for(x = 0; x < Width; x ++){
			if(Get(y, x) == NULL) continue;
			if(Get(y, x)->GetState() == TS_SELECTED){
//				Get(y, x)->SetState(TS_BREAKING);
				MatchCount ++;
			}
		}
	}
	return MatchCount;
}

int cTearsBoard::Check(int dx, int dy){
	int xFind, yFind;
	int MatchCount;
	int WholeMatchCount;
	int BaseKind;
	int z, y, x;

	WholeMatchCount = 0;

	for(y = 0; y < Height; y ++){
		for(x = 0; x < Width; x ++){
			if(Get(y, x) == NULL) continue;
			BaseKind = Get(y, x)->GetKind();
			MatchCount = 1;
			for(z = 1; z < 7; z ++){
				yFind = y + dy * z;
				xFind = x + dx * z;
				if(yFind < 0 || yFind >= Height
					|| xFind < 0 || xFind >= Width) break;
				if(Get(yFind, xFind) == NULL) break;
				if(Get(yFind, xFind)->GetKind() != BaseKind)
					break;
				MatchCount ++;
			}
			if(MatchCount >= 3){
				for(z = 0; z < MatchCount; z ++){
					yFind = y + dy * z;
					xFind = x + dx * z;
					Get(yFind, xFind)->SetState(TS_SELECTED);
					WholeMatchCount += MatchCount;
				}
			}
		}
	}

	return WholeMatchCount;
}

void cTearsBoard::ShiftDown(){
	cTear *pTear;
	int y, x, h;

	for(x = 0; x < Width; x ++){
		h = Height - 1;
		for(y = Height - 1; y >= 0; y --){
			if(Get(y, x) != NULL){
				if(Get(y, x)->GetState() == TS_SELECTED){
					TearList.Add(Get(y, x));
					Get(y, x)->cVector3D<int>::Set(PPToTP(x * 32 + 180), PPToTP(y * 32 + 40), 0);
					Get(y, x)->SetState(TS_BREAKING);
					Set(y, x, NULL);
				}else{
					pTear = Get(y, x);
					Set(y, x, NULL);
					Set(h, x, pTear);
					pTear->cVector3D<int>::Set(BPToTP(x), BPToTP(h), 0);
					h --;
				}
			}
		}
	}

}

void cTearsBoard::ShowEffect(cPicture *pDestPic, int Left, int Top){
	cTear *pTear;

	TearList.SetSelect();
	while(TearList.Get(&pTear)){
		pTear->Show(pDestPic, Left, Top);
		TearList.SelectNext();
	}

}
