#include "lib\kolibri.h"
#include "lib\random.h"

unsigned char block[] = FROM "lib\\boxes.raw";

system_colors sc;

//óðîâíè ñëîæíîñòè
int DIFFICULTY_LEVEL=1; //ïî-óìîë÷àíèþ ñðåäíåå ïîëå
char *BOARD_SIZES[]={ "S", "M", "L", 0 };
int DIFFICULTY_LEV_PARAMS[]={ 9, 12, 16 };

int BLOCKS_NUM; //êîëè÷åñòâî êâàäðàòèêîâ ïî Õ è ïî Y
int BLOCKS_LEFT; //áëîêîâ îñòàëîñü
int blocks_matrix[28*28]; //öâåòà äëÿ ïîëÿ ñ êâàäðàòèêàìè

#define USER_PANEL_HEIGHT 35
#define BLOCK_SIZE 21 //ðàçìåð êâàäðàòèêà
#define MARKED 7
#define DELETED_BLOCK 6
#define HEADER "Just Clicks v2.2"

#ifndef AUTOBUILD
#include "lang.h--"
#endif

#ifdef LANG_RUS
	#define NEW_GAME_TEXT "‡ ­®¢® [F2]"
	#define RESULT_TEXT   "¥§ã«ìâ â: "
#elif LANG_EST
	#define NEW_GAME_TEXT "Uus mäng [F2]"
	#define RESULT_TEXT   "Tulemus: "
#else
	#define NEW_GAME_TEXT "New Game [F2]"
	#define RESULT_TEXT   "Result: "
#endif


void main()
{
	int id;

	BLOCKS_NUM=DIFFICULTY_LEV_PARAMS[DIFFICULTY_LEVEL];

	new_game();

	loop()
		switch(WaitEvent())
		{
			case evButton:
				id = @GetButtonID();
				if (id==1) ExitProcess();
				if (id==2) || (id==3) goto _NEW_GAME_MARK;
				if (id>=100)
				{
					if (check_for_end()) break; //åñëè èãðà çàêîí÷åíà

					move_blocks(id-100);
					draw_field();

					draw_clicks_num();

					break;
				}
				if (id==10) //èçìåíÿåì ðàçìåð ïîëÿ
				{
					if (DIFFICULTY_LEVEL<2) DIFFICULTY_LEVEL++; else DIFFICULTY_LEVEL=0;

					BLOCKS_NUM = DIFFICULTY_LEV_PARAMS[DIFFICULTY_LEVEL]; //êîëè÷åñòâî êâàäðàòèêîâ ïî Õ è ïî Y

					new_game();

					MoveSize(-1, -1, BLOCK_SIZE*BLOCKS_NUM +9, BLOCK_SIZE*BLOCKS_NUM +GetSkinHeight()+4+USER_PANEL_HEIGHT);
					break;
				}
				break;
			case evKey:
				@GetKeyScancode();
				if (AL==001) //Escape
					 ExitProcess();
				if (AL==060) //F2
				{
					_NEW_GAME_MARK:
						new_game();
						draw_clicks_num();
						draw_field();
				}
				break;
			case evReDraw:
				draw_window();
		}
}


