HWND gblHSpec;

int plans[MAX_FONDS];
int nPlansLies, CopieSpec=0, indexSpecX, indexSpecY;
#define lieMaps (nPlansLies>1)

int tailleTilesX, tailleTilesY, taillePlanX, taillePlanY;
int scrlX, scrlY;

#define LaMap(plan,x,y)		(params[(plan)].gblMap[params[(plan)].tailleX*(y)+(x)])
int grandeurX;
int grandeurY;

void DessineMapSpec(int mapNb, int taille)			{
	int x,y,i, xx, yy, fX, fY;
	int dX, dY;
	int k;
	unsigned char *palette;
	unsigned long *motifs;
	PARAM *p;

	i=0;

	dX=scrlX;
	dY=scrlY;
//	mX=scrlX%tileX;
//	mY=scrlY%tileY;
	if (taillePlanX-dX>grandeurX)
		fX=grandeurX+1;
	else
		fX=taillePlanX-dX;
	if (taillePlanY-dY>grandeurY)
		fY=grandeurY+1;
	else
		fY=taillePlanY-dY;

	for (y=0;y<fY;y++)		{
		for (x=0;x<fX;x++)		{
			for (k=0;k<nPlansLies;k++)		{
				p=&params[plans[k]];
				i=p->gblMap[taillePlanX*(y+dY)+x+dX]+blocBase;
				if (i!=masqueInvisible && (i!=0 || !masqueZero))
					break;
			}
			if (k>=nPlansLies)
				continue;

			i=VerifConditions(i,k,gfxmask);

			motifs=p->gblMotifs;
			palette=p->gblPal;
			palette[0]=(cFond&0x00ff0000)>>16;
			palette[1]=(cFond&0x0000ff00)>>8;
			palette[2]=cFond&0x000000ff;

//			i&=p->gfxmask;
			//Motif non-valide (ne devrait pas arriver)
//			if (!emul_gba)		{
				if ((i&gbatilmask)>=p->taille || i<0)
					continue;
//			}

			for (yy=0;yy<tileY;yy+=8)
				for (xx=0;xx<tileX;xx+=8)		{
					if (emul_gba)
						DessineTile(Bits4,x*tailleTilesX+xx,y*tailleTilesY+yy,p,(i*tailleTilesX*tailleTilesY)/64+(tailleTilesX/8)*(yy/8)+(xx/8),0);
					else
						SpritePal(Bits4,x*tailleTilesX+xx,y*tailleTilesY+yy,8,8,motifs+(i*tailleTilesX*tailleTilesY)+64*(tailleTilesX/8)*(yy/8)+64*(xx/8),palette);
				}
//			ColoreCadre(x,y,16,16,RGB(255,0,0));
		}
	}
}

void ScrollX(HWND hDlg)		{
	//Remet la position dans la gamme possible
	if (scrlX>taillePlanX-grandeurX)
		scrlX=taillePlanX-grandeurX;
	if (scrlX<0)
		scrlX=0;

	SetScrollPos(hDlg,SB_HORZ,scrlX,TRUE);
}

void ScrollY(HWND hDlg)		{
	//Remet la position dans la gamme possible
	if (scrlY>taillePlanY-grandeurY)
		scrlY=taillePlanY-grandeurY;
	if (scrlY<0)
		scrlY=0;

	SetScrollPos(hDlg,SB_VERT,scrlY,TRUE);
}


LRESULT CALLBACK ProcSpecimen(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)		{
	int i,j,x,y,p,q,c,k;
	static int Sel=FALSE, posDepartX, posDepartY, posX, posY, derTickCount, ancCopieSpec=FALSE;
	int sCode;
	short int nPos;
	MAP (*bloc)[1024];
	static int neverUpdated=TRUE;

	switch (message)
	{
		case WM_INITDIALOG:
			RECT rect;

/*			if (nPlansLies<=0)			{
				DestroyWindow(hDlg);
				return TRUE;
			}*/
			gblHSpec=hDlg;

//			ShowWindow(hDlg,SW_SHOW);
			GetWindowRect(hDlg,&rect);
			SetTimer(hDlg,1,100,NULL);

			scrlX=scrlY=0;

			SetWindowPos(hDlg,HWND_TOP,0,0,rect.right-rect.left+1,rect.bottom-rect.top+1,SWP_NOZORDER|SWP_NOMOVE);
			neverUpdated=TRUE;
			return TRUE;

		case WM_VSCROLL:
			sCode = (int) LOWORD(wParam); // scroll bar value 
			nPos = (short int) HIWORD(wParam);  // scroll box position 

			if (sCode==SB_LINEUP)
				scrlY-=2;
			if (sCode==SB_LINEDOWN)
				scrlY+=2;
			if (sCode==SB_PAGEUP)
				scrlY-=16;
			if (sCode==SB_PAGEDOWN)
				scrlY+=16;
			if (sCode==SB_BOTTOM)
				scrlY=32767;
			if (sCode==SB_TOP)
				scrlY=0;
			if (sCode==SB_THUMBTRACK || sCode==SB_THUMBPOSITION)
				scrlY=nPos;

			ScrollY(hDlg);
			CopieSpec=0;
			InvalidateRect(hDlg,NULL,0);
			break;


		case WM_HSCROLL:
			sCode = (int) LOWORD(wParam); // scroll bar value 
			nPos = (short int) HIWORD(wParam);  // scroll box position 

			if (sCode==SB_LINELEFT)
				scrlX-=2;
			if (sCode==SB_LINERIGHT)
				scrlX+=2;
			if (sCode==SB_PAGELEFT)
				scrlX-=16;
			if (sCode==SB_PAGERIGHT)
				scrlX+=16;
			if (sCode==SB_RIGHT)
				scrlX=32767;
			if (sCode==SB_LEFT)
				scrlX=0;
			if (sCode==SB_THUMBTRACK || sCode==SB_THUMBPOSITION)
				scrlX=nPos;

			ScrollX(hDlg);
			CopieSpec=0;
			InvalidateRect(hDlg,NULL,0);
			break;

		case WM_MOUSEMOVE:
			if (CopieSpec)
				break;
			posX=(short)LOWORD(lParam);
			posY=(short)HIWORD(lParam);
			if (Sel)
				InvalidateRect(hDlg,NULL,0);
			break;

		case WM_RBUTTONDOWN:
		case WM_LBUTTONDOWN:
			posX=(short)LOWORD(lParam);
			posY=(short)HIWORD(lParam);
			Sel=TRUE;
			CopieSpec=FALSE;
			posDepartX=posX/tailleTilesX;
			posDepartY=posY/tailleTilesY;
			SetCapture(hDlg);
			InvalidateRect(hDlg,NULL,0);
			break;

		case WM_RBUTTONUP:
		case WM_LBUTTONUP:
			ReleaseCapture();
			posX=(short)LOWORD(lParam);
			posY=(short)HIWORD(lParam);
			if (posX<0) posX=0;
			if (posY<0) posY=0;
			if (posX>=grandeurX*tailleTilesX)
				posX=grandeurX*tailleTilesX;
			if (posY>=grandeurY*tailleTilesY)
				posY=grandeurY*tailleTilesY;
			Sel=FALSE;
			i=posDepartX;
			j=posDepartY;
			x=posX/tailleTilesX+1;
			y=posY/tailleTilesY+1;
			if (x<=i)		{
				p=i;
				i=x-1;
				x=p+1;
			}
			if (y<=j)		{
				p=j;
				j=y-1;
				y=p+1;
			}

			memset(blocCopieOk, 0, sizeof(blocCopieOk));
			if (x+scrlX>taillePlanX || y+scrlY>taillePlanY)		{
				InvalidateRect(hDlg,NULL,0);
				break;
			}

			for (k=0;k<MAXBLOCS && k<nPlansLies;k++)		{
				bloc=blocCopie+1024*k;
				if (params[plans[k]].gblTypeMap==TYPE_LISTE)
					goto pasbon;
				for (q=j;q<=y;q++)
					for (p=i;p<=x;p++)		{
						bloc[q-j][p-i]=LaMap(plans[k],p+scrlX,q+scrlY);
					}
				blocCopieOk[k] = 1;
			}
			profondeurSel=k;
			indexSpecX=i+scrlX;
			indexSpecY=j+scrlY;
			CopieX=x-i;
			CopieY=y-j;
			CopieSpec=1;
			CopieXprecise=CopieX*tailleTilesX, CopieYprecise=CopieY*tailleTilesY;
pasbon:
			InvalidateRect(hDlg,NULL,0);
			break;

		case WM_TIMER:
			if (nPlansLies<=0)
				break;
			if (CopieSpec!=ancCopieSpec)
				InvalidateRect(hDlg,NULL,0);

			ancCopieSpec=CopieSpec;

			i=GetTickCount();
			k=GetAsyncKeyState(VK_SHIFT)?5:1;
			for (j=0;j<(i-derTickCount)/100*k;j++)		{
				if (!Sel)
					return FALSE;
				if (posX<0 && scrlX>0)
					scrlX--, posDepartX++;
				if (posY<0 && scrlY>0)
					scrlY--, posDepartY++;
				if (posX>grandeurX*tailleTilesX && scrlX<taillePlanX-grandeurX)
					scrlX++, posDepartX--;
				if (posY>grandeurY*tailleTilesY && scrlY<taillePlanY-grandeurY)
					scrlY++, posDepartY--;
			}
			derTickCount=i;
			ScrollX(hDlg);
			ScrollY(hDlg);
			InvalidateRect(hDlg,NULL,0);
			break;

		case WM_SIZE:
			SCROLLINFO si;

			if (nPlansLies<=0)
				break;

			i = LOWORD(lParam);  // width of client area 
			j = HIWORD(lParam); // height of client area 

size_update:
			grandeurX=i/tailleTilesX;
			grandeurY=j/tailleTilesY;

			si.cbSize=sizeof(si);
			si.nMin=0;
			si.nMax=taillePlanY;
			si.nPos=scrlY;
			si.nPage=grandeurY;
			si.fMask=SIF_POS | SIF_RANGE | SIF_PAGE;
			SetScrollInfo(hDlg,SB_VERT,&si,1);

			si.nMax=taillePlanX;
			si.nPos=scrlX;
			si.nPage=grandeurX;
			si.fMask=SIF_POS | SIF_RANGE | SIF_PAGE;
			SetScrollInfo(hDlg,SB_HORZ,&si,1);

			ScrollX(hDlg);
			ScrollY(hDlg);

			if (neverUpdated)			{
				neverUpdated = FALSE;
				goto apres_size;
			}
			InvalidateRect(hDlg,NULL,0);
			break;

		case WM_PAINT:
			HDC hdc;

			if (nPlansLies<=0)
				break;
			else if (neverUpdated)		{
				GetWindowRect(hDlg, &rect);
				i = rect.right-rect.left;
				j = rect.bottom-rect.top;
				InvalidateRect(hDlg, NULL, 0);
				goto size_update;
			}
apres_size:

			BeginPaint(hDlg,NULL);
			ColoreCadre(Bits4,0,0,LARG,HAUT,cFond);
			i=plans[0];
			if (params[i].gblTypeMap!=TYPE_LISTE)
				DessineMapSpec(i,params[i].taille);
			if (Sel || CopieSpec)		{
				i=posDepartX;
				j=posDepartY;
				x=posX/tailleTilesX+1;
				y=posY/tailleTilesY+1;
				if (x<=i)		{
					p=i;
					i=x-1;
					x=p+1;
				}
				if (y<=j)		{
					p=j;
					j=y-1;
					y=p+1;
				}

				k=128;
				if (x+scrlX>taillePlanX || y+scrlY>taillePlanY)
					c=RGB(255,0,0);
				else if (CopieSpec)
					c=RGB(255,255,255), k=96;
				else
					c=RGB(255,255,255);
				i*=tailleTilesX;
				j*=tailleTilesY;
				x*=tailleTilesX;
				y*=tailleTilesY;
				TransRect(Bits4,i,j+1,x-i,y-j,RGB(0,0,0),k);
				TransCadre(Bits4,i+1,j+1,x-2-i,y-2-j,c,k);
			}
/*			sprintf(str,"%i",Sel);
			TextOut(hdcSpec,0,0,str,strlen(str));*/
			hdc=GetDC(hDlg);
			BitBlt(hdc,0,0,grandeurX*tailleTilesX,grandeurY*tailleTilesY,hdcSpec,0,0,SRCCOPY);
			ReleaseDC(hDlg,hdc);
			EndPaint(hDlg,NULL);
			break;

		case WM_COMMAND:
			if (LOWORD(wParam) == IDCANCEL)
			{
				bSpecimenAffiche = 0;
				ShowWindow(hDlg,SW_HIDE);
//				DestroyWindow(hDlg);
				return TRUE;
			}

			break;
	}

    return FALSE;
}

