#include "exec/types.h"
#include "exec/memory.h"
#include "intuition/intuition.h"
#include "graphics/gfxmacros.h"
#include "graphics/sprite.h"

#define  AANTALSPR    6   /* AANTALSPR is eigenlijk 1 teveel ! */
#define INTUITION_REV 31
#define GRAPHICS_REV 31
#define ABS(X)  ( (X) < 0 ? (-X) : (X) )

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Screen *Scrn;
struct Window *NoBorder;
struct ViewPort *vp;
struct RastPort *r;
struct SimpleSprite sprite[AANTALSPR];
struct SimpleSprite *sprt;
struct IntuiMessage *mesg;

UWORD *sprdata[AANTALSPR];
UWORD sprite_data[404];

#define MAXW  320 /* max width van window ! */
#define MAXH  200 /* max height van window ! */
#define HALFMAXH MAXH/2-1

struct NewScreen NewScrn = {
        0, 0,           /* LeftEdge, TopEdge */
        320, 200,       /* Width, Height */
        5,              /* Depth */
        0, 1,           /* DetailPen, BlockPen */
        SPRITES,        /* ViewModes ... value of 0 = low resolution */
        CUSTOMSCREEN,   /* Type of screen */
        NULL,           /* Font to be used as default for this screen */
        NULL,           /* DefaultTitle for its title bar */
        NULL,           /* screens user-gadgets, always NULL, ignored */
        NULL };         /* address of custom bitmap for screen */

struct NewWindow NewNoBorder = {
        0,              /* LeftEdge */
        0,              /* TopEdge  */
        MAXW, MAXH,     /* Width, Height of this window */
        -1,             /* DetailPen */
        -1,             /* BlockPen */
        MOUSEBUTTONS,   /* IDCMP Flags */
        ACTIVATE|NOCAREREFRESH|BORDERLESS|GIMMEZEROZERO,
                        /* Window Flags:  (see below for more info) */
        NULL,           /* FirstGadget */
        NULL,           /* CheckMark   */
        NULL,           /* Window title */
        NULL,           /* Pointer to Screen if not workbench */
        NULL,           /* Pointer to BitMap if a SUPERBITMAP window */
        0, 0,           /* minimum width, minimum height */
        0,0,            /* maximum width, maximum height */
        CUSTOMSCREEN    /* type waarin window opend */
        };



int dxcte, dycte, dx[AANTALSPR], dy[AANTALSPR];
int teller=0, xpos[AANTALSPR], ypos[AANTALSPR], spgot[AANTALSPR];
int afstand,aantaltellen;

