# include <stdio.h>
# include <conio.h>
# include <dos.h>
# include <stdlib.h>
# include <graphics.h>
# include <string.h>

# define WIDTH 50
# define HEIGHT 20
# define LEFTMARGIN 70
# define UPMARGIN 150

#define PORT1 0x3F8  // Port Address of COM 1
#define INTVECT 0x0C // Port's IRQ

# define XFILE file(6,43,111,111,LIGHTBLUE,LIGHTBLUE)		//ccordinates,border color,textcolor
# define EDIT edit(62,43,130,111,LIGHTBLUE,LIGHTBLUE)
# define VIEW view(115,43,230,110,LIGHTBLUE,LIGHTBLUE)
# define HELP help(195,43,305,110,LIGHTBLUE,LIGHTBLUE)

#define LEFT 80
#define TOP 170
#define RIGHT 220
#define BOTTOM 280
#define I_WHITE 15




/////////////////////////USER DEFINED FUNCTIONS prototypes/////////////////////////////

///////////COMMUNICATION RELATED FUNCTIONS////////
void port_init();
void port_dinit();
void interrupt PORT1INT();
void send(char[]);
void chat();
int fget();
int fsend();

/////////////////STRING INPUT/////////////////////
void xgets(char *);
void xputs(char *);
void showcursor();

/////////////////MENU CONTROL FUNCTIONS/////////////
void menu(void);
void menucontrol(void);
void file(int,int,int,int,int,int);
void edit(int,int,int,int,int,int);
void view(int,int,int,int,int,int);
void help(int,int,int,int,int,int);
void erase(void);
void chatwindow();
void draw_dbox(char [10],char [22],char [22],char [22]);
void clear_dbox();
void fade(int,int,int,int,int, char*);
void credits();
void future();
void statusbar(char mssg[80],int);
void shortkeys();
void splash();

int bufferin =0, bufferout = 0;
char ch='a', buffer[512];
int maxx,maxy, bkcolor=BLUE;
void *dbox;
void interrupt (*oldport1isr)();

///////////////////////////MAIN///////////////////////////////
int main()
{
int driver=DETECT,mode;

initgraph(&driver,&mode,"\\tc\\bgi");

maxx=getmaxx(),maxy=getmaxy();
splash();
port_init();
menu();

while(371)
	{
	menucontrol();
	}
return 0;
}


///////////////PORT_INIT   INITIALIZE PORT////////////////////
void port_init()
{
 outportb(PORT1 + 1 , 0);        /* Turn off interrupts - Port1 */

 oldport1isr = getvect(INTVECT); /* Save old Interrupt Vector of later
				    recovery */

 setvect(INTVECT, PORT1INT);     /* Set Interrupt Vector Entry */
				 /* COM1 - 0x0C */
				 /* COM2 - 0x0B */
				 /* COM3 - 0x0C */
				 /* COM4 - 0x0B */

 /*         PORT 1 - Communication Settings         */

 outportb(PORT1 + 3 , 0x80);  /* SET DLAB ON */
 outportb(PORT1 + 0 , 0x0C);  /* Set Baud rate - Divisor Latch Low Byte */
				/* Default 0x03 =  38,400 BPS */
				/*         0x01 = 115,200 BPS */
				/*         0x02 =  57,600 BPS */
				/*         0x06 =  19,200 BPS */
				/*         0x0C =   9,600 BPS */
				/*         0x18 =   4,800 BPS */
				/*         0x30 =   2,400 BPS */
 outportb(PORT1 + 1 , 0x00);  /* Set Baud rate - Divisor Latch High Byte */
 outportb(PORT1 + 3 , 0x03);  /* 8 Bits, No Parity, 1 Stop Bit */
 outportb(PORT1 + 2 , 0xC7);  /* FIFO Control Register */
 outportb(PORT1 + 4 , 0x0B);  /* Turn on DTR, RTS, and OUT2 */

 outportb(0x21,(inportb(0x21) & 0xEF));  /* Set Programmable Interrupt Controller */
					 /* COM1 (IRQ4) - 0xEF  */
					 /* COM2 (IRQ3) - 0xF7  */
					 /* COM3 (IRQ4) - 0xEF  */
					 /* COM4 (IRQ3) - 0xF7  */

 outportb(PORT1 + 1 , 0x01);  /* Interrupt when data received */
}


////////////////////PORT_DINIT PORT INITIALIZATION////////////////////////
void port_dinit()
{
 outportb(PORT1 + 1 , 0);       /* Turn off interrupts - Port1 */
 outportb(0x21,(inportb(0x21) | 0x10));  /* MASK IRQ using PIC */
					 /* COM1 (IRQ4) - 0x10  */
					 /* COM2 (IRQ3) - 0x08  */
					 /* COM3 (IRQ4) - 0x10  */
					 /* COM4 (IRQ3) - 0x08  */
 setvect(INTVECT, oldport1isr); /* Restore old interrupt vector */
}

//////////////////INTERRUPT FUNCTION////////////////
void interrupt PORT1INT()  /* Interrupt Service Routine (ISR) for PORT1 */
{
  int c;
 do { c = inportb(PORT1 + 5);
	if (c & 1) {buffer[bufferin] = inportb(PORT1);
		  bufferin++;
		  if (bufferin == 512) {bufferin = 0;}}
    }while (c & 1);
 outportb(0x20,0x20);	//end of interrupt
}


//////////////////////SEND//////////////////////////////
void send(char mess[512])
{
int a;
for(a=0;a<=strlen(mess);a++)
	{
	if(a%10==0)
		delay(10);
	outportb(PORT1,*(mess+a));
	delay(1);	// home only
	}
outportb(PORT1,'\r');
}

