/************************************************************************
*
*  Title: ifs.c
*
************************************************************************/

#include <stdio.h>
#include <math.h>
#include <functions.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>

struct GfxBase *GfxBase;
struct IntuitionBase *IntuitionBase;
double ran();

/* */
/* Short function to open up required libraries. */
/* */

void Init()

{

if( !(IntuitionBase=
     (struct IntuitionBase *)OpenLibrary("intuition.library",0L)) )
   {
   printf("Error opening intuition.library\n");
   Exit(20L);
   }

if( !(GfxBase=
     (struct GfxBase *)OpenLibrary("graphics.library",0L)) )
   {
   printf("Error opening graphics.library\n");
   CloseLibrary(IntuitionBase);
   Exit(20L);
   }

}



/**/
/* Function which actually makes OpenWindow call. */
/**/

struct Window *SetWindow(title,left,top,width,height)

short left,top,width,height;
char *title;

{

struct NewWindow *nw;
struct Window *wp;

nw=(struct NewWindow *)AllocMem((long)(sizeof(struct NewWindow)),MEMF_CHIP);
if( !nw )
   {
   printf("Error allocating NewWindow structure\n");
   CloseLibrary(GfxBase);
   CloseLibrary(IntuitionBase);
   Exit(20L);
   }
   
nw->LeftEdge=left;
nw->TopEdge=top;
nw->Width=width;
nw->Height=height;
nw->DetailPen=0;
nw->BlockPen=1;
nw->IDCMPFlags=MENUPICK|CLOSEWINDOW;
nw->Flags=SMART_REFRESH|ACTIVATE|WINDOWSIZING|WINDOWCLOSE|WINDOWDRAG|
          WINDOWDEPTH;
nw->FirstGadget=NULL;
nw->CheckMark=NULL;
nw->Title=(unsigned char *)title;
nw->Screen=(struct Screen *)NULL;
nw->BitMap=(struct BitMap *)NULL;
nw->MinWidth=10;
nw->MinHeight=10;
nw->MaxWidth=640;
nw->MaxHeight=200;
nw->Type=WBENCHSCREEN;

wp=(struct Window *)OpenWindow(nw);
FreeMem(nw,(long)(sizeof(struct NewWindow)));
if( !wp )
   {
   printf("Error opening window\n");
   CloseLibrary(GfxBase);
   CloseLibrary(IntuitionBase);
   Exit(20L);
   }

return(wp);

}



/**/
/* Function to setup menu and monitor messages for close window signal */
/**/

void QuitWindow(wp)

struct Window *wp;

{

long  class,code;                     /* Event information */

struct IntuiMessage *message;         /* Gets input event */

static struct IntuiText menu_text = { /* Menu description */
   2,1,JAM2,                          /* Frontpen, Backpen, Draw mode */
   20,1, NULL,                        /* Left and Top offsets, Font */
   (UBYTE *)"QUIT",NULL };            /* Text to display, next IntuiText */

static struct MenuItem menu_item = {
   NULL, 0,0,100,10,                  /* Next item,Left,Top,Width,Height */
   HIGHBOX |ITEMENABLED |MENUTOGGLE |
   ITEMTEXT |CHECKIT |COMMSEQ,
   NULL,(APTR)&menu_text,             /* MutualExclude, ItemFill */
   NULL, 'Q', NULL };                 /* SelectFill, Command , SubItem */

static struct Menu menu = {
   NULL, 0,0,60,10,                   /* Next item, Left,Top,Width,Height */
   MENUENABLED, "Menu",               /* Flags , text */
   &menu_item };                      /* Pointer to first menu-item */

SetMenuStrip( wp, &menu );

while(1)                      /* Infinite loop */
   {
   WaitPort(wp->UserPort);    /* Wait for input event */
   message=(struct IntuiMessage *)GetMsg(wp->UserPort);
   class=message->Class;      /* Get event info */
   code=message->Code;
   ReplyMsg(message);         /* Tell intuition we're through with event */
   switch(class)              /* Process the input event */
      {
      case MENUPICK:
         if ( (MENUNUM(code)==0) && (ITEMNUM(code)==0) )
	    goto quit;        /* I know ... 'goto' in a C program. */
	 break;               /* Pretty or not, it looks like the */
      case CLOSEWINDOW:       /* fastest way to get out of this while */
         goto quit;           /* loop. */
	 break;
      }

   }

quit:
ClearMenuStrip(wp);
CloseWindow(wp);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);

}



/**/
/* Main function */
/**/

main()

{

struct Window *wp;
struct RastPort *rp;
float a[10],b[10],c[10],d[10],e[10],f[10],p[10];
float x,y,newx,newy,xscale,yscale,xoffset,yoffset,pk,pt;
long left,top,width,height;
long i,j,m,px,py;
unsigned long iters;

newx=newy=x=y=pt=0.;

printf("IFS Input Data\n");

Init();
if(4!=scanf("%ld%ld%ld%ld",&left,&top,&width,&height))
   {
   printf("Error Reading Window Specifications -> left top width height\n");
   goto quit;
   }
printf("Window Specifications -> %ld %ld %ld %ld\n",left,top,width,height);
wp=SetWindow("SimpleWindow",left,top,width,height);
rp=wp->RPort;

if(1!=scanf("%ld",&iters))
   {
   printf("Error Reading Number of Iterations -> iters\n");
   goto quit;
   }
if(iters>4294967295)
   {
   printf("Too Many Iterations, Maximum -> 4,294,967,295\n");
   goto quit;
   }

printf("Number of Iterations -> %ld\n",iters);

if(4!=scanf("%f%f%f%f",&xoffset,&yoffset,&xscale,&yscale))
   {
   printf("Error Reading Offsets or Scales -> xoffset yoffset xscale yscale\n");
   goto quit;
   }

printf("Offsets and Scaling -> %f %f %f %f\n",xoffset,yoffset,xscale,yscale);

if(1!=scanf("%ld",&m))
   {
   printf("Error Reading Number of Transformations -> m\n");
   goto quit;
   }

printf("Number of Transformations -> %ld\n",m);

for(i=0L;i<m;i++)
   {
   if(7!=scanf("%f%f%f%f%f%f%f",&a[i],&b[i],&c[i],&d[i],&e[i],&f[i],&pk))
      {
      printf("Error Reading Transformation Coefficients -> a. b. c. d. e. f. p.\n");
      goto quit;
      }
   printf("Coefficients -> %f %f %f %f %f %f %f\n",a[i],b[i],c[i],d[i],e[i],f[i],pk);
   pt=pt+pk;
   p[i]=pt;
   }

for(i=0L;i<10L;i++)
   {
   pk=(float)ran();
   for(j=0L;p[j]<pk && j<m;j++);
   newx=a[j]*x+b[j]*y+e[j];
   newy=c[j]*x+d[j]*y+f[j];
   x=newx;
   y=newy;
   }
   
for(i=0L;i<iters;i++)
   {
   pk=(float)(ran());
   for(j=0L;p[j]<pk && j<m;j++);
   newx=a[j]*x+b[j]*y+e[j];
   newy=c[j]*x+d[j]*y+f[j];
   x=newx;
   y=newy;
   px=(long)(x*xscale+xoffset);
   py=(long)(height-(y*yscale+yoffset));
   if(px>0L && px<width && py>0L && py<height)
      WritePixel(rp,px,py);
   }

quit:
QuitWindow(wp);

}
