#include "exec/types.h"
#include "exec/memory.h"
#include "graphics/gfxbase.h"
#include "graphics/gfxmacros.h"
#include "intuition/intuitionbase.h"
#include "intuition/intuition.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"
#include  <stdio.h>                 /*for printf*/
                                    /*structures*/
struct RastPort *rp, *rpreq;        /*RastPort for the window*/
struct ViewPort *WVP;               /*screen ViewPort*/
struct BitMap PicBitMap;            /*picture BitMap*/
struct BitMap ScreenBitMap;         /*screen BitMap*/
struct GfxBase *GfxBase;            /*graphics base*/
struct IntuitionBase *IntuitionBase;/*intuition base*/
struct Screen *CustScr;             /*pointer to screen structure*/
struct Window *Wdw;                 /*pointer to window structure*/
struct Window *ReqWindow;
struct IntuiMessage *message;       /*pointer to message from window port*/
struct FileHandle *filehandle;      /*output filehandle for writing to screen*/
                                    /*defined in gadgets.c*/
extern struct Gadget Gadget1;       /*pointer to main first gadget*/
extern struct Gadget AGadget1;       /*pointer to first gadget, code1 */
extern struct Gadget BGadget2;       /*pointer to first gadget, code 2*/
extern struct Gadget CGadget4;       /*pointer to first gadget, code 3*/
extern struct Gadget DGadget6;       /*pointer to first gadget, code 4*/
extern struct Gadget EGadget7;       /*pointer to first gadget, code 5*/
extern UBYTE DGadget6SIBuff[];
extern UBYTE DGadget6SIUndo[];


short horizvalue = 0;              /*initial proportional values*/
short vertvalue = 0;
char horizstring[6] = "     ";    
char vertstring[6]  = "     ";

long i,k;                           /*loop variables*/
long libraries =0;                  /*libraries flag*/
long code,class;                   /*usedin intuimessage*/
long  reqanswer;                   /*request answer*/
short quit_flag,flag;              /*quit flags for windows*/          
 

 /*standard full size lo-res screen*/
static  struct NewScreen NewCustScr =
{
  0,270,
  320,
  256,
  5,
  1,8,
  SPRITES,
  CUSTOMSCREEN | CUSTOMBITMAP,
  0,
  NULL,
  NULL,
  &ScreenBitMap,
};

 /*full size window for screen*/
static  struct NewWindow NewWdw =
{
  0,0,
  320,
  256,
  1,8,
  CLOSEWINDOW|GADGETUP|GADGETDOWN|MOUSEBUTTONS,
  SUPER_BITMAP | ACTIVATE
  | BORDERLESS,
  NULL,
  NULL,
  NULL,
  NULL,
  &ScreenBitMap,
  0,0,
  0,0,
  CUSTOMSCREEN
};
/*requester window*/
struct NewWindow ANewWindowStructure1 = {
   0,0,
   320,100,
   0,1,
   MOUSEBUTTONS+GADGETDOWN+GADGETUP,
   RMBTRAP+ACTIVATE+NOCAREREFRESH,
   &AGadget1,
   NULL,
   NULL,
   NULL,
   NULL,
   320,100,
   320,100,
   CUSTOMSCREEN
};

void main(),init(),cleanup(),closelibraries(),quit(),Handle_IDCMP();
void writetext(),horiztext(),itoa(),reverse(),Handle_IDCMPReq();

void main()
{
   libraries= openlibraries();    /*open the libraries*/
   if (libraries == 0) exit(1);
   init();                        /*initialise display*/ 
   SetAPen(Wdw->RPort,1);         /*set the foreground pen*/
   writetext();                   /*display the text string*/
   MoveScreen(CustScr,0,-270);    /*move screen into place*/
   Handle_IDCMP();                /*main polling loop*/
   cleanup();                     /*free memory*/  
   closelibraries();               
}
openlibraries()                   /*open the libraries*/
{
   GfxBase= (struct GfxBase *)OpenLibrary("graphics.library",0);
   if (GfxBase == 0) return(0);
   IntuitionBase= (struct IntuitionBase *)OpenLibrary("intuition.library",0);
   if (IntuitionBase == 0) return(0);
return(1);                      /*returns a value if all libraries open*/
}