main(argc,argv)
int argc;
char *argv[];
{
 SHORT i,j,xzijde,yzijde,xnul,ynul;
 ULONG mclass;
 UWORD *src, *dest;

 VOID OpenALL(), CloseALL(), CleanUp();


 /* ---------- einde defs ------------ */

 OpenALL();

 if((Scrn = (struct Screen *) OpenScreen(&NewScrn)) == 0) CloseALL();
 
 NewNoBorder.Screen = Scrn;

 if((NoBorder = (struct Window *) OpenWindow(&NewNoBorder)) == 0) CloseALL();

 r=NoBorder->RPort;
 vp=ViewPortAddress(NoBorder);

  SetRGB4(vp,0,0,0,0);
  for(i=1;i<16;i++)
  {
   SetRGB4(vp,i,i,i,i);
  }
  for(i=16;i<28;i+=4)
  {
   SetRGB4(vp,  i,15,15,15);
   SetRGB4(vp,  i+1,i%16,0,15);
   SetRGB4(vp,  i+2,i%16,0,4);
   SetRGB4(vp,  i+3,15,15,15);
  }

 sprite_data[0] = 0x0000;
 sprite_data[1] = 0x0000;
 for(i=2;i<402;i++)sprite_data[i]=0xAAAA;
 sprite_data[402] = 0x0000;
 sprite_data[403] = 0x0000;



 sprt = &sprite[1];

 for(i=1;i<AANTALSPR;i++)
 {
  spgot[i] = GetSprite(sprt,i);
  if(spgot[i] != i) 
  {
   puts("Kan sprite niet alloceren.\n");
   CleanUp();
  }

  sprite[i].x = sprite[i].y = 0;
  sprite[i].height = 200;

  sprdata[i] = (UWORD *)AllocMem((sprite[i].height+2)*4,MEMF_CHIP);

  if(sprdata[i] == NULL)
  {
   FreeSprite(spgot[i]);
   break;
  }

  src = sprite_data; dest = sprdata[i];

  for(j=0;j<(sprite[i].height+2)*2;j++) *dest++ = *src++;
 
  ChangeSprite(0,sprt,sprdata[i]);
  MoveSprite(0,sprt,0,0);
  sprt++;
 }

 if(argc>1)
  dxcte=atoi(argv[1]); /* dxcte : snelheid in x-richting */
 else
  dxcte=1;

 if(argc>2)
  dycte=atoi(argv[2]); /* snelheid in y-richting */
 else
  dycte=0;

 if(argc>3)
  afstand=atoi(argv[3]); /* x-afstand tussen sprites */
 else
  afstand=16;

 if(argc>4)
  aantaltellen=atoi(argv[4]); /* na hoeveel tellen dat de kleuren veranderen */
 else
  aantaltellen=20;


/* rechthoeken */

 xzijde = 16;
 yzijde = 10;

 for(j=0;j<10;j++)
 {
  for(i=0;i<10;i++)
  {
   SetAPen(r,1+((i+j)%15));
   xnul = 0;ynul = 0;
   RectFill(r,xnul+xzijde*i,ynul+yzijde*j,xnul+xzijde*(i+1),ynul+yzijde*(j+1));
   RectFill(r,xnul+xzijde*j,ynul+yzijde*i,xnul+xzijde*(j+1),ynul+yzijde*(i+1));

   xnul = 319;ynul = 0;
   RectFill(r,xnul-xzijde*(i+1),ynul+yzijde*j,xnul-xzijde*i,ynul+yzijde*(j+1));
   RectFill(r,xnul-xzijde*(j+1),ynul+yzijde*i,xnul-xzijde*j,ynul+yzijde*(i+1));
   
   xnul = 0;ynul = 200;
   RectFill(r,xnul+xzijde*i,ynul-yzijde*(j+1),xnul+xzijde*(i+1),ynul-yzijde*j);
   RectFill(r,xnul+xzijde*j,ynul-yzijde*(i+1),xnul+xzijde*(j+1),ynul-yzijde*i);

   xnul = 319;ynul = 200;
   RectFill(r,xnul-xzijde*(i+1),ynul-yzijde*(j+1),xnul-xzijde*i,ynul-yzijde*j);
   RectFill(r,xnul-xzijde*(j+1),ynul-yzijde*(i+1),xnul-xzijde*j,ynul-yzijde*i);
  }
 }



InitSpritePositions();


 /* ======einde in stijl !====== */
for(;;)
 {
   while((mesg=(struct IntuiMessage *) GetMsg(NoBorder->UserPort))==NULL)
   {
    NewPositions_and_Display();
   } /* end while */

   ReplyMsg(mesg);
   mclass=mesg->Class;
   if( (mclass=mesg->Class) == MOUSEBUTTONS) break;
 }

  CleanUp();
}

/*  -------------------------------- einde van main ------------------- */

VOID OpenALL()
{
 /*==Intuition==*/

 IntuitionBase=(struct IntuitionBase *)
            OpenLibrary("intuition.library",INTUITION_REV);

 if(IntuitionBase==NULL)
    CloseALL();

 /*==Graphics Library==*/

 GfxBase=(struct GfxBase *)
          OpenLibrary("graphics.library",GRAPHICS_REV);

 if(GfxBase==NULL)
    CloseALL();

}

VOID CloseALL()
{
 if(NoBorder) CloseWindow(NoBorder);
 if(Scrn) CloseScreen(Scrn);
 if(GfxBase) CloseLibrary(GfxBase);
} 

VOID CleanUp()
{
 SHORT i;

 for(i=0;i<AANTALSPR;i++) if(spgot[i] != -1) FreeSprite(spgot[i]);
 
 CloseALL();
}

InitSpritePositions()
{
 int i;

 for(i=1;i<AANTALSPR;i++)
 {
  dx[i] = dxcte;
  dy[i] = dycte;
  xpos[i] = i*afstand;
  ypos[i] = 0;
 }

}


NewPositions_and_Display()
{
 int i,k;

 for(i=1;i<AANTALSPR;i++)
 {
 if( (xpos[i] < 0) || xpos[i] > (MAXW-1-( 16+(ABS(dx[i])) )) ) 
  dx[i] = -dx[i];                      /* 16 = sprite.width */
 if( (ypos[i] < 0) || ypos[i] > (MAXH-1-( sprite[i].height+(ABS(dy[i])) )) )
  dy[i] = -dy[i];
 }


  if(teller>aantaltellen)
  {
   teller=0;
  }
  else
  {
   for(i=1;i<16;i++) SetRGB4(vp,i,0,(i+teller)%16,(i+teller)%16,(i+teller)%16);
   teller++;
  }

for(i=1;i<AANTALSPR;i++)
 {
  WaitBOVP(vp);
  MoveSprite(0,&sprite[i],xpos[i]+= dx[i],ypos[i]+= dy[i]);
 }
}