////////////////////CHAT FUNCTION/////////////////////
void chat()
{
char messbuff [20][512],*temp="nick:",nickhis[20]="Him: ",nickmine[20]="Me:",optn;
int nicklen1=5,nicklen2=4,row=UPMARGIN;
int chcount=0,ctp=0,messcount=0;
int lbox[10]={LEFTMARGIN+1,UPMARGIN+(HEIGHT*10)+15+1,LEFTMARGIN+(WIDTH*10)-1,UPMARGIN+(HEIGHT*10)+15,LEFTMARGIN+(WIDTH*10)-1,UPMARGIN+(HEIGHT*10)+70,LEFTMARGIN,UPMARGIN+(HEIGHT*10)+70,LEFTMARGIN+1,UPMARGIN+(HEIGHT*10)+15+1};
int ubox[10]={LEFTMARGIN+1,UPMARGIN+1,LEFTMARGIN+(WIDTH*10)-1,UPMARGIN,LEFTMARGIN+(WIDTH*10)-1,UPMARGIN+(HEIGHT*10),LEFTMARGIN+1,UPMARGIN+(HEIGHT*10),LEFTMARGIN+1,UPMARGIN+1};

draw_dbox("Input","Enter Nickname: ","","");
gotoxy(27,16);
 gets(nickmine);
clear_dbox();

strcat(temp,nickmine);
strcat(nickmine,":");
nicklen2=strlen(nickmine);
send(temp);

do {
     if(messcount>19)
	  messcount=0;

     if (bufferin != bufferout)
				{
				ch = buffer[bufferout];
				*(messbuff[messcount]+chcount++)=ch;
				bufferout++;

				if(buffer[bufferout-1]=='\r')
					{
					*(messbuff[messcount]+chcount)='\0';
					chcount=0;
					ctp=1;
					}

				if (bufferout == 512)
				   bufferout = 0;
				}
     if(ctp==1)
	{

	if(*(messbuff[messcount]+4)==':')
	  {
	  temp=strchr(messbuff[messcount],':');
	  strcpy(nickhis,temp+1);
	  strcat(nickhis,":");
	  nicklen1=strlen(nickhis);
	  }


	if((strcmp("BEEP",messbuff[messcount]))==0)
	  {
	  sound(500);
	  delay(200);
	  nosound();
	  }

	row+=10;
	if(row>UPMARGIN+HEIGHT*10-10)
		{
		row=UPMARGIN+10;
		setfillstyle(SOLID_FILL,WHITE);
		fillpoly(5,ubox);
		}

	moveto(LEFTMARGIN+(nicklen1*9),row);
	setcolor(4);
	outtextxy(LEFTMARGIN+3,row,nickhis);
	setcolor(BLACK);
	row+=(strlen(messbuff[messcount])/50)*10;
	xputs(messbuff[messcount++]);
	sound(500);
	delay(200);
	nosound();
	ctp=0;
	}

     if (kbhit())
     {
     moveto(LEFTMARGIN+10,UPMARGIN+(HEIGHT*10)+20);
     setcolor(BLACK);
     xgets(messbuff[messcount]);
     send(messbuff[messcount]);

     if(*(messbuff[messcount]+4)==':')
	  {
	  temp=strchr(messbuff[messcount],':');
	  strcpy(nickmine,temp+1);
	  strcat(nickmine,":");
	  nicklen2=strlen(nickmine);
	  }
     if(*(messbuff[messcount]+0)=='\x1b')
	{
	draw_dbox("Question","Really Quit","","[Y]    [N]");
	optn=getch();
	if(optn=='y' || optn=='Y') break;
	clear_dbox();
	}

     setfillstyle(SOLID_FILL,WHITE);
     fillpoly(5,lbox);
	row+=10;
	if(row>UPMARGIN+HEIGHT*10-10)
		{
		row=UPMARGIN+10;
		setfillstyle(SOLID_FILL,WHITE);
		fillpoly(5,ubox);
		}

	moveto(LEFTMARGIN+(nicklen2*9),row);
	setcolor(3);
	outtextxy(LEFTMARGIN+3,row,nickmine);
	setcolor(BLACK);
	row+=(strlen(messbuff[messcount])/50)*10;
	xputs(messbuff[messcount++]);
     }

    } while (392);
}


////////////////////FGET  GET FILE FROM PORT////////////////////
fget()
{
char *temp, *fname,optn;
int count=0;
FILE *file;

draw_dbox("Save As","Enter Filename: ","","");
moveto(215,225);
setcolor(WHITE);
xgets(fname);
clear_dbox();

draw_dbox("Warning","Existing file will be","ovrwritten. Overwrite?","[Y]   [N]");
gotoxy(27,16);
optn=getch();
if(optn=='n' || optn=='N')
{
clear_dbox();
fget();
}

draw_dbox("File Receive","Receiving File now:","Press ESC to Pause","Wait");


file=fopen(fname,"wb");

do {
if(kbhit())
	if((optn=getch())=='\x1b')
	  {
	   draw_dbox("Caution!","Cancel Download? ","","[Y]   [N]");
	   optn=getch();
	   clear_dbox();
	   if(optn=='y' || optn=='Y')
	   fcloseall();
	   return 0;
	  }
if (bufferin != bufferout)
	{
	ch = buffer[bufferout++];
	if (bufferout == 512) bufferout = 0;
	if(ch!=21)
	  {
	  if(ch!=29 && ch!=30)
		gotoxy(27,16);
		printf("%d",count++);
		putc(ch,file);
	  }
	}
} while (ch !=21);
clear_dbox();
draw_dbox("Message","Download complete","Press Any key","");
getch();
clear_dbox();
fcloseall();
return 0;
}


/////////////////FSEND  SENDS FILE TO PORT///////////////////
fsend()
{
unsigned long int size,per,count;
FILE * file;

unsigned char c,*temp,*fname;
char optn;

draw_dbox("File Transfer","Enter Filename: ","","");
moveto(215,225);
setcolor(WHITE);
xgets(fname);
clear_dbox();

file=fopen(fname,"rb");

if(file==NULL)
{
draw_dbox("Error","Can't Open File. It may","not exist. Continue?","[Y]   [N]");
optn=getch();
	if(optn=='y' || optn=='Y')
	{
	clear_dbox();
	fsend();
	}
clear_dbox();
fcloseall();
return 0;
}

for(size=0;(ch=getc(file))!=EOF;size++);
(void)fseek(file,0,0);

draw_dbox("Confirmation","Start Sending?","","[Y]   [N]");
optn=getch();
if(optn=='n' || optn=='N')
{
clear_dbox();
fcloseall();
return 0;
}

draw_dbox("File Transfer","File is being sent","","");

for(count=0;(ch=getc(file))!=EOF;count++)
	{
	outportb(PORT1,ch);
	gotoxy(36,16);
	per=count*100/(size-1);
	printf("%ld %",per);
	delay(1);		//at home computer 1
	}

outportb(PORT1,21);	//end of file marker
clear_dbox();
draw_dbox("File Transfer","Transfer Complete","Press Any Key To","Continue");
getch();
clear_dbox();
fcloseall();
return 0;
}