/*set up a lo-res screen and window*/
void init()
{
   InitBitMap(&ScreenBitMap,5,320,256);  /*set up a bitmap */
   for(i=0;i<5;i++)                      /*allocate screen for it*/
      {
        ScreenBitMap.Planes[i] = (PLANEPTR)AllocRaster(320,256);
        if (ScreenBitMap.Planes[i] == 0) exit(2);
        BltClear(ScreenBitMap.Planes[i],40*256,0); /*clear the a screen area*/
      }
   CustScr= (struct Screen *) OpenScreen(&NewCustScr);
   if (CustScr == 0) exit(1);           /*open the screen*/
   NewWdw.FirstGadget=&Gadget1;         /*attach the first gadget*/
   NewWdw.BitMap=(struct BitMap *) &ScreenBitMap; /*attach the bitmap*/
   NewWdw.Screen = CustScr;             /*open the window*/
   Wdw = (struct Window *)OpenWindow(&NewWdw);
   if (Wdw  == NULL) exit(FALSE);
   WVP=(struct ViewPort *)ViewPortAddress(Wdw); /*find viewport address*/
   rp = Wdw->RPort;                    /*RastPort address of window*/
}
/*display the text string*/
void writetext()
{
  SetAPen(rp,0);               /*clear text area*/ 
  RectFill(rp,0,30,300,60);
  SetAPen(rp,1);
  Move(rp,0,50);              /*Move cursor to start of text area*/
  Text(rp,DGadget6SIBuff,strlen(DGadget6SIBuff));  /*write the text*/
}
/*display the horizontal value*/
void horiztext()
{
  long horint;
  horint = horizvalue;
  itoa(horint,horizstring);
  SetAPen(rp,0);               /*clear text area*/ 
  RectFill(rp,0,210,300,230);
  SetAPen(rp,1);
  Move(rp,0,228);              /*Move cursor to start of text area*/
  Text(rp,"horizontal value is ",20);  /*write the text*/
  Text(rp,horizstring,strlen(horizstring));
}
/*display the horizontal value*/
void vertext()
{
  long vertint;
  vertint = vertvalue;
  itoa(vertint,vertstring);
  SetAPen(rp,0);               /*clear text area*/ 
  RectFill(rp,0,210,300,230);
  SetAPen(rp,1);
  Move(rp,0,228);              /*Move cursor to start of text area*/
  Text(rp,"vertical value is ",18);  /*write the text*/
  Text(rp,vertstring,strlen(vertstring));
}

/*close windows and screens, free rasters,close file*/
void cleanup()
{
  int i;                               /*close window and screen*/
  CloseWindow(Wdw);
  CloseScreen(CustScr);
  for (i=0;i<5;i++)                   /*free the screen memory*/
    {
       FreeRaster(ScreenBitMap.Planes[i],320,256);
    }
}

void closelibraries()               /*close libraries*/
{
  CloseLibrary(GfxBase);
  CloseLibrary(IntuitionBase);
}

/*choice of IntuiTexts for requester*/

struct IntuiText simple2 =
{
  1,2,JAM2,20,30,0,"Click on OK gadget to continue",0
};

struct IntuiText simple=
{
  1,2,JAM2,20,10,0,"A simple requester",&simple2
};

struct IntuiText twogad2 =
{
  1,2,JAM2,20,30,0,"Do you want to wait?",0
};
struct IntuiText twogad =
{
  1,15,0,20,20,0,"This requester has two gadgets:-",&twogad2
};
struct IntuiText textinstr2 =
{
  1,2,JAM2,30,80,0,"Cancel or Continue",0
};
struct IntuiText textinstr =
{
  1,15,0,20,20,0,"Enter text in this string gadget",&textinstr2
};
struct IntuiText proptext =
{
  1,15,0,20,20,0,"Adjust horizontal and vertical values",&textinstr2
};


/*warning requester*/
Request(code,itext)
long code;
struct IntuiText *itext;
{
   if (code==1) ANewWindowStructure1.FirstGadget=&AGadget1;
   if (code==2) ANewWindowStructure1.FirstGadget=&BGadget2;
   if (code==3) ANewWindowStructure1.FirstGadget=&CGadget4;
   if (code==4) ANewWindowStructure1.FirstGadget=&DGadget6;
   if (code==5) ANewWindowStructure1.FirstGadget=&EGadget7;
   ANewWindowStructure1.Height=120;
   if (code<3) ANewWindowStructure1.Height=100;
   if (InitR()==1) return(TRUE);
   PrintIText(rpreq,itext,0,0);
   Handle_IDCMPReq();
   CleanUpR(NULL);
   return(reqanswer);
}