void move_blocks(int button_id) //åñëè ôèøêà îäíà, òî íå óäàëÿåì
{
	int i, j,
	marked_num=1,
	old_marker=blocks_matrix[button_id],
	restart;

	blocks_matrix[button_id]=MARKED;

	//âûäåëÿåì âñå ôèøêè òîãî æå ÷âåòà
	_RESTART_MARK:
	restart=0;
	for (i=0;i<BLOCKS_NUM;i++)
		for (j=0;j<BLOCKS_NUM;j++)
		{
			if (blocks_matrix[i*BLOCKS_NUM+j]<>old_marker) continue; //åñëè ôèøêà íå íóæíîãî öâåòà èä¸ì äàëüøå
			if (blocks_matrix[i*BLOCKS_NUM+j]==MARKED) continue; //åñëè ôèøêà óæå îòìå÷åíà, èä¸ì äàëåå

			if (j>0) && (blocks_matrix[i*BLOCKS_NUM+j-1]==MARKED) blocks_matrix[i*BLOCKS_NUM+j]=MARKED; //ñìîòðèì ëåâûé
			if (i>0) && (blocks_matrix[i-1*BLOCKS_NUM+j]==MARKED) blocks_matrix[i*BLOCKS_NUM+j]=MARKED; //ñìîòðèì âåðõíèé
			if (j<BLOCKS_NUM-1) && (blocks_matrix[i*BLOCKS_NUM+j+1]==MARKED) blocks_matrix[i*BLOCKS_NUM+j]=MARKED; //ñìîòðèì ïðàâûé
			if (i<BLOCKS_NUM-1) && (blocks_matrix[i+1*BLOCKS_NUM+j]==MARKED) blocks_matrix[i*BLOCKS_NUM+j]=MARKED; //ñìîòðèì íèæíèé

			if (blocks_matrix[i*BLOCKS_NUM+j]==MARKED) //åñëè ôèøêó îòìåòèëè, òî ïîòîì öèêë íóæíî áóäåò ïðîêðóòèòü ñíà÷àëà - ìîæ åù¸ ÷¸ îòìåòèì
			{
				restart=1;
				marked_num++;
			}
		}
	if (restart) goto _RESTART_MARK;

	if (marked_num==1) //åñëè áëîê òîëüêî îäèí, óõîäèì
	{
		blocks_matrix[button_id]=old_marker;
		return;
	}

	//äâèãàåì áëîêè ïî âåðòèêàëè
	_2_RESTART_MARK:
	restart=0;
	for (i=BLOCKS_NUM;i>0;i--)
		for (j=BLOCKS_NUM;j>=0;j--)
		{
			if (blocks_matrix[i*BLOCKS_NUM+j]==MARKED) && (blocks_matrix[i-1*BLOCKS_NUM+j]<>blocks_matrix[i*BLOCKS_NUM+j])
			{
				blocks_matrix[i*BLOCKS_NUM+j]><blocks_matrix[i-1*BLOCKS_NUM+j];
				restart=1;
			}
		}
	if (restart) goto _2_RESTART_MARK;

	//îòìå÷àåì ôèøêè, êàê óäàë¸ííûå
	for (i=0;i<BLOCKS_NUM*BLOCKS_NUM;i++)
			if (blocks_matrix[i]==MARKED)
				blocks_matrix[i]=DELETED_BLOCK;

	//äâèãàåì áëîêè âëåâî, åñëè åñòü ïóñòîé ñòîëáåö
	restart=BLOCKS_NUM; //íå ïðèäóìàë íè÷åãî ëó÷øå :(

	_3_RESTART_MARK:
	for (j=0;j<BLOCKS_NUM-1;j++)
		if (blocks_matrix[BLOCKS_NUM-1*BLOCKS_NUM+j]==DELETED_BLOCK)
		{
			for (i=0;i<BLOCKS_NUM;i++)
				blocks_matrix[i*BLOCKS_NUM+j]><blocks_matrix[i*BLOCKS_NUM+j+1];
		}
	restart--;
	if (restart) goto _3_RESTART_MARK;
}


