/*--------------------------------------------------------------------*\
	TRYST Problem #1

	Compiles under Platform :

	Turbo C++
	------------
	( BGI graphics files req. for optional GRAPHICS display )

						   ARCHIPELAGO
	A computer program to calculate number
	of Islands in a given Map ..including ..GRAPHICS.. display

									Designed and programmed by:
									   ASHISH GUPTA
									   A-2 , Jwalamukhi
									   98131
									   B.Tech
									   COMPUTER SCIENCE AND ENGINEERING
									   IITD

	The input file must be a simple text file (ASCII format) :
	consisting of 1s and 0s

	Sample :
	---------
	1010101
	1000101
	0010101
	1000101

	the height and width need not be specified
	( Automatic Detection in this program )
	( works for any m X n  Grid )

\*--------------------------------------------------------------------*/

#include <fstream.h>
#include <iostream.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
#include <graphics.h>
#include <iomanip.h>
#include <dos.h>

//_________________Global Functions_______________
void Clean_Island(int y,int x);
void Fill_Map();
void Display_Map(int**);
void Display_VGA(int** map);
void Animate(char* s,int x,int y);
void Normal();
void Reverse();
void Intro();
//_________________Global Variables___________

int icount=0;
int W=0;
int H=0;
int **map;
int **resultmap;

void main()
{

int x=0;
int y=0;
cout << endl<<endl;

clrscr();
Animate("Archipelago",35,1);
int i;
for(i=1;i<=80;i++)
{
	gotoxy(i,2);
	cout << "Í";

}

Intro();

Fill_Map();
cout << "\n\nThe input file contains \n";
cout << "---------------------------\n";

Display_Map(map);
for(y=0;y<H;y++)
	for(x=0;x<W;x++)
	{
		if (map[y][x]==1)
		{
			icount++;
			Clean_Island(y,x);
		}
	}

cout << "\nPress any key...\n\n";
getch();


cout << "\n\nThe number of islands are : " << icount;
cout << endl;
cout << "Press any key...";
getch();
cout << "\nThe Resultant Numbered Map in text mode is :";
cout << "\n------------------------------------------------";
cout << endl;
Display_Map(resultmap);

cout << "\n\nPress any key to get a color map of the island in VGA mode !";
getch();
Display_VGA(resultmap);


cout << endl << endl;
cout << "\n\n\nThank you for using this program !";
cout << "\nPress any key...";
getch();

}

//__________The main function that "recognizes" one block of island !_____
void Clean_Island(int y,int x)
{
map[y][x]=0;
resultmap[y][x]=icount;

if(y<(H-1) && map[y+1][x]==1) Clean_Island(y+1,x);
if(y>0 && map[y-1][x]==1) Clean_Island(y-1,x);

if(x<(W-1) && map[y][x+1]==1) Clean_Island(y,x+1);
if(x>0 && map[y][x-1]==1) Clean_Island(y,x-1);

if(y<(H-1) && x<W-1 && map[y+1][x+1]==1) Clean_Island(y+1,x+1);
if(y<(H-1) && x>0 && map[y+1][x-1]==1) Clean_Island(y+1,x-1);

if(y>0 && x>0 && map[y-1][x-1]==1) Clean_Island(y-1,x-1);
if(y>0 && x<W-1 && map[y-1][x+1]==1) Clean_Island(y-1,x+1);

}