//////////////////////////////////XGETS///////////////////////////
void xgets(char *temp)
{
char ch[2],chtemp;
int count=0,x,y,xinit,ctemp=0;
int chblock[8],color,prevcolor;
x=xinit=getx();
y=gety();
ch[1]='\0';
color=getpixel(x+13,y+2);
prevcolor=getcolor();
start:
while((ch[0]=getch())!='\r')
{
	if(x > (LEFTMARGIN+WIDTH*10-10))		//move to next line
		{
		 chtemp=ch[0];
		  while(*(temp+count)!=' ')
		    {
		    count--;
		    ctemp++;
		    x-=9;
		    setcolor(color);
		    setfillstyle(1,color);

		    chblock[0]=x;
		    chblock[1]=y;
		    chblock[2]=x+7;
		    chblock[3]=y;
		    chblock[4]=x+7;
		    chblock[5]=y+8;
		    chblock[6]=x;
		    chblock[7]=y+8;

		    fillpoly(4,chblock);
		    setcolor(prevcolor);
		    if(ctemp>20)
			break;
		    }

		 x=xinit;
		 y+=10;

		 while(ctemp>0) //moves incomplete word to next line
		  {
		  ch[0]=*(temp+count++);
		  ctemp--;
		  outtextxy(x,y,ch);
		  x+=9;
		   }
		ch[0]=chtemp;
		}

	if(ch[0]==8)	// delete characters on backspace
	  {
	  count--;
	  x-=9;

	     if(x < xinit)	//stop backspacing at initial position
		{
		x=xinit;
		count++;
		sound(100);
		delay(10);
		nosound();
		goto start;
		}

	  setcolor(color);
	  setfillstyle(1,color);

	  chblock[0]=x;
	  chblock[1]=y;
	  chblock[2]=x+7;
	  chblock[3]=y;
	  chblock[4]=x+7;
	  chblock[5]=y+8;
	  chblock[6]=x;
	  chblock[7]=y+8;

	  fillpoly(4,chblock);
	  setcolor(prevcolor);
	  moveto(x,y);
	  showcursor();
	  goto start;
	  }

*(temp+count)= ch[0]; //prints character in the current font in graphics mode
outtextxy(x,y,ch);
count++;
x+=9;
moveto(x,y);
showcursor();
}

*(temp+count)='\0';
}


//////////////////////////XPUTS//////////////////////////////
void xputs(char *temp)
{
char ch[2],chtemp;
int count=0,x,y,xinit,ctemp=0;
int chblock[8],color,prevcolor;
x=xinit=getx();
y=gety();
ch[1]='\0';
color=getpixel(x+13,y+2);
prevcolor=getcolor();

while( (ch[0]= *(temp+count) )!='\0')
{
     if(x > (LEFTMARGIN+WIDTH*10-10))		//move to next line
		{
		 chtemp=ch[0];
		  while(*(temp+count)!=' ')
		    {
		    count--;
		    ctemp++;
		    x-=9;
		    setcolor(color);
		    setfillstyle(1,color);

		    chblock[0]=x;
		    chblock[1]=y;
		    chblock[2]=x+7;
		    chblock[3]=y;
		    chblock[4]=x+7;
		    chblock[5]=y+8;
		    chblock[6]=x;
		    chblock[7]=y+8;

		    fillpoly(4,chblock);
		    setcolor(prevcolor);
		    if(ctemp>20)
			break;
		    }

		 x=xinit;
		 y+=10;

		 while(ctemp>0) //moves incomplete word to next line
		  {
		  ch[0]=*(temp+ count++);
		  ctemp--;
		  outtextxy(x,y,ch);
		  x+=9;
		   }
		ch[0]=chtemp;
		}

outtextxy(x,y,ch);
count++;
x+=9;
}
}

///////////////////////////SHOWCURSOR/////////////////////////
void showcursor()
{
int x,y,color,showcolor;
x=getx();
y=gety();
color=getpixel(x+12,y+2);
showcolor=getcolor();

while(!kbhit())
{
setcolor(showcolor);
line(x,y-2,x,y+8);
delay(200);
if(kbhit())break;
setcolor(color);
line(x,y-2,x,y+8);
delay(100);
}
setcolor(color);
line(x,y-2,x,y+8);
setcolor(showcolor);
}


///////////////////////MENU//////////////////////
void menu(void)
{
cleardevice();

setbkcolor(BLUE);
setcolor(LIGHTBLUE);

rectangle(1,1,maxx-1,maxy-1); //big rect.
rectangle(2,2,maxx-2,maxy-2); // for 3d view

line(1,20,maxx-1,20);         // title bar
line(1,21,maxx-1,21);         // for 3d view

line(1,40,maxx-1,40);         // menu bar
line(1,41,maxx-1,41);         // for 3d view

line(1,maxy-20,maxx-1,maxy-20);  // status bar
line(1,maxy-21,maxx-1,maxy-21);  // for 3d view

line(maxx-20,20,maxx-20,maxy-20);  //scroll bar
line(maxx-21,20,maxx-21,maxy-20);  // for 3d view

///////////////////////////////////////////////////////////////////////
rectangle(maxx-20,5,maxx-10,16);  rectangle(maxx-21,5,maxx-10,17);
line(maxx-18,7,maxx-12,14); line(maxx-12,7,maxx-18,14);    // close button

rectangle(maxx-35,5,maxx-25,16); rectangle(maxx-36,5,maxx-25,17);
rectangle(maxx-33,7,maxx-29,12); rectangle(maxx-31,9,maxx-27,14);  // max. button

rectangle(maxx-50,5,maxx-40,16); rectangle(maxx-51,5,maxx-40,17);
line(maxx-48,14,maxx-42,14);                           // minimize button

setfillstyle(SOLID_FILL,LIGHTGRAY); // filing color in title bar
floodfill(3,10,LIGHTBLUE);
////////////////////////////////////////////////////////////////////////

setcolor(WHITE);
outtextxy(17,7,"MYSIR Instant Messenger");

settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
setcolor(LIGHTBLUE);
outtextxy(18,28,"File ³  Edit  ³  View  ³  Help");
setcolor(YELLOW);
outtextxy(18,28,"F       E        V        H");
////////////////////////////////////////////////////////////////////////

setcolor(LIGHTBLUE);
setfillstyle(SOLID_FILL,bkcolor);
floodfill(12,52,LIGHTBLUE);    //  background color SOLID_FILL 7 9
setfillstyle(CLOSE_DOT_FILL,WHITE);
floodfill(12,maxy-5,LIGHTBLUE); // color filing small box
floodfill(maxx-5,32,LIGHTBLUE); // color filing scroll bar
}

//////////////////////////MENU CONTROL////////////////////
void menucontrol(void)
{

setfillstyle(SOLID_FILL,BLUE);

if(!(ch==18 || ch==33 || ch==35 || ch==43))
	 ch=getch();

if(ch==0)    // IF ALT KEY PRESS
  ch=getch();

switch(ch)
{                          /*bordercolor,txtcolor*/

case 33  :  XFILE ; //case ALT+F :
	    break;

case 18 :   EDIT ; //case  ALT+E :
	    break;

case 47 :   VIEW ; //case  ALT+V :
	    break;

case 35 :   HELP ; //case  ALT+H :
	    break;

default :   menucontrol();

}
}


//////////////////////////////FILE/////////////////////
void file(int x1,int y1,int x2,int y2,int bordercolor,int txtcolor)
{
char fopt,optn;
static int row=0;

setviewport(x1,y1,x2,y2,1);  // setviewport and clears the viewport
clearviewport();
setviewport(0,0,maxx,maxy,1);

setcolor(bordercolor);
setfillstyle(SOLID_FILL,BLUE);
rectangle(x1,y1,x2,y2);
rectangle(x1,y1,x2+1,y2+1);
setcolor(BLACK);
rectangle(x1-1,y1-1,x2+2,y2+2);
setcolor(bordercolor);
floodfill(x1+6,y1+3,bordercolor);
outtextxy(x1+3,y1+40,"____________");
setcolor(txtcolor);

rectangle(x1+4,y1+3+row,x2-4,y1+17+row); // highlighting
setfillstyle(SOLID_FILL,WHITE);
floodfill(x1+12,y1+12+row,bordercolor);


outtextxy(x1+6,y1+7,"Start Chat");
outtextxy(x1+6,y1+22,"Send File");
outtextxy(x1+6,y1+37,"Receive File");
outtextxy(x1+6,y1+52,"Exit");

while(390)    // infinite loop
{
fopt=getch();

if(fopt==0)
    fopt=getch();

switch(fopt)
{
case 80  :  // down key
	    if(row<45)   // highlighting next line
		row+=15;
	    else
		row=0;
	    XFILE; break;

case 72  :  // up key
	    if(row>0)
		row-=15;
	    else
		row=45;
	    XFILE; break;

case 75 :   // right key
	    row=0; erase(); HELP;
	    break;

case 77 :   // left key
	    row=0; erase(); EDIT;
	    break;

case '\r' :   switch(row)
		{
		case 0  :
			 erase();
			 chatwindow(); // start chat
			 chat();
			 menu();
			 break;

		case 15 :
			erase();
			fsend();
			menu();
			break;        // send file

		case 30 :
			 erase();
			 fget();
			 menu();
			 break;        // receive file

		case 45 :
			erase();
			draw_dbox("Question?","Really Quit:","","[Y]   [N]");
			optn=getch();
			if(optn=='y' || optn=='Y')
				exit(0);
			clear_dbox();
			menu();
			break;


		}
		row=0;
		break;

case '\x1b':  erase(); ch='a';
		menucontrol(); row=0;
		break;

default    :   //XFILE;
		 break;

} //  end switch
} //  end file
} //  end file



////////////////////////EDIT/////////////////////////////////
void edit(int x1,int y1,int x2,int y2,int bordercolor,int txtcolor)
{
static int row=0; char eopt;

setviewport(x1,y1,x2,y2,1);
clearviewport();
setviewport(0,0,maxx,maxy,1);

rectangle(x1,y1,x2,y2);
rectangle(x1,y1,x2+1,y2+1);
setcolor(BLACK);
rectangle(x1-1,y1-1,x2+2,y2+2);
setcolor(LIGHTBLUE);
floodfill(x1+5,y1+3,bordercolor);
outtextxy(x1+1,y1+10,"________");

rectangle(x1+4,y1+3+row,x2-4,y1+17+row); // HIGHLIGHTING OPTIONS
setfillstyle(SOLID_FILL,WHITE);
floodfill(x1+6,y1+10+row,bordercolor);

setcolor(txtcolor);
outtextxy(x1+8,y1+7 ,"Undo");
outtextxy(x1+8,y1+22,"Cut");
outtextxy(x1+8,y1+37,"Copy");
outtextxy(x1+8,y1+52,"Paste");

while(390)    // infinite loop
{
eopt=getch();

if(eopt==0)
    eopt=getch();

switch(eopt)
{
case 80  :  // down key
	    if(row<45)
		row+=15; // highlighting next line
	    else
		row=0;
	    erase(); EDIT;
	    break;

case 72  :  // up key
	    if(row>0)
		row-=15;
	    else
		row=45;
	    erase(); EDIT;
	    break;

case 75 :   // left key
	    row=0; erase(); XFILE ;
	    break;

case 77 :   // right key
	    row=0; erase(); VIEW ;
	    break;

case '\r' :   switch(row)
	      {
		case 0  :  // undo

		case 15 :  //cut

		case 30 :  //copy

		case 45 :  	//paste
		erase();
		draw_dbox("Message","This feature will be","availiable soon","");
		statusbar("Press Any Key to go to Main Menu",BLUE);
		getch();
		clear_dbox();
		menu();
		}
		row=0;
		break;

case '\x1b':  erase(); ch='a';
		menucontrol(); row=0;
		break;

default    :  //erase(); EDIT;
		break;

} // end switch
} // end while
} // end edit



//////////////////////////////VIEW//////////////////////////
void view(int x1,int y1,int x2,int y2,int bordercolor,int txtcolor)
{
static int row=0; char vopt;

setviewport(x1,y1,x2,y2,1);  // setviewport and clears the viewport
clearviewport();
setviewport(0,0,maxx,maxy,1);

rectangle(x1,y1,x2,y2);
rectangle(x1,y1,x2+1,y2+1);
setcolor(BLACK);
rectangle(x1-1,y1-1,x2+2,y2+2);
setcolor(LIGHTBLUE);
floodfill(x1+7,y1+5,bordercolor);
outtextxy(x1+5,y1+11,"____________");

rectangle(x1+4,y1+3+row,x2-4,y1+17+row); // HIGHLIGHTING OPTIONS
setfillstyle(SOLID_FILL,WHITE);
floodfill(x1+6,y1+12+row,bordercolor);

setcolor(txtcolor);
outtextxy(x1+7,y1+7,"Set Fonts");
outtextxy(x1+7,y1+22,"Set Textcolor");
outtextxy(x1+7,y1+37,"Set Bkcolor");

while(390)    // infinite loop
{
vopt=getch();

if(vopt==0)
    vopt=getch();

switch(vopt)
{
case 80  :  // down key
	    if(row<30)
		row+=15; // highlighting next line
	    else
		row=0;
	    erase(); VIEW; break;

case 72  :  // up key
	    if(row>0)
		row-=15;
	    else
		row=30;
	    erase(); VIEW;
	    break;

case 75 :   // left key
	    row=0; erase(); EDIT ;
	    break;

case 77 :   // right key
	    row=0; erase(); HELP ;
	    break;

case '\r' :   switch(row)
	      {
		case 0  :          // set fonts

		case 15 :          // set text color

		case 30 :          // set bkcolor

		case 45 :
		erase();
		draw_dbox("Message","This feature will be","availiable soon","");
		statusbar("Press Any Key to go to Main Menu",BLUE);
		getch();
		clear_dbox();
		menu();
	      }
		row=0;
		break;

case '\x1b':  erase(); ch='a';
	      menucontrol(); row=0;
		break;

default    :  //erase(); VIEW;
		break;

} // end switch
} // end while
} // end view



/////////////////////////////////HELP////////////////////////
void help(int x1,int y1,int x2,int y2,int bordercolor,int txtcolor)
{
static int row=0; char hopt;

setviewport(x1,y1,x2,y2,1);  // setviewport and clears the viewport
clearviewport();
setviewport(0,0,maxx,maxy,1);

rectangle(x1,y1,x2,y2);
rectangle(x1,y1,x2+1,y2+1);
setcolor(BLACK);
rectangle(x1-1,y1-1,x2+2,y2+2);
setcolor(LIGHTBLUE);
floodfill(x1+5,y1+3,bordercolor);
outtextxy(x1+3,y1+11,"____________");

rectangle(x1+4,y1+3+row,x2-2,y1+17+row);  // HIGHLIGHTING OPTIONS
setfillstyle(SOLID_FILL,WHITE);
floodfill(x1+12,y1+12+row,bordercolor);

setcolor(txtcolor);
outtextxy(x1+5,y1+7,"Help");
outtextxy(x1+5,y1+22,"Shortcut Keys");
outtextxy(x1+5,y1+37,"Future");
outtextxy(x1+5,y1+52,"About Us");

while(390)    // infinite loop
{
hopt=getch();

if(hopt==0)
    hopt=getch();

switch(hopt)
{
case 80  :  // down key
	    if(row<45)
		row+=15; // highlighting next line
	    else
		row=0;
	    erase(); HELP ; break;

case 72  :  // up key
	    if(row>0)
		row-=15;
	    else
		row=45;
	    erase(); HELP ;
	    break;

case 75 :   // left key
	    row=0; erase(); VIEW ;
	    break;

case 77 :   // left key
	    row=0; erase(); XFILE ;
	    break;

case '\r' :   switch(row)
		{
		case 0  :                // Help
			   erase();
			   shortkeys();
			   menu();
			   break;        // Shortcut Keys
			 break;

		case 15 :
			   erase();
			   shortkeys();
			   menu();
			   break;        // Shortcut Keys

		case 30 :
			   erase();
			   future();
			   menu();
			   break;        // Future

		case 45 :
			    credits();
			    menu();
			    break;        // About Us

		}
		row=0;
		break;

case '\x1b':  row=0; erase(); ch='a';menucontrol();
		break;

default    :  //erase(); HELP ;
		break;

} // end switch
} // end while
}


/////////////////////////ERASE//////////////////////////
void erase(void)
{
static int a[10]={4,42,312,42,312,125,4,125,4,42};

setcolor(bkcolor);
setfillstyle(SOLID_FILL,bkcolor);
fillpoly(4,a);
setcolor(LIGHTBLUE);
setfillstyle(SOLID_FILL,BLUE);
}



//////////////////////////CHAT WINDOW///////////////////
void chatwindow()
{
erase();

setcolor(LIGHTBLUE);

rectangle(LEFTMARGIN,127,LEFTMARGIN+(WIDTH*10),147); // Title Bar
rectangle(LEFTMARGIN-1,128,LEFTMARGIN+(WIDTH*10)+1,148); // Title Bar
setfillstyle(SOLID_FILL,CYAN);
floodfill(105,138,LIGHTBLUE);

rectangle(maxx-125,131,maxx-115,144); rectangle(maxx-126,132,maxx-114,143);
line(maxx-123,141,maxx-117,141);                           // minimize button

rectangle(maxx-110,131,maxx-100,144); rectangle(maxx-111,132,maxx-99,143);
rectangle(maxx-108,134,maxx-104,139); rectangle(maxx-106,136 ,maxx-102,141);  // max. button

rectangle(maxx-95,131,maxx-85,144);  rectangle(maxx-96,132,maxx-84,143);
line(maxx-84,132,maxx-96,143); line(maxx-84,143,maxx-96,132);    // close button

setfillstyle(SOLID_FILL,LIGHTRED);
floodfill(105,148,LIGHTBLUE);
setcolor(WHITE);
outtextxy(80,135,"Chat Window");

setcolor(LIGHTBLUE);
setfillstyle(SOLID_FILL,WHITE);
rectangle(LEFTMARGIN,UPMARGIN,LEFTMARGIN+(WIDTH*10),UPMARGIN+(HEIGHT*10)); // Upper box
rectangle(LEFTMARGIN-1,UPMARGIN-1,LEFTMARGIN+(WIDTH*10)+1,UPMARGIN+(HEIGHT*10)+1); // Upper box
floodfill(LEFTMARGIN+4,UPMARGIN+4,LIGHTBLUE);

rectangle(LEFTMARGIN,UPMARGIN+(HEIGHT*10)+15,LEFTMARGIN+(WIDTH*10),UPMARGIN+(HEIGHT*10)+70);// lower box
rectangle(LEFTMARGIN-1,UPMARGIN+(HEIGHT*10)+15-1,LEFTMARGIN+(WIDTH*10)+1,UPMARGIN+(HEIGHT*10)+71);
floodfill(LEFTMARGIN+4,UPMARGIN+(HEIGHT*10)+20,LIGHTBLUE);

setcolor(BLACK); // upper box
rectangle(LEFTMARGIN-2,UPMARGIN-2,LEFTMARGIN+(WIDTH*10)+2,UPMARGIN+(HEIGHT*10)+2);

//LOWER BOX
rectangle(LEFTMARGIN-2,UPMARGIN+(HEIGHT*10)+16,LEFTMARGIN+(WIDTH*10)+2,UPMARGIN+(HEIGHT*10)+71);

rectangle(LEFTMARGIN-2,127,LEFTMARGIN+(WIDTH*10)+2,147); // Title Bar
}


//DIALOGUE BOX syntax: dbox(title,message line 1,message line 2,choice(s));
void draw_dbox(char string[10],char mssg1[22],char mssg2[22],char choice[22])
{
int poly[10]={200,185,400,185,400,200,200,200,200,185};
int poly2[10]={200,200,400,200,400,276,200,276,200,200};
unsigned int size,prevcolor;
struct fillsettingstype fillinfo;
getfillsettings(&fillinfo);
prevcolor=getcolor();

   size = imagesize(197, 182, 407, 279);
   dbox = malloc(size);
   getimage(197, 182, 407, 279, dbox);

setfillstyle(SOLID_FILL,BLACK);
fillpoly(5,poly2);

setcolor (LIGHTGRAY);
rectangle(200,184,400,275);
rectangle(199,185,401,276);
setfillstyle(1,CYAN);
fillpoly(5, poly);
setcolor(BLACK);
outtextxy(205,189,string);

setcolor (LIGHTBLUE);
outtextxy(210,210,mssg1);
outtextxy(210,225,mssg2);
outtextxy(270,260,choice);
setfillstyle(fillinfo.pattern,fillinfo.color);
setcolor(prevcolor);
}


///////////////CLEAR DIALOG BOX//////////////////////
void clear_dbox()
{
putimage(197, 182, dbox, COPY_PUT);
free(dbox);
}


///////////////////////////FADE////////////////////////
void fade(int r,int g,int b,int x,int y,char *string)
{
struct palettetype palnew,palprev;
int i;

getpalette(&palprev);
getpalette(&palnew);


for (i=0; i<palnew.size; i++)
	setrgbpalette(palnew.colors[i], i*r, i*g, i*b);

for(i=0;i<palnew.size;i++)
	{
	setcolor(i);
	outtextxy(x,y,string);
	delay(200);
	}

for(i=palnew.size-1;i>0;i--)
	{
	setcolor(i);
	outtextxy(x,y,string);
	delay(300);
	}
}


///////////////////CREDITS//////////////////////
void credits()
{
int driver=DETECT,mode;
initgraph(&driver, &mode, "//tc//bgi");

while(!kbhit())
{
fade(3,0,0,240,200,"MYSIR Instant Messeger");
if (kbhit())
	break;

fade(3,0,0,255,200,"Version 2.01.10");
if (kbhit())
	break;

fade(3,0,0,280,200,"DEVELOPERS");
if (kbhit())
	break;
fade(3,0,0,160,200,"M. Yousuf Bin Azhar     musuf@yahoo.com");
if (kbhit())
	break;

fade(3,0,0,160,200,"Mehmood Usman     mehmoodu@hotmail.com");
if (kbhit())
	break;

fade(3,0,0,150,200,"Suleman Mumtaz     sulemanmumtaz@hotmail.com");
if (kbhit())
	break;

fade(3,0,0,180,200,"Razi Ur Rehman     meetrazi@yahoo.com");
if (kbhit())
	break;

fade(3,0,0,160,200,"Israr Ahmed     alibawa40@hotmail.com");
if (kbhit())
	break;

fade(3,0,0,180,200,"Date of completion: 24 October 2001");
if (kbhit())
	break;

fade(3,0,0,230,200,"Made by students of:");
if (kbhit())
	break;

fade(3,0,0,100,200,"Sir Syed University of Engineering & Technology, Karachi");
if (kbhit())
	break;

}
initgraph(&driver, &mode, "//tc//bgi");
}


/////////////////////////FUTURE INFO////////////////////////
void future()
{
int prevcolor;
prevcolor=getcolor();
setcolor(RED);
outtextxy(200,60,"MYSIR INSTANT MESSENGER: FUTURE");
setcolor(14);
outtextxy(30,80,"This software has been made as a project by second semester students of");
outtextxy(10,100,"Sir Syed University of Engineering & Technology. This version of our");
outtextxy(10,120,"software is in fact a first step towards hardware interfacing and serial");
outtextxy(10,140,"communication. And the software has all the capabilities to be enhanced");
outtextxy(10,160,"whenever the need arises. In this software we are basically chatting,");
outtextxy(10,180,"and transferring files that are in text mode. But it will be possible");
outtextxy(10,200,"that through this software we can peform serial communication in larger ");
outtextxy(10,220,"network and even play two player games. And the idea  conceived will be ");
outtextxy(10,240,"implemented inshallah in the coming days very soon.");

outtextxy(15,375,"- M. Yousuf Bin Azhar     musuf@yahoo.com");
delay(400);
outtextxy(15,390,"- Mehmood Usman           mehmoodu@hotmail.com");
delay(400);
outtextxy(15,405,"- Suleman Mumtaz          sulemanmumtaz@hotmail.com");
delay(400);
outtextxy(15,420,"- Israr Ahmed             alibawa40@hotmail.com");
delay(400);
outtextxy(15,435,"- Razi Ur Rehman          meetrazi@yahoo.com");
delay(600);
statusbar("Press Any key to go to Main Menu.",BLUE);

getch();
setcolor(prevcolor);
}