/*handle gadgets for load screen*/
void Handle_IDCMP()
{
  APTR object;
  for (quit_flag = FALSE;!quit_flag;)
    {
    if (1<<Wdw->UserPort->mp_SigBit)
       {
    while (!(message=(struct IntuiMessage *)GetMsg(Wdw->UserPort)))
         { /*any other processing*/         
         }
       }
    class = message->Class;    
    code = message->Code;    
    object=message->IAddress;
    ReplyMsg((struct Message *) message );   
    switch ( class )
       {

       case GADGETUP:             /*gadget pressed */
          HandleEvent(object);
          break;

       case GADGETDOWN:           /*gadget released*/
          HandleEvent(object);
          break;

       case MOUSEBUTTONS:
	    break; 
       }                           /* end switch */
    }                              /* end forloop */
}
/*initialise requester window */
InitR()
{  long height;
   ANewWindowStructure1.Screen=CustScr;
   ReqWindow = (struct Window *)OpenWindow(&ANewWindowStructure1);
   if(! ReqWindow)
         {
          cleanup("OpenWindow Failed!");
          return(1);
         }
   rpreq=ReqWindow->RPort;
   SetAPen(rpreq,2);
   height=ANewWindowStructure1.Height;
   RectFill(rpreq,1,0,319,height-1);
   RefreshGadgets(ANewWindowStructure1.FirstGadget,ReqWindow,0);
   DrawRect(1,0,0,319,height-1);
   return(0);
}

DrawRect(c,x1,y1,x2,y2)
short c,x1,y1,x2,y2;
{
   SetAPen(rpreq,c);
   Move(rpreq,x1,y1);
   Draw(rpreq,x2,y1);
   Draw(rpreq,x2,y2);
   Draw(rpreq,x1,y2);
   Draw(rpreq,x1,y1);
   SetAPen(rpreq,2);
   return(0);
}

/*close requester window*/
CleanUpR(errormsg)
char *errormsg;
{
   if(errormsg)   printf("Error %s\n",errormsg);
   if(ReqWindow) CloseWindow(ReqWindow);
   return(0);
}


/*handle gadgets for requester*/                                                       /* end function */
void Handle_IDCMPReq()
   {
   APTR object;  
   flag = FALSE;
   while(flag ==FALSE)
      {
      if (1<<ReqWindow->UserPort->mp_SigBit)
         {
      while (!(message=(struct IntuiMessage *)GetMsg(ReqWindow->UserPort)))
          {
          }
         }
      class = message->Class;    
      code = message->Code;    /* Get event info */
      object=message->IAddress;
      ReplyMsg((struct Message *) message );
           switch ( class )
         {
         case GADGETUP:
            HandleEventR(object);
            break;

         case GADGETDOWN:
            HandleEventR(object); 
            break;

         case MOUSEBUTTONS:
            
            break;
         }                        

      }                            
 
   }



/*leave program*/
void quit()
{
   quit_flag=TRUE;
}

/*gadgets invoked by main program*/

requestgadget()
{
   Request(1,&simple);
   return(0);
}

stringadget()
{
   Request(4,&textinstr);
   writetext();
   strcpy(DGadget6SIUndo,DGadget6SIBuff);
   return(0);
}
yesnogadgets()
{
  Request(2,&twogad);
  return(0);
}
propgadget()
{
  Request(5,&proptext);
  return(0);
}

/*integer to ASCII string for display*/

void itoa(n,s)
int n;
char s[];
{
     int i;
     i=0;
     do 
          {
             s[i++] =n%10+'0';
          } 
     while ((n /= 10)>0);
     s[i] = '\0';
     reverse(s);
}

void reverse(s)
char s[];
{
     int c,i,j;
     for (i=0,j=strlen(s)-1;i<j;i++,j--)
         {
            c=s[i];
            s[i]=s[j];
            s[j]=c;
         }
}