void Fill_Map()
{
ifstream infile;

char filename[80];
char buffer[80];


while(1)
{
cout << "\nPlease Enter the complete MAP file name ( including path ) : ";
cin.getline(filename,80);
infile.open(filename);
if(infile==0)
{
	cout << "\nFatal Error : Error opening file";
}
else
{
	cout << "\nSuccess : The Map file was found.";
	break;
}

}

//____________Determine H and W_____________
int h=0;

while(infile)
{
	infile.getline(buffer,80);
	if (strlen(buffer)>=W && strlen(buffer)>0)
	{
		W=strlen(buffer);
		h++;
	}
}
H=h;

//_______Allocate sufficient memory for map_________
map=new int*[H+1];
for(int i=0;i<H;i++) map[i]=new int[W+1];

resultmap=new int*[H+1];
for(i=0;i<H;i++) resultmap[i]=new int[W+1];

//____________Now Store the data in Array__________
infile.close();
infile.open(filename);

h=0;
while(infile.eof()==0)
{

	infile.getline(buffer,80);
	if(strlen(buffer)>0)
	{
		for(int i=0;i<W;i++)
		{
			if(buffer[i]=='1')
			{
				map[h][i]=int(1);
				resultmap[h][i]=int(1);
			}
			else
			{
				map[h][i]=int(0);
				resultmap[h][i]=int(0);
			}
		}

		h++;
	}
}
}

void Display_Map(int **map)
{

int x,y;
for(y=0;y<H;y++)
{
	for(x=0;x<W;x++)
	{
		cout << setw(3) << int(map[y][x]);
	}
	cout << endl;
}


}


void Display_VGA(int** map)
{
int grDriver=DETECT,grMode;

char path[80];
cout << "\nTo get a VGA display ,\n";
cout << "Please enter the path where the graphics drivers ( BGI files ) are located.";
cout << "\nExample location : \\tc\\bgi";
cout << "\n\nEnter path : ";
cin.getline(path,80);


initgraph(&grDriver,&grMode,path);

if(graphresult()) cout << "\n\nPath entered is not correct";


int x,y;
int bw,bh;
bw=getmaxx()/W;
bh=getmaxy()/H;
int xc=0,yc=0;
int color=0;
int mc=getmaxcolor();

for(y=0;y<H;y++)
{
	xc=0;
	for(x=0;x<W;x++)
	{

		if(map[y][x]==0)
			setfillstyle(SOLID_FILL,1);
		else
		{
			color=map[y][x] % mc;
			if(color==1 || color==0) color+=2;
			setfillstyle(SOLID_FILL,color);

		}


		bar(xc,yc,xc+bw,yc+bh);
		xc+=bw;
	}

	yc+=bh;
	cout << endl;
}

getch();
closegraph();
}

void Animate(char* s,int x,int y)
{

int i,j,l;
char buffer[2];
buffer[1]=NULL;

l=strlen(s);
for(i=l-1;i>=0;i--)
{
	for(j=1;j<=(i+x-1);j++)
	{
		buffer[0]=s[i];
		Reverse();
		gotoxy(j,y);
		cputs(buffer);

		sound(200+j*50);
		delay(1);
		nosound();

	   if(j<(i+x-1))
	   {
			gotoxy(j,y);
			Normal();
			cputs(" ");
	   }
	}
}

Normal();
}

void Reverse()
{
	textcolor(0);
	textbackground(7);
}

void Normal()
{
	textcolor(7);
	textbackground(0);
}

void Intro()
{
cout << "\nWelcome to ARCHIPELAGO !";
cout << "\nThis program finds the number of continuous land masses";
cout << "\nin a sea. The MAP is input as a simple ASCII text file ";
cout << "\nof 1s and 0s. 1 indicates land and 0 indicates water.";
cout << "\nIt even displays a Graphical Display of the MAP using";
cout << "\ndifferent colors for islands making it easy to distinguish";
cout << "\nbetween different islands !";
cout << "\nNote : Location of Turbo C++ BGI Graphics drivers must be specified";
cout << "\nwhen asked for.\n";
cout << "\nSAMPLE FILE";
cout << "\n------------";
cout << "\n10001001";
cout << "\n10010001";
cout << "\n10001001";
cout << "\n00001001";
cout << "\n\nThe program automatically detects the width and height of the MAP";
cout << "\nNote : Allows m X n maps also.";
cout << endl ;
}