///////////////////// STATUSBAR//////////////////////////
void statusbar(char mssg[80],int color)
{
setcolor (LIGHTBLUE);
setfillstyle(SOLID_FILL,WHITE);
rectangle(3,459,638,476);
floodfill(5,470,LIGHTBLUE);
setcolor (color);
outtextxy(5,464,mssg);
}


//////////////////////SHORT KEYS INFO/////////////////////
void shortkeys()
{
int prevcolor;
prevcolor=getcolor();

setcolor(RED);
outtextxy(260,60,"SHORT CUT KEYS");
outtextxy(10,80,"MENU COMMANDS");
outtextxy(10,220,"CHAT COMMANDS");

setcolor(YELLOW);
outtextxy(10,100,"ALT+F---------------------Opens File Menu");
outtextxy(10,120,"ALT+E---------------------Opens Edit Menu");
outtextxy(10,140,"ALT+V---------------------Opens View Menu");
outtextxy(10,160,"ALT+H---------------------Opens Help Menu");
outtextxy(10,180,"ARROW KEYS----------------Select Options in Menus");
outtextxy(10,200,"ENTER---------------------Run Selected Option");

outtextxy(10,240,"nick:<nickname>-----------Changes Nickname during chat");
outtextxy(10,260,"ECS then ENTER------------Exits Chat window");

statusbar("Press Any key to go to Main Menu.",BLUE);
getch();
setcolor(prevcolor);
}


