/* INSPIRE GRAPHICS DEVELOPMENT STAGE 23 */
#include <stdio.h>

#include <graphics.h>

#include <stdlib.h>

#include <bios.h>

#include <conio.h>

#include <stdarg.h>

#include <string.h>

#include <alloc.h>

#include <dos.h>

#define  true 0

#define  false 1


int mc=1,oc=1,c,lx,ly,pa[100],p=0,ax[3],ay[3],pix[4],cx=0,cy=0,f=0,mx,my,em,ef=0,m=5,
    dc=0,cv,ec=3,escf=false,lw=1,ls=0,fs=1,dir=0,font=0,ff=0,sx,sy,trx,s,k=0,
	 edop=1,mof=0,cutf=false,modop=7,moop=1,fxop=1;
void  *ep;         /* mc=main choice,   lx,ly=currnt cursor coordinates */
void  *eb;         /* pa=polyarray   ax[],ay[] arrays storing clicks  */
void  *cursor;
 void  *pen;
//char  *tem[300];

char tem[300];
char  *tstr;
void  *textbuf;
void far *tembuf;
void  *cutbuf;

/*=========================================================================*/
	  /* CREATES PULLDOWN MENU  OF ANY GIVEN SIZE
	bcol  BACGROUNDCOLOR OF THE MENU
	dcol  DRAWCOLOR OF THE NENU
	x,y   COORDINATE OF THE TOP LEFT CORNER OF THE MENU
	n     NO OF OPTIONS
	*ttl  VARIABLE ARGUMENT ARRAY
			CONSISTING OF TITLE FOLLOWED BY OPTION NAMES  */

	  int  gmenu(int attr,int bcol,int dcol,int lx,int ly,int n,char *ttl ...)
	{
	 int n2=n,rx,ry,c=0,x,y,sl,ml,xx,yy,k,tp,scale=20;
	 if(getmaxy()<=200) {  scale=10; dcol=1;bcol=0;  }
	 else if(getmaxy()<400) scale=15;

	 char *strar[20];
	 void *menub;
	 void *barb;
	 va_list ap;

	 setviewport(0,0,mx,my,1);
	 ry=ly+(n*scale)+26;   //---20

	 escf=false;                /* initially set escape flag to false */
	 setcolor(dcol);
	 setlinestyle(0,1,1);
	 ml=strlen(ttl);
//	 for(int i=0;i<20;i++) strar[i]=(char*)malloc(sizeof(char)*20);


	 va_start(ap,ttl);
	 while(n2!=0)
			{
			 strar[c] =va_arg(ap,char*);

			 sl=strlen(strar[c]);
	       if(sl>ml)  ml=sl;        /* finds the max:length of options*/
	       c++;n2--;
	      }
	 va_end(ap);

	 x=lx+2; y=ly+2;
	 rx=lx+((ml+3)*8);	   /* width of the mwnu box from max:len*/
	 if((attr!=0)&&(attr<=4)) rx+=60;

	 menub=malloc(imagesize(lx,ly,rx,ry));
	 if( menub==NULL)
	     {
		closegraph();
		printf("75");
		exit(1);
	      }
	 getimage(lx,ly,rx,ry,menub);      /* stores the screen in buffer */
	 setfillstyle(1,15);
	 bar(lx+5,ly,rx-5,ly+scale-4);    //16                      /* hilight bar */

	 barb=malloc(imagesize(lx+5,ly,rx-5,ly+scale-4));
	 if( barb==NULL)
	     {
		closegraph();
		printf("85");
		exit(1);
	      }
	 getimage(lx+5,ly,rx-5,ly+scale-4,barb);
	 setfillstyle(1,bcol);                                /* masking  */
	 bar(lx,ly,rx,ry);
	 setfillstyle(1,15);

	 tp=lx+((rx-lx)/2);
	 settextjustify(1,1);
	 outtextxy(tp,y+11,ttl);                          /* prints title */
	 settextjustify(0,0);

	 rectangle(x,y,rx-2,y+20);                     /* title rectangle */
	 rectangle(x,y+22,rx-2,ry-2);                /* options rectangle */
	 rectangle(lx,ly,rx,ry);                       /* outer rectangle */

	 y=ly+33+((scale-8)/2);  //--39

	 for(c=0;c<n;c++)
	    {
	     if((attr!=0)&&(attr<=3))
	       {
		setlinestyle(0,1,1);
		rectangle(rx-60,y-9,rx-8,y);
	       }
	     if(attr==4)         //COLORS

	       {
		setfillstyle(1,c);
		fillellipse(rx-34,y-4,25,4);
		setfillstyle(fs,dc);
	       }
	     if(attr==3)         //FILLSTYLE

	       {
		setfillstyle(c,dc);
		floodfill(rx-20,y-4,dcol);
		setfillstyle(fs,dc);
	       }
	     if(attr==2)        //LINESTYLE

	       {
		setlinestyle(c,1,1);
		line(rx-57,y-4,rx-11,y-4);
			 }
		  if(attr==1)       //LINEWIDTH

	       {
		if(c==0) setlinestyle(0,1,1);
		if(c==1) setlinestyle(0,1,3);
	       }
	     if(attr!=5) outtextxy(lx+10,y,strar[c]);    /* prints options */
	     if(attr==5)                                 /*PRINTS IN FONTS */
	       {
		settextstyle(c,0,0);
		if(c!=0) setusercharsize(1,2,1,2);
		if(c==2) setusercharsize(3,2,3,2);
		if(c>=9) setusercharsize(1,4,1,4);
		outtextxy(lx+10,y,strar[c]);
		settextstyle(0,0,1);
	       }
	     y+=scale;       //---20

	    }
	 xx=lx+5;
	 yy=ly+26+((cv-1)*scale);      /*initial position of highlight bar */
	 putimage(xx,yy,barb,1);    /*corrected according to current option*/
	 c=cv;                    /* option initialised to current position*/
	 do
	   {
	    k=bioskey(0);
	    if(k==283)
	      {
	       escf=true;           /*if key=<esc> set escape flag to true */
	       c=cv;
	       goto esc;
	      }
	    if((k==20480)&&(c<n+1)) /* down arrow key and not last option */
	      {
	       putimage(xx,yy,barb,1);
	       yy+=scale; c++;         //----20

	       putimage(xx,yy,barb,1);
	      }
	    if((k==20480)&&(c==n+1))    /* down arrow key and last option */
	      {
	       putimage(xx,yy,barb,1);
			 yy=ly+26;c=1;
			 putimage(xx,yy,barb,1);
	      }
	    if((k==18432)&&(c==1))   /* up arrow key and first option */
	      {
	       putimage(xx,yy,barb,1);
	       yy+=(n-1)*scale; c=n;
	       putimage(xx,yy,barb,1);
	      }
	    else if((k==18432)&&(c>1))    /* up arrow key and not first option */
	      {
	       putimage(xx,yy,barb,1);
	       yy-=scale; c--;         //---20

	       putimage(xx,yy,barb,1);
	      }



	   } while(k!=7181);                              /* until <enter> */

	 esc: putimage(lx,ly,menub,0);
	 free(menub);
	 free(barb);
  //	 for(i=0;i<20;i++) free(strar[i]);

	 setcolor(dc);
	 setfillstyle(fs,dc);
	 setlinestyle(ls,1,lw);
	 setviewport(0,23,mx,my,1);
	 return(c);
	}

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     void getstr(int px,int py,int col)
       {
	 unsigned int bk;
	 int i=0,newp,nuch=0,nc;
	   //tstr[0]=0;

	   setcolor(col);
	   settextstyle(0,0,0);
	   settextjustify(0,2);
		nc=trx/10;
		textbuf=malloc(imagesize(px,py,px+trx,py+10));
	   if( textbuf==NULL)
	     {
		closegraph();
		printf("204");
		exit(1);
	      }
	   getimage(px,py,px+trx,py+10,textbuf);
	   bk=1;
	   while(bk!=7181)
	    {
	   //  if(nuch>nc)

	     //  {

	  //	putchar(7);

	    //   }

	      bk=bioskey(0);
	     if(bk==283)
	      {
		i=1;
		goto out;
			}
	     if(bk==3592)
	      {
	       nuch--;
	       tstr[i-1]=0;
	       if(i>=0) i-=2;
	       else putchar(7);
	      }
	     else
	      {
	       if(nuch<=nc)
		{
		 tstr[i]=bk & 0x00ff;
		 tstr[i+1]=0;
		 nuch++;
		}
	       else putchar(7);
	      }
	     if(bk==7181)
			{
			 tstr[i]=0;
	      }
	     if(dir==0) putimage(px,py,textbuf,0);
	     outtextxy(px,py,tstr);

	     i++;
	    }


	out:putimage(px,py,textbuf,0);
	   tstr[i-1]=0;

	   outtextxy(px,py,tstr);
	   cx=0; cy=0; f=0;
	 //  mc=1;

	   free(textbuf);
	   settextjustify(0,0);
	   setcolor(dc);
	   settextstyle(0,0,1);
	}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     void  msgbox(int mod,int bcol,int dcol,int lx,int ly,int n,char *ttl ...)
	{
	 int n2=n,rx,ry,c=0,x,y,sl,ml,xx,yy,k,tp,scale=20;
	 if(getmaxy()<=200) {  scale=10; dcol=1;bcol=0;  }
	 else if(getmaxy()<400) scale=15;

	 char *strar[20];
	 char *arg;
	 void *menub;
	 va_list ap;

	 ly=ly-(((n*scale)+24)/2);
	 ry=ly+(n*scale)+24;
	 escf=false;                /* initially set escape flag to false */
	 setcolor(dcol);
	 setlinestyle(0,1,1);
	 ml=strlen(ttl);
	 va_start(ap,ttl);
	 while(n2!=0)
	      {
	       strar[c] =va_arg(ap,char*);

	       sl=strlen(strar[c]);
	       if(sl>ml)  ml=sl;        /* finds the max:length of options*/
	       c++;n2--;
	      }
	 va_end(ap);
	 lx=lx-((ml)*5);
	 x=lx+2; y=ly+2;
	 sx=x+5; sy=y+30;
	 rx=lx+((ml)*10);	  /* width of the mwnu box from max:len*/
	 trx=rx-lx;                  /* stores the width of box for tstr fn:*/
	 menub=malloc(imagesize(lx,ly,rx,ry));
	 if (menub==NULL)
	     {
		closegraph();
		printf("299");
		exit(1);
	      }
	 getimage(lx,ly,rx,ry,menub);      /* stores the screen in buffer */
	 setfillstyle(1,bcol);                                /* masking  */
	 bar(lx,ly,rx,ry);
	 setfillstyle(1,15);
	 tp=lx+((rx-lx)/2);
	 settextjustify(1,1);
	 outtextxy(tp,y+11,ttl);                          /* prints title */
	 settextjustify(1,0);

	 rectangle(x,y,rx-2,y+20);                     /* title rectangle */
	 rectangle(x,y+22,rx-2,ry-2);                /* options rectangle */
	 rectangle(lx,ly,rx,ry);		     /* outer rectangle */
	 rectangle(x+2,ry-16,rx-4,ry-4);

	 y=ly+33+((scale-8)/2);  //--39

	 for(c=0;c<n;c++)
	    {
		  outtextxy(tp,y,strar[c]);               /* prints options */
		  y+=scale;       //---20

	    }
	 xx=lx+5; yy=ly+26+((cv-1)*scale);//----20 /*initial position of highlight bar */


	 if(mod==1)
	  {
	  getstr(sx,sy,WHITE);
	  putimage(lx,ly,menub,0);
	  free(menub);
	  }
	 if(mod==2)
	  {
	  k=bioskey(0);
	  while(k!=283)  k=bioskey(0);
	  if(k==283)
	  putimage(lx,ly,menub,0);
	  free(menub);
	 }


	 setcolor(dc);
	 setfillstyle(fs,dc);
	 setlinestyle(ls,1,lw);
	}
        

 char far *scrptr;
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     void callmouse()
       {

	int x,y,buttons;
	union REGS regs,iregs,oregs;
	//scrptr=(char *)MK_FP(0x40,0x49);   //HERC

	putimage(lx,ly,cursor,1);
	// *scrptr=6;

	poke(0x40,0x49,6);                             //HERC   poke

	regs.x.ax=0;
	int86(0x33,&regs,&regs);
	setcolor(BLACK);

  if(regs.x.ax == 0)
  {

	msgbox(2,0,15,mx/2,my/2,4,"A TASTE OF MOUSE","sorry mouse not found",
		 "Use shift+arrow keys","for a crude simulation","<ESC> to quit");
   mof=1;
   goto xit;
  }

  regs.x.ax=1;
  int86(0x33,&regs,&regs);

  do
  {
   regs.x.ax=3;
   int86(0x33,&regs,&regs);
   buttons=regs.x.bx & 3;
   x=regs.x.cx;
   y=regs.x.dx;
//   if(getmaxy()>200)  putimage(x-2,y-30,pen,1);

   if(regs.x.bx & 1)
      {
	setcolor(dc);
	lineto(x,y-24);
	}
	else if(regs.x.bx & 2)
      {
       setcolor(WHITE);
       lineto(x,y-24);
      }
   delay(50);
   moveto(x,y-24);
  // if(getmaxy()>200) putimage(x-2,y-30,pen,1);

   }while(buttons!=3);

xit:   regs.x.ax=2;
   int86(0x33,&regs,&regs);
   putimage(lx,ly,cursor,1);

  }

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     void about()
       {
	 msgbox(2,0,15,mx/2,my/2,9,"ABOUT INSPIRE FX",
				"UNDER DEVOLPEMENT BY",
				"KISHAN P THOMAS",
				"Version 1.01 with complete",
				"mouse support will be",
				"available soon",
				"For more information contact",
				"WILD ROSE, ST:JAMES CHURCH LANE",
				"COCHIN 682034.",
				"<ESC> to continue");
       }


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     void stylestat()
       {
	 setviewport(0,0,mx,my,1);
	 if(dc==0) setfillstyle(1,15);
	 else setfillstyle(1,0);
	 bar(mx-54,3,mx-3,20);
	 setlinestyle(ls,1,lw);
	 rectangle(mx-53,4,mx-4,19);
	 setfillstyle(fs,dc);
	 bar(mx-50,7,mx-7,16);
	 setviewport(0,23,mx,my,1);
       }
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     void notav()
	{
	 msgbox(2,15,0,mx/2,my/2,6,"INSPIRE FX","Not available in this",
		"demo version","Will be implemented in",
		"INSPIRE FX Ver 1.01"," ","<ESC> to continue");
	}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     int callmain()
	{
	 return(gmenu(0,15,0,1,1,16,"MAIN MENU"," 1.OPTIONS"," 2.ERASE"," 3.MOUSEDRAW",
	   " 4.LINEWIDTH"," 5.LINESTYLE"," 6.FILLPATTERN"," 7.COLORS"," 8.TEXTIN",
	   " 9.EDIT+FX","10.VISUALFX","11.CLEAR","12.SAVE",
	   "13.VIEW","14.PRINT","15.ABOUT","16.EXIT"));
	}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*++++++++++++++++++MENU CALL ORGANISER++++++++++++++++++++++++++++++++++++*/
     void menu()
	{
	 int dct,lwt=1,lst=1,fst=1,dirt=1,fontt=1;/*MAIN MENU - FIRST CALL */
start:   cv=mc;
	 mc=callmain();

	 while((mc==7)&&(escf==false))                   /* DRAWING COLORS */
	 {
seven:   cv=dc+1;
	 dct=gmenu(4,15,0,1,1,16,"COLORS","1.BLACK","2.BLUE","3.GREEN","4.CYAN",
	    "5.RED","6.MAGENTA","7.BROWN","8.LIGHT GRAY","9.DARKGRAY",
	    "10.LIGHTBLUE","11.LIGHT GREEN","12.LIGHTCYAN","13.LIGHTRED",
	    "14.LIGHTMAGENTA","15.YELLOW","16.WHITE");
	 dc=dct-1;
	 setcolor(dc);
	 stylestat();
	 cv=mc;
	 mc=callmain();

	 }

	 while((mc==4)&&(escf==false))                       /* LINE WIDTH */
	 {
four:     cv=lwt;
	  lwt=gmenu(1,15,0,1,1,2,"LINEWIDTH","1.ONE PIXEL","2.THREE PIXELS");
	  if(lwt==1)  lw=1;
	  if(lwt==2)  lw=3;
	  setlinestyle(ls,1,lw);
	  stylestat();
	  cv=mc;
	  mc=callmain();

	  if(mc==7) goto seven;
	 }

	 while((mc==5)&&(escf==false))                     /* LINE STYLES */
	 {
five:      cv=ls+1;
	  lst=gmenu(2,15,0,1,1,4,"LINESTYLE","1.SOLID","2.DOTTED","3.CENTRE",
	  "4.DASHED");
	  ls=lst-1;
	  setlinestyle(ls,1,lw);
	  stylestat();
	  cv=mc;
	  mc=callmain();
	  if(mc==7)  goto seven;
	  if(mc==4)  goto four;
	 }
	 while((mc==6)&&(escf==false))                   /* FILL PATTERNS */
	 {
	  cv=fs+1;
	  fst=gmenu(3,15,0,1,1,12,"FILLPATTERN"," 1.EMPTY"," 2.SOLID"," 3.LINE",
	  " 4.LTSLASH"," 5,SLASH"," 6.BSLASH"," 7.LTBSLASH"," 8.HATCH"," 9.XHATCH",
	  "10.INTERLEAVE","11.WIDE DOT","12.CLOSE DOT");
	  fs=fst-1;
	  setfillstyle(fs,dc);
	  stylestat();
	  cv=mc;
	  mc=callmain();

	  if(mc==7)  goto seven;
	  if(mc==4)  goto four;
	  if(mc==5)  goto five;
	   }
	 if(mc==8)
	    {
	     cv=dir+1;
	     dirt=gmenu(0,15,0,1,1,2,"DIRECTION","1,HORIZONTAL","2.VERTICAL");
	     dir=dirt-1;
	     cv=font+1;
	     fontt=gmenu(5,0,15,1,1,11,"FONTS","1.DEFAULT","2.TRIPLEX",
	     "3.SMALL","4.SANS_SERIF","5.GOTHIC","6.SCRIPT","7.LCOM",
	     "8.LITT","9.TSCR","10.EURO","11.BOLD");
	     font=fontt-1;
	    }
	 if((mc==9)&&(escf==false))
	 {
	  cv=edop;
	  edop=gmenu(0,15,0,1,1,14,"EDIT+FX"," 1.COPY"," 2.MOVE"," 3.DELETE",
	  " 4.CUT"," 5.PASTE"," 6.ENLARGE"," 7.REDUCE"," 8.MORPH"," 9.MIRROR",
	  "10.REFLECT","11.TILE","12.MO-D-FI","13.ROTATELEF","14.ROTATERIGHT");
	 }
	 if((mc==10)&&(escf==false))
	  {
	   cv=fxop;
	   fxop=gmenu(0,15,0,1,1,2,"VISUALFX","1.DEMOS","2.MULTIMEDIA");
	  }
	 if(mc==1)
	   {
	    cv=oc;
	    oc=gmenu(0,15,0,1,1,7,"OPTIONS"," 1.CIRCLE"," 2.LINE"," 3.RECTANGLE",
		     " 4.ELLIPSE"," 5.POLYLINE"," 6.BAR"," 7.STAR");
	   }
	 if(mc==2)
	   {
	    cv=ec;
	    ec=gmenu(0,15,0,1,1,5,"ERASER SIZE","1.VERY SMALL","2.SMALL",
	       "3.MEDIUM","4.LARGE","5.EXTRA LARGE");
	   }
	 if((mc==11)&&(escf==false))
	   {
	    setfillstyle(1,getmaxcolor());
	    bar(0,0,mx,my);
	    putimage(lx,ly,cursor,1);
	    goto start;
	   }
	 if(mc==16)
	   {
	    free(cursor);
	    free(cutbuf);
	    closegraph();
	    printf("ARE YOU INSPIRED 'NUFF ?");
	    exit(0);
	   }
	 if(mc==12) msgbox(1,0,14,mx/2,my/2,3,"      Save as.....  ",
				       " "," ","<ESC> To Quit");
	 if(mc==13) msgbox(1,0,14,mx/2,my/2,3,"Enter file name.....",
				       " "," ","<ESC> To Quit");
	 if((mc==15)&&(escf==false))
	   {
	    about();
	    goto start;
	   }
	 if(((mc==9)&&(edop==12))&&(escf==false))
	   {
	    cv=modop;
	    modop=gmenu(0,15,0,1,1,11,"MO_D_FY","1.SOLIDSHADOW","2.SELFSHADOW",
	    "3.SOLIDBJOCK","4.CUBE","5.2_SIDECUBE","6.JUMPOUT","7.FRAMEIT",
	    "8.LINEHATCH","9.CIRCLEFILL","10.SQAREFILL","11.ZOOMOUT");
	   }

	 if(((mc==9)&&(edop==8))&&(escf==false))
	   {
	    cv=moop;
	    moop=gmenu(0,15,0,1,1,8,"MORPH","1.H-DRAG","2.V-DRAG",
	    "3.V-COMPRESS","4.H-COMPRESS","5.H- / TWIST","6.H- \ TWIST",
	    "7.V- / TWIST","8.H- \TWIST");
	   }


	 if((mc==9)&&(edop>12))
	   {
	    notav();
	    goto start;
	   }
	 if((edop==12)&&(modop!=7))
	  {
	   notav();
	   goto start;
	  }
	 if((edop==8)&&(moop!=1))
	   {
	    notav();
	    goto start;
	   }
	 if(mc==14)
	   {
	    msgbox(2,15,0,mx/2,my/2,9,"PRINT OPTION",
	    "THIS OPTION IS UNDER DEVOLOPMENT",
	    "FOR THE TIME BEING YOU MAY USE",
	    "GRAPHICS MODE PRINTSCREEN FACILITY",
	    "AVAILABLE IN DOS. SETUP THE PRINTER",
	    "TYPE graphics AT DOS PROMPT",
	    "RUN INSPIRE GET THE IMAGE YOU WANT ",
	    "TO PRINT AND PRESS THE PRINTSCREEN",
	    "BUTTON",
	    "<ESC> to Quit");
	    goto start;
	   }
	}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	  void textin()
		 {
	 unsigned int bk,nch;
	 int i=0,newpx,newpy,newy,newx;


	 if((c==7181)&&(f<=2))
	  {
		ax[cx]=lx+5;
		ay[cy]=ly+5;
		if(f<2) putpixel(lx+5,ly+5,dc);
		cx++; cy++; f++;
	  }

	 if(c==283)
	  {
		if(f==1) putpixel(ax[0],ay[0],getpixel(ax[0]+1,ay[0]+1));
		if(f==2)
		 {
		  putpixel(ax[0],ay[0],getpixel(ax[0]+1,ay[0]+1));
		  putpixel(ax[1],ay[1],getpixel(ax[1]+1,ay[1]+1));
		 }
		cx=0; cy=0; f=0;
	  }
	 if(f==3)
	  {
		//if((ax[1]-ax[0])>80) ax[1]=ax[0]+80;

		if((ay[1]-ay[0])>60) {ay[1]=ay[0]+60;ay[2]=ay[0]+60;}
		if((ax[