#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define OK					0
#define ERROR				1
#define MAX_GENERATION 	200

void 	print_board(FILE *read_game);
int 	* read_size (FILE *read_game);
int 	error_check(FILE *read_game, int x, int y);
void 	board (FILE *read_game, int x, int y, int board_val[100][100]);
int 	neighbours_num(int board[100][100], int x, int y, int max_x, int max_y);


int main(int argc, char **argv){

	FILE *read_game;
	int *dimensions;
	int status,x,y,i,j;
	int board_main[100][100];
	int neigh_num_board[100][100];
	int generations=0;

	if (argc == 2){
		/* get the dimensions */
		read_game = fopen(argv[1], "r");
		dimensions = read_size(read_game);
		fclose(read_game);
		x = *dimensions;
		y = *(dimensions+2);

		/* check the file */
		read_game = fopen(argv[1],"r");
		status = error_check(read_game,x,y);
		fclose(read_game);

		if (status == ERROR){
			fprintf(stderr,"\nThe file %s is not in the correct format.\n\n",argv[1]);
			exit(1);
		}

		/* print the file */
		read_game = fopen(argv[1],"r");
		print_board(read_game);
		fclose(read_game);

	}
	else{
		fprintf(stderr,"\nYou have to type a filename...!\n\n");
		exit(1);
	}

	/* start to deploy */


	/* print board with 0 & 1 */
	/*
	for (i=0;i<x;i++){
		printf("\n");
		for (j=0; j<y; j++){
			printf("%d",board_main[i][j]);
		}
	}*/

	/* retrieve the board array with 0 & 1 */
	read_game = fopen(argv[1],"r");
	board(read_game,x,y,board_main);
	fclose(read_game);

	while (generations < MAX_GENERATION){

		/* set and <print> neighbours */
		for (i=0;i<x;i++){
			/*printf("\n");*/
			for (j=0; j<y; j++){
				neigh_num_board[i][j] = neighbours_num(board_main, i, j, x-1, y-1);
				/*printf("%d",neigh_num_board[i][j]);*/
			}
		}

		/* change array's values by using neigh_values - apply the game's rules */
		for (i=0; i<x; i++){
			for (j=0; j<y; j++){
				if ( (neigh_num_board[i][j] < 2) || (neigh_num_board[i][j] > 3) ){
					board_main[i][j] = 0;
				}

				if (neigh_num_board[i][j] == 3){
					board_main[i][j] = 1;
				}

			}
		}

		/* print this generation board */
		printf("\n");

		for (i=0; i<x; i++){
			printf("\n");
			for (j=0; j<y; j++){
				if (board_main[i][j] == 0){
					printf("-");
				}
				else{
					printf("#");
				}
			}
		}


		generations++;
	}



	printf("\n");
	return 0;
}

/****************************************************************/
/****************************************************************/
/****************************************************************/
/****************************************************************/
int * read_size (FILE *read_game){

	static int dimensions[2];

	fscanf(read_game,"%d %d",&dimensions[0],&dimensions[2]);

	return dimensions;

}

/****************************************************************/
int error_check(FILE *read_game, int x, int y){

	int i = 0,elements,j;

	/* check the corectness of the number of elements */
	elements = x * y;
	while ((j = getc(read_game)) != EOF){
		if ( ((char)j == '-') || ((char)j == '#')){
			i++;
		}
	}

	if (i != elements){
		return ERROR;
	}

	return OK;
}

/****************************************************************/
void print_board(FILE *read_game){

	int j;

	while ((j = getc(read_game)) != EOF){
		if ( ((char)j == '-') || ((char)j == '#') || ((char)j=='\n') ){
			printf("%c",(char)j);
		}
	}

	printf("\n");

}

/****************************************************************/
void board(FILE *read_game,int x,int y, int board_val[100][100]){
	int i = 0,elements,j,k=0,t=0;

	/* check the corectness of the number of elements */
	elements = x * y;
	printf("\n");

	while ((j = getc(read_game)) != EOF){
		if ( ((char)j == '-') || ((char)j == '#')){
			i++;

			if ( ((i-1)%y == 0) && ((i-1)!=0) ){
				t++;
				/*printf("\n");*/
			}
			if ((i-1)%y == 0){
				k = 0;
			}

			if ((char)j == '-'){
				board_val[t][k] = 0;
				/*printf("0");*/
			}

			if ((char)j == '#'){
				board_val[t][k] = 1;
				/*printf("1");*/
			}

			k++;
		}
	}

	printf("\n");
}

/****************************************************************/
int neighbours_num(int board[100][100], int x, int y, int max_x, int max_y){

	int neigh_num = 0;

	if ((board[x-1][y-1] == 1) && (x-1 >= 0) && (y-1 >= 0)){
		neigh_num++;
	}

	if ((board[x-1][y] == 1) && (x-1 >= 0)){
		neigh_num++;
	}

	if ((board[x-1][y+1] == 1) && (x-1 >= 0) && (y+1 <= max_y)){
		neigh_num++;
	}

	if ((board[x][y-1] == 1) && (y-1 >= 0)){
		neigh_num++;
	}

	if ((board[x][y+1] == 1) && (y+1 <= max_y)){
		neigh_num++;
	}

	if ((board[x+1][y-1] == 1) && (x+1 <= max_x) && (y-1 >= 0)){
		neigh_num++;
	}

	if ((board[x+1][y] == 1) && (x+1 <= max_x)){
		neigh_num++;
	}

	if ((board[x+1][y+1] == 1) && (x <= max_x) && (y+1 <= max_y)){
		neigh_num++;
	}

	return neigh_num;
}

