#include "myWin.h"
#include "math.h"
#define MAX 49
#define MD  5 //この値を入れ替えて、絵がのように変わるか遊んでみよう
int cur;
int dt[2][MAX+1][MAX+1];
int cTab[8]=
	{0x330000,0xFFFFFF, 0x0000FF, 0x00FF00,
	 0xFF0000,0x00FFFF, 0x0033FF, 0xFF00FF};
double PI=3.1415926535897932385;
static HDC hBuff; static HBITMAP hBM;
void draw(){
	for(int i=1;i<MAX-1;i++) for(int j=1;j<MAX-1;j++){
		int c=dt[cur][i][j];
		HPEN   hpen=CreatePen(PS_SOLID,1,cTab[c]); SelectObject(hBuff,hpen);
		HBRUSH hbrush=CreateSolidBrush(cTab[c])  ; SelectObject(hBuff,hbrush);
		int X=i*10, Y=j*10;
		Rectangle(hBuff,X,Y,X+10,Y+10);
		DeleteObject(hbrush);DeleteObject(hpen);
	}
}
void cellAutomaton(){
	int nxt=1-cur;
	for(int i=1;i<MAX-1;i++) for(int j=1;j<MAX-1;j++){
		dt[nxt][i][j]=(dt[cur][i][j-1]+dt[cur][i][j+1]+dt[cur][i-1][j]+dt[cur][i+1][j]) % MD;
	}
	cur=nxt;
}

void procPaint(HWND hw, WPARAM wp,LPARAM lp){
	PAINTSTRUCT ps;	HDC hdc=BeginPaint(hw, &ps);
	BitBlt(hdc, 0,0,550,550,hBuff,0,0,SRCCOPY);
	EndPaint(hw,&ps);
}

void procLButtonDown(HWND hw, WPARAM wp,LPARAM lp){
	cellAutomaton(); draw();
	InvalidateRect(hw,NULL,TRUE);
}
void procCreate(HWND hw, WPARAM wp,LPARAM lp){
	SetWindowText(hw,TEXT("二次元セルオートマトン"));
	MoveWindow(hw,0,0,530,530,TRUE);
	HDC hdc=GetDC(hw); hBM=CreateCompatibleBitmap(hdc,550,550);
	hBuff=CreateCompatibleDC(hdc); SelectObject(hBuff,hBM);
	SelectObject(hBuff,GetStockObject(NULL_PEN));
	PatBlt(hBuff,0, 0,550,550,WHITENESS);
	ReleaseDC(hw,hdc);
	cur=0;
	for(int i=0;i<(MAX+1);i++)for(int j=0;j<(MAX+1);j++)dt[cur][i][j]=0;
	int center = MAX/2;
	dt[cur][center][center] = 1;
	SetTimer(hw,1,200,NULL);
	draw();
}
void procTimer(HWND hw, WPARAM wp,LPARAM lp){
	procLButtonDown(hw,wp,lp);
}
LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wp,LPARAM lp){
	switch(msg){
	case WM_DESTROY       : PostQuitMessage(0)         ; return 0;
	case WM_CREATE        : procCreate(hw,wp,lp)       ; return 0;
	case WM_PAINT         : procPaint(hw,wp,lp)        ; return 0;
	//次をコメントにすると左ボタンクリックで描画
	case WM_TIMER         : procTimer(hw,wp,lp)        ; return 0;
	case WM_LBUTTONDOWN   : procLButtonDown(hw,wp,lp)  ; return 0;
	}
	return DefWindowProc(hw,msg,wp,lp);
}