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

#define  AANTALSPR    8   /* 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 *spr;
struct IntuiMessage *mesg;

UWORD *sprdata[AANTALSPR];
UWORD sprite_data[] =
  {
  0,0,

  0xffff, 0xffff,
  0xffff, 0xffff,

  0xc003, 0xce73,
  0xc003, 0xce73,

  0xff8f, 0xc073,
  0xff8f, 0xc073,

  0xc003, 0xce73,
  0xc003, 0xce73,

  0xf1ff, 0xce03,
  0xf1ff, 0xce03,

  0xc003, 0xce73,
  0xc003, 0xce73,

  0xffff, 0xffff,
  0xffff, 0xffff,

  0,0
  };

UWORD patroon[4] = {0x5050,0x8888,0xAAAA,0xFFFF};


#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 */
        };



SHORT dx, dy, teller=0, xpos[AANTALSPR], ypos[AANTALSPR], spgot[AANTALSPR];

main(argc,argv)
int argc;
char *argv[];
{
 SHORT i,j,xzijde,yzijde,xnul,ynul,nrofcolors;
 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,(12+i*2)%16,3+i,8+i);
   SetRGB4(vp,i+1,3+i%13,13,(i*2+4)%16);
   SetRGB4(vp,i+2,(12-i*3)%16,10,i%12+4);
   SetRGB4(vp,i+3,(15-i)%16,1,(i*4)%7+5);
  }

 spr = &sprite[1];

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

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

  sprdata[i] = (UWORD *)AllocMem(64,MEMF_CHIP);

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

  src = sprite_data; dest = sprdata[i];

  for(j=0;j<32;j++) *dest++ = *src++;
 
  ChangeSprite(0,spr,sprdata[i]);
  MoveSprite(0,spr,0,0);
  spr++;
 }

 if(argc>1)
  dx=atoi(argv[1]);
 else
  dx=4;

 if(argc>2)
  dy=atoi(argv[2]);
 else
  dy=dx;

 if(argc>3)
  nrofcolors=atoi(argv[3]);
 else
  nrofcolors=15;


/* rechthoeken */

 xzijde = 16;
 yzijde = 10;

 for(j=0;j<10;j++)
 {
  for(i=0;i<10;i++)
  {
   SetAPen(r,1+((i+j)%nrofcolors));
   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();
    DisplaySprites();
   } /* 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()
{
 SHORT i;

 for(i=1;i<AANTALSPR;i++)
 MoveSprite(0,&sprite[i],(AANTALSPR-i)*(ABS(dx)),(AANTALSPR-i)*(ABS(dy)));
}


NewPositions()
{
 SHORT i;

 for(i=AANTALSPR-1;i>=2;i--)
 {
  xpos[i] = xpos[i-1];
  ypos[i] = ypos[i-1];
 }

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

  SetAPen(r,teller%15+1);
  if(teller>319)
  {
   teller=0;
  }
  else
  {
   teller++;
   for(i=1;i<16;i++) SetRGB4(vp,i,0,(i+teller)%16,16-(i+teller)%16);
  }

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