void splash()
{
int i,j;
void *gbuff,*gbuff1,*halfbuff;
int f=0,s=0,t=0;
unsigned size; /*size of buffer */
int prevcolor;
prevcolor=getcolor();

	setcolor(BROWN);
	rectangle(LEFT,TOP,RIGHT,BOTTOM); /* Ist monitor */
	rectangle(LEFT+10,TOP+10,RIGHT-10,BOTTOM-10);
	rectangle(RIGHT-22,BOTTOM-6,RIGHT-10,BOTTOM-2); /* ON/OFF button */
	setfillstyle(SOLID_FILL,LIGHTGREEN); /* monitor light */
	floodfill(RIGHT-18,BOTTOM-5,BROWN);
	setfillstyle(INTERLEAVE_FILL,WHITE);
	floodfill(LEFT+1,TOP+1,BROWN);
	line(LEFT+20,BOTTOM,LEFT,BOTTOM+10);/* basement */
	line(RIGHT-20,BOTTOM,RIGHT,BOTTOM+10);
	rectangle(LEFT-20,BOTTOM+10,RIGHT+20,BOTTOM+60); /* Ist CPU */
	setfillstyle(INTERLEAVE_FILL,BROWN);
	floodfill(LEFT+22,BOTTOM+2,BROWN);
	rectangle(RIGHT-60,BOTTOM+18,RIGHT-2,BOTTOM+36); /* Ist CD */
	setfillstyle(SOLID_FILL,WHITE); /* give me hint */
	floodfill(RIGHT-50,BOTTOM+32,BROWN);
	circle(RIGHT-10,BOTTOM+31,2); /* CD buttons */
	circle(RIGHT-20,BOTTOM+31,2);
	rectangle(RIGHT-57,BOTTOM+23,RIGHT-4,BOTTOM+27); /* CD's tray */
	settextstyle(SMALL_FONT,HORIZ_DIR,2);
	setcolor(BLACK);
	outtextxy(RIGHT-43,BOTTOM+27,"50x");
	setcolor(RED);
	rectangle(RIGHT-52,BOTTOM+30,RIGHT-47,BOTTOM+33); /* CD's LED */
	setfillstyle(SOLID_FILL,RED);
	floodfill(RIGHT-50,BOTTOM+32,RED);
	setcolor(BROWN);
	rectangle(RIGHT-53,BOTTOM+40,RIGHT-7,BOTTOM+53); /* Ist floppy */
	setfillstyle(SOLID_FILL,WHITE);
	floodfill(RIGHT-50,BOTTOM+41,BROWN);
	rectangle(RIGHT-48,BOTTOM+44,RIGHT-12,BOTTOM+47); /* insertion */
	line(RIGHT-22,BOTTOM+51,RIGHT-12,BOTTOM+51); /* push button */
	rectangle(RIGHT-46,BOTTOM+49,RIGHT-40,BOTTOM+52); /* floppy's LED */
	setfillstyle(SOLID_FILL,YELLOW);
	floodfill(RIGHT-45,BOTTOM+50,BROWN);
	setcolor(BROWN);
	rectangle(LEFT-10,BOTTOM+48,LEFT,BOTTOM+44); /* ON/OFF button */
	setfillstyle(SOLID_FILL,LIGHTGREEN);                 /* CPU light */
	floodfill(LEFT-9,BOTTOM+45,BROWN);
	setfillstyle(INTERLEAVE_FILL,WHITE);
	floodfill(LEFT-19,BOTTOM+11,BROWN);
	setcolor(WHITE);
	rectangle(LEFT-20,BOTTOM+90,RIGHT+20,BOTTOM+95); /* Ist 1/6 keyboard */
	setfillstyle(INTERLEAVE_FILL,WHITE);
	floodfill(LEFT-15 ,BOTTOM+92,WHITE);
	rectangle(LEFT-20,BOTTOM+95,RIGHT+20,BOTTOM+135); /* Ist 5/6 keyboard */
	floodfill(LEFT-15 ,BOTTOM+92,WHITE);
	setcolor(BROWN);
	/* making keyboard buttons */
	for(i=0;i<30;i+=10)
	{
	   for(j=0;j<176;j+=15)
	   {
		rectangle(LEFT-18+j,BOTTOM+100+i,LEFT-7+j,BOTTOM+107+i);
	   }
	}
	setcolor(WHITE);
	arc(LEFT-20,BOTTOM+50,60,270,45); /* keyboard wire */
	arc(LEFT-16,BOTTOM+50,60,270,45);
	arc(BOTTOM+40,RIGHT+140,35,145,100); /* serial cable */
	arc(BOTTOM+40,RIGHT+143,35,145,100);
	setcolor(BROWN);
	size = imagesize(10,170,240,420); /* taking size of half image */
	halfbuff=(void *)malloc(size);
	getimage(10,170,240,420,halfbuff);/* copy half image */
	putimage(350,170,halfbuff,OR_PUT); /* Just opposite to it */
	arc(99, 99, -70, 10, 35);         /* making hand and fingers */
	line(133,92,125,70);
	line(125,70,118,80);
	arc(125,78,180,340,5);
	setfillstyle(SOLID_FILL,WHITE);
	floodfill(125,80,BROWN);
	size = imagesize(100,60,150,140);/* taking size of hand and fingers */
	gbuff=(void *)malloc(size);
	getimage(100,60,150,140,gbuff);   /* copy-paste hand and fingers */
	putimage(100,60,gbuff,XOR_PUT);   /* erase finger from its origin */
	/* for first pc */
	putimage(95,385,gbuff,OR_PUT); /* put fingers on keyboard */
	putimage(105,385,gbuff,OR_PUT);
	putimage(115,385,gbuff,OR_PUT);
	line(95,425,89,442); /* making thumb */
	arc(95,437,180,24,5);
	line(112,405,114,425);
	arc(105,425,180,360,10);
	line(101,465,89,441);
	arc(117,466,180,250,15);
	floodfill(95,438,BROWN);
	/* for second pc */
	putimage(425,385,gbuff,OR_PUT);
	putimage(435,385,gbuff,OR_PUT);
	putimage(445,385,gbuff,OR_PUT);
	line(425,425,419,442); /* making thumb */
	arc(425,437,180,24,5);
	line(442,405,444,425);
	arc(435,425,180,360,10);
	line(431,465,419,441);
	arc(447,466,180,250,15);
	floodfill(425,438,BROWN);
	settextstyle(SANS_SERIF_FONT,HORIZ_DIR,5);/* writing serial cahtting */
	setcolor(BLUE);
	outtextxy(220,60,"MYSIR Instant Messenger");
	setcolor(BROWN);
	settextstyle(SANS_SERIF_FONT,HORIZ_DIR,1);
	/* moving fingers on 1st keyboard */
	for(i=0;i<2;i++)
		{
	    delay(500);
	    f+=5;
	    t+=5;
	    /* 1st finger */
	    putimage(95,385,gbuff,XOR_PUT);
	    putimage(95-f,385+s,gbuff,OR_PUT);
	    if(!i)
	    {
	       outtextxy(LEFT+20,BOTTOM-25,"H");
	       outtextxy(LEFT+360,TOP+20,"H");
	    }
	    if(i==1)
	    {
	       outtextxy(LEFT+62,BOTTOM-25,"L");
	       outtextxy(LEFT+402,TOP+20,"L");
	    }
	    delay(500);
	    putimage(95-f,385+s,gbuff,XOR_PUT);
	    putimage(95,385,gbuff,OR_PUT);
	    delay(500);
	    s-=5;
	    f-=10;
	    /*2nd finger*/
	    putimage(105,385,gbuff,XOR_PUT);
	    putimage(105,385+s,gbuff,OR_PUT);
	    if(!i)
	    {
	       outtextxy(LEFT+34,BOTTOM-25,"E");
	       outtextxy(LEFT+374,TOP+20,"E");
	    }
	    if(i==1)
	    {
	       outtextxy(LEFT+76,BOTTOM-25,"O");
	       outtextxy(LEFT+416,TOP+20,"O");
	    }
	    delay(500);
	    putimage(105,385+s,gbuff,XOR_PUT);
	    putimage(105,385,gbuff,OR_PUT);
	    delay(500);
	    /*3rd finger*/
	    putimage(115,385,gbuff,XOR_PUT);
	    putimage(115+i,385-t,gbuff,OR_PUT);
	    if(!i)
	    {
	       outtextxy(LEFT+48,BOTTOM-25,"L");
	       outtextxy(LEFT+388,TOP+20,"L");
	    }
	    if(i==1)
	    {
	       outtextxy(LEFT+88,BOTTOM-25,"!");
	       outtextxy(LEFT+428,TOP+20,"!");
	    }
	    delay(500);
	    putimage(115+i,385-t,gbuff,XOR_PUT);
	    putimage(115,385,gbuff,OR_PUT);
	}
	 /* regeneration of 1st keyboard buttons */
	setcolor(BROWN);
	for(i=0;i<30;i+=10)
	{
	   for(j=0;j<176;j+=15)
	   {
		rectangle(LEFT-18+j,BOTTOM+100+i,LEFT-7+j,BOTTOM+107+i);
	   }
	}
	f=s=t=0;
	/* moving fingers on 2nd keyboard */
	for(i=0;i<1;i++)
	{
	    delay(500);
	    f+=5;
	    t+=5;
	    /* 1st finger */
	    putimage(425,385,gbuff,XOR_PUT);
	    putimage(425-f,385+s,gbuff,OR_PUT);
	    outtextxy(LEFT+20,TOP+20,"H");
	    outtextxy(LEFT+360,BOTTOM-25,"H");
	    delay(500);
	    putimage(425-f,385+s,gbuff,XOR_PUT);
	    putimage(425,385,gbuff,OR_PUT);
	    delay(500);
	    s-=5;
	    f-=10;
	    /*2nd finger*/
	    putimage(435,385,gbuff,XOR_PUT);
	    putimage(435,385+s,gbuff,OR_PUT);
	    outtextxy(LEFT+34,TOP+20,"I");
	    outtextxy(LEFT+374,BOTTOM-25,"I");
	    delay(500);
	    putimage(435,385+s,gbuff,XOR_PUT);
	    putimage(435,385,gbuff,OR_PUT);
	    delay(500);
	    /*3rd finger*/
	    putimage(445,385,gbuff,XOR_PUT);
	    putimage(445+i,385-t,gbuff,OR_PUT);
	    outtextxy(LEFT+48,TOP+20,"!");
	    outtextxy(LEFT+388,BOTTOM-25,"!");
	    delay(500);
	    putimage(445+i,385-t,gbuff,XOR_PUT);
	    putimage(445,385,gbuff,OR_PUT);
	}
	/* regeneration of 2nd keyboard buttons */
	setcolor(BROWN);
	for(i=0;i<30;i+=10)
	{
	   for(j=0;j<176;j+=15)
	   {
		rectangle(402+j,380+i,413+j,387+i);
	   }
	}
free(gbuff);
free(gbuff1);
free(halfbuff);
setcolor(prevcolor);
}