
#include <intuition/intuition.h>
#include <exec/types.h>
#include <exec/execbase.h>
#include <graphics/text.h>

#include <proto/exec.h>
#include <proto/graphics.h>

#include "hame_pragmas.h"
#include "HameStruct.h"
#include "HameProtos.h"
#include "HameRev.h"


#include <string.h>
#include <exec/memory.h>
#include <exec/tasks.h>

#include <graphics/view.h>
#include <graphics/gfx.h>
#include <graphics/rastport.h>

#include <proto/intuition.h>


struct Library *HameBase;
struct HamePort *HamePort;
struct HamePort *HamePort2;

extern struct Screen *OpenScreen();
extern struct Window *OpenWindow();

extern struct ExecBase *SysBase;  /* These are all pointers to system */
struct IntuitionBase *IntuitionBase;  /* These are all pointers to system */
struct GfxBase       *GfxBase;        /* data structures I need access to */

struct Screen        *screen;
struct Window        *window;

#define WIDTH 640
#define HEIGHT 400
#define YSIZ 190

struct NewScreen my_screen =
  {
    0, 0, WIDTH, HEIGHT,
    4,
    0, 1,
    HIRES | LACE,
    CUSTOMSCREEN,
    (struct TextAttr *) NULL,
    NULL,
    NULL, NULL
  };

struct NewWindow my_window =
  {
    0, 0, WIDTH, HEIGHT,
    (UBYTE) 0, (UBYTE) 1,
    MOUSEBUTTONS
       | INTUITICKS,
    SMART_REFRESH
       | BORDERLESS
       | BACKDROP
       | ACTIVATE
       | NOCAREREFRESH
       | REPORTMOUSE,
    NULL, NULL,
    NULL,
    NULL, NULL,
    0, 0, 0, 0,
    CUSTOMSCREEN
  };


/*
  Clean up and exit
*/
void CloseStuff()
  {
    struct Library *result;
      if (window)             CloseWindow(window);
      if (screen)             CloseScreen(screen);
      if (HamePort)           HAME_Dispose(HamePort);
      if (HamePort2)          HAME_Dispose(HamePort2);
      if (HameBase)           CloseLibrary(HameBase);
      if (GfxBase)            CloseLibrary(GfxBase);
      if (IntuitionBase)      CloseLibrary(IntuitionBase);


/* This sequence expunges the library if it is no longer in use */
      Forbid();
      if ( (result = (struct Library *) 
           FindName(&SysBase->LibList,"hame.library")) != NULL ) 
        {
          RemLibrary(result);
        }
      Permit();

      exit(0);
  }

/*
  Draw a random colored, random sized ellipse at a random location
*/
void DrawOval()
  {
  int cc, x, y, xr, yr, c, f;

  x = rand() % 320;
  y = rand() % YSIZ;
  xr = rand() % 140;
  yr = rand() % 50;
  f  = rand() % 2;

  while (!(c =  rand() % 256));

  HAME_SetAPen( HamePort, c );
  HAME_Ellipse(HamePort, x, y, xr, yr, f );

  HAME_SetAPen( HamePort2, c );
  HAME_Ellipse(HamePort2, x, YSIZ-y, xr, yr, f );

  if (f)
    {
      if ( (cc = HAME_ReadPixel(HamePort, x, y)) != c )
        {
          printf("EL wrote %ld read %ld at %ld,%ld\n", c, cc, x, y);
        }
    }
  }

/*
  Draw a random colored line in a random spot
*/
void DrawLine()
  {
  int cc, x1, y1, x2, y2, c;

  if (rand() & 1)  /* Vertical line */
    {
      x1 = rand() % 320;
      x2 = rand() % 320;
      y1 = rand() % YSIZ;
      y2 = y1;
    }
  else             /* Horizontal line */
    {
      x1 = rand() % 320;
      y1 = rand() % YSIZ;
      x2 = x1;
      y2 = rand() % YSIZ;
    }

  /* any color but color 0 */
  while (!(c =  rand() % 256));

  HAME_SetAPen( HamePort, c );
  HAME_Line(HamePort, x1, y1, x2, y2 );

  HAME_SetAPen( HamePort2, c );
  HAME_Line(HamePort2, x1, YSIZ-y1, x2, YSIZ-y2 );

  if ( (cc = HAME_ReadPixel(HamePort, x1, y1)) != c )
    {
      printf("LN wrote %ld read %ld at %ld,%ld\n", c, cc, x1, y1);
    }
  }

/*
  Change a random color register to random colors
*/
void DoCREG()
  {
  int reg, r, g, b;

  while (!(reg =  rand() % 256));
  r = rand() % 256;
  g = rand() % 256;
  b = rand() % 256;

  HAME_SetRGB8(HamePort, reg, r, g, b );
  HAME_GetRGB8(HamePort, reg );
  if ( HamePort->r != r ) printf(".R1.");
  if ( HamePort->g != g ) printf(".G1.");
  if ( HamePort->b != b ) printf(".B1.");

  HAME_SetRGB8(HamePort2, reg, r, g, b );
  HAME_GetRGB8(HamePort2, reg );
  if ( HamePort2->r != r ) printf(".R2.");
  if ( HamePort2->g != g ) printf(".G2.");
  if ( HamePort2->b != b ) printf(".B2.");
  }

/*
  Change a random color register to random colors
*/
void DoCycle()
  {
  int r1, r2, t;

  while(!(r1 = rand() % 256));
  while(!(r2 = rand() % 240));
  if ( r2 == r1 ) r2 += 8;

  if (r2 < r1)
    {
      t = r1; r1 = r2; r2 = t;
    }

  if ( rand() & 1)
    {
      HAME_CycleLeft(HamePort, r1, r2);
      HAME_CycleLeft(HamePort2, r1, r2);
    }
  else
    {
      HAME_CycleRight(HamePort, r1, r2);
      HAME_CycleRight(HamePort2, r1, r2);
    }
  }

/*
  Draw a random colored box in a random location
*/
void DrawBox()
  {
  int x1, y1, x2, y2, c, f;

  x1 = rand() % 320;
  x2 = rand() % 320;

  y1 = rand() % YSIZ;
  y2 = rand() % YSIZ;

  f  = rand() % 2;

  while (!(c =  rand() % 256));

  HAME_SetAPen( HamePort, c );
  HAME_Box(HamePort, x1, y1, x2, y2, f );
  HAME_SetAPen( HamePort2, c );
  HAME_Box(HamePort2, x1, YSIZ-y1, x2, YSIZ-y2, f );
  }


/*
  Decide which random object to draw
*/
void DrawThing()
 {
 int thing;

 thing = rand() % 5;
 switch(thing)
  {
   case 0:
    DoCREG();
   break;

   case 1:
    DrawLine();
   break;

   case 2:
    DrawBox();
   break;

   case 3:
    DrawOval();
   break;

   case 4:
    DoCycle();
   break;

   default:
   break;
  }
 }

/*
  Draw a vertical column of pixels at the left margin to prevent hame from
  turning off.
*/
void DrawLeftMargin()
  {
  int i;

  HAME_SetAPen( HamePort, 1 );
  HAME_SetAPen( HamePort2, 2 );
  for ( i = 0; i < YSIZ; i++ )
    {
      HAME_WritePixel( HamePort, 0, i);
      HAME_WritePixel( HamePort2, 0, i);
    }
  }

/*
  Initialize the pallette to random colors
*/
void palette1()
  {
  int i, r, g, b;

  for ( i = 1; i < 256; i++ )
    {
      r = rand() & 0xff;
      g = rand() & 0xff;
      b = rand() & 0xff;
      HAME_SetRGB8(HamePort, i, r, g, b);
      HAME_SetRGB8(HamePort2, i, r, g, b);
    }
  }

extern struct View *ViewAddress();

/*
  Main routine
*/
int main(argc, argv)
  int argc;
  char *argv[];
  {
  ULONG  msg_class;
  USHORT msg_code;
  int    finished=0;
  struct IntuiMessage *message;
  struct Gadget *gadget;


  if ((IntuitionBase = (struct IntuitionBase *)
       OpenLibrary("intuition.library",33L))==NULL)
    {
      CloseStuff();
    }

  if ((GfxBase = (struct GfxBase *)
       OpenLibrary("graphics.library" , 0L))==NULL)
    {
      CloseStuff();
    }

  /* Open the hame library */
  if ((HameBase = (struct Library *) 
       OpenLibrary("hame.library",HAMELIB_VERSION)) == NULL)
    {
      printf("No hame.library\n");
      CloseStuff();
    }


  /* Get a screen to play with */
  if ((screen = OpenScreen(&my_screen))     ==NULL)
    {
      CloseStuff();
    }

  my_window.Screen = screen;

  /* Get a window to play with */
  if ((window = OpenWindow(&my_window)) == NULL)
    {
      CloseStuff();
    }

  /* turn off the title bar */
  ShowTitle(screen, 0L);

  /* Tell the library where to put pixels */
  if ((HamePort = HAME_Init(screen, 640, 400, 400, 0, 0, 4, YSIZ)) == NULL)
    {
      CloseStuff();
    }

  /* Set up a second screen region */
  if ((HamePort2 = HAME_Init(screen, 640, 400, 400, 0, 200, 4, YSIZ)) == NULL)
    {
      CloseStuff();
    }

  /* Set the pallette */
  palette1();

  /* Keep hame from turning off because of screen wide color 0 */
  DrawLeftMargin();

  while( !finished )
    {
/*
      message = (struct IntuiMessage *) WaitPort(window->UserPort);
*/
      message = (struct IntuiMessage *) GetMsg(window->UserPort);
      if (message)
        {
          msg_class = message->Class;
          msg_code = message->Code;
          gadget = (struct Gadget *) message->IAddress;
          ReplyMsg((struct Message *)message);

          switch( msg_class )
            {
              case MOUSEBUTTONS:
                finished = 1;
              break;

              case MENUPICK:
              break;

              case GADGETUP:
              break;

              case INTUITICKS:
                /* Draw something in HAME mode */
                DrawThing();
              break;

              case CLOSEWINDOW:
                finished = 1;
              break;

              default:
                printf("?");
            }
        }
      else
        {
        DrawThing();
        }
     }

  while ((message = (struct IntuiMessage *)
          GetMsg( window->UserPort )) != NULL)
    {
      ReplyMsg((struct Message *)message);
    }

  CloseStuff();
}