void draw_window()
{
	int PANEL_Y;
	proc_info Form;

	sc.get();
	DefineAndDrawWindow(300,176, BLOCK_SIZE*BLOCKS_NUM +9, BLOCK_SIZE*BLOCKS_NUM +GetSkinHeight()+4+USER_PANEL_HEIGHT,
		0x74,sc.work,0,0,HEADER);

	//ïðîâåðÿåì íå ñõëîïíóòî ëè îêíî â çàãîëîâîê
	GetProcessInfo(#Form, SelfInfo);
	if (Form.status_window>2) return;


	PANEL_Y=BLOCK_SIZE*BLOCKS_NUM;

	DrawBar(0,PANEL_Y, PANEL_Y, USER_PANEL_HEIGHT, sc.work); //ïàíåëü ñíèçó

	DrawCaptButton(10, PANEL_Y+7, 90, 20, 2, sc.work_button, sc.work_button_text,NEW_GAME_TEXT);
	DrawCaptButton(105,PANEL_Y+7, 20, 20, 10,sc.work_button, sc.work_button_text,BOARD_SIZES[DIFFICULTY_LEVEL]);

	draw_field();

	draw_clicks_num();
}


int check_for_end()
{
	int i, j, button_id;

	if (!BLOCKS_LEFT) return 1; //epic win

	for (i=0;i<BLOCKS_NUM;i++)
		for (j=0;j<BLOCKS_NUM;j++)
		{
			button_id=blocks_matrix[i*BLOCKS_NUM+j];

			if (button_id==DELETED_BLOCK) continue;

			if (j>0) && (blocks_matrix[i*BLOCKS_NUM+j-1]==button_id) return 0;
			if (i>0) && (blocks_matrix[i-1*BLOCKS_NUM+j]==button_id) return 0;
			if (j<BLOCKS_NUM-1) && (blocks_matrix[i*BLOCKS_NUM+j+1]==button_id) return 0;
			if (i<BLOCKS_NUM-1) && (blocks_matrix[i+1*BLOCKS_NUM+j]==button_id) return 0;
		}
	return 2;
}


void draw_clicks_num()
{
	char rezult[15];
	int i;
	int TEXT_Y=BLOCK_SIZE*BLOCKS_NUM+14;
	int TEXT_X=TEXT_Y/2+48; //130;

	BLOCKS_LEFT=0;

	for (i=0;i<BLOCKS_NUM*BLOCKS_NUM;i++)
		if (blocks_matrix[i]<>DELETED_BLOCK) BLOCKS_LEFT++;

	DrawBar(TEXT_X, TEXT_Y, 18,9, sc.work);
	WriteText(TEXT_X,TEXT_Y,0x80,sc.work_text,IntToStr(BLOCKS_LEFT),0);

	if (check_for_end())
	{
		copystr(RESULT_TEXT, #rezult);
		copystr(IntToStr(BLOCKS_LEFT), #rezult+strlen(#rezult));
		if (check_for_end()==1) copystr("Epic WIN!!1", #rezult);
		DrawFlatButton(BLOCK_SIZE*BLOCKS_NUM/2-70, BLOCK_SIZE*BLOCKS_NUM/2-20, 140, 40, 3, #rezult);
	}
}


void new_game()
{
	int i;

	//ïÿòü öâåòîâ èñïîëüçóåòñÿ â èãðå äëÿ êâàäðàòèêîâ, MARKED äëÿ òîãî,
	//÷òîáû îòìåòèòü êâàäðàòèêè â ïðîöåññå çàëèâêè è DELETED_BLOCK  äëÿ èõ óäàëåíèÿ
	for (i=0;i<BLOCKS_NUM*BLOCKS_NUM;i++) {
		blocks_matrix[i] = random(5);
	}
	DeleteButton(3);
}


void draw_field()
{
	int i, j;
	int current_id;

	for (i=0;i<BLOCKS_NUM;i++)
		for (j=0;j<BLOCKS_NUM;j++)
		{
			current_id = i*BLOCKS_NUM+j;
			DeleteButton(current_id+100);
			if (blocks_matrix[current_id]==DELETED_BLOCK)
			{
				DrawBar(j*BLOCK_SIZE,i*BLOCK_SIZE, BLOCK_SIZE,BLOCK_SIZE, 0xB2B4BF);
			}
			else
			{
				DefineButton(j*BLOCK_SIZE,i*BLOCK_SIZE,BLOCK_SIZE-1,BLOCK_SIZE-1, current_id+100+BT_HIDE,0);
				PutImage(blocks_matrix[current_id]*1323+#block,21,21,j*BLOCK_SIZE,i*BLOCK_SIZE);
			}
		}
}


void DrawFlatButton(dword x,y,width,height,id,text)
{
	DrawRegion_3D(x,y,width,height,sc.work_graph,sc.work_graph);
	DrawRegion_3D(x+1,y+1,width-2,height-2,0xFFFFFF,sc.work);
	DrawBar(x+2,y+2,width-3,height-3,sc.work);
	IF (id)	DefineButton(x,y,width,height,id+BT_HIDE,sc.work);
	WriteText(-strlen(text)*6+width/2+x+1,height/2-3+y,0x80,sc.work_text,text,0);
}

stop: