
#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;

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;

struct Clip *clip;
UBYTE  *ptr1, *ptr2;
long ptsize;

#define WIDTH 640
#define HEIGHT 200

struct NewScreen my_screen =
  {
    0, 0, WIDTH, HEIGHT,
    4,
    0, 1,
    HIRES,
    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()
  {
      if (clip)               HAME_DisposeClip(clip);
      if (ptr1)               FreeMem(ptr1, ptsize);
      if (window)             CloseWindow(window);
      if (screen)             CloseScreen(screen);
      if (HamePort)           HAME_Dispose(HamePort);
      if (HameBase)           CloseLibrary(HameBase);
      if (GfxBase)            CloseLibrary(GfxBase);
      if (IntuitionBase)      CloseLibrary(IntuitionBase);

      exit(0);
  }


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

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

/*
  Initialize the palette to a grey, a red, a green and a blue scale
  Note that the four groups are intermingled, and not separate groups
*/
void palette1()
  {
  int i, j, r;

  j = 1;
  for ( i = 0; i < 64; i++ )
    {
      r = i << 2;
      HAME_SetRGB8(HamePort, j++, r, r, r);
      HAME_SetRGB8(HamePort, j++, r, 0, 0);
      HAME_SetRGB8(HamePort, j++, 0, r, 0);
      HAME_SetRGB8(HamePort, j++, 0, 0, r);
    }
  }

/*
  Main routine
*/
int main(argc, argv)
  int argc;
  char *argv[];
  {
  ULONG  msg_class;
  USHORT msg_code;
  int    reg, i, j, 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, 196)) == NULL)
    {
      CloseStuff();
    }

  /* Set the pallette */
  palette1();

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

  /* 8 bit buffer is 128 x 128 */
  ptsize = 128*128;

  /* Get fast memory */
  ptr1 = AllocMem(ptsize, MEMF_PUBLIC|MEMF_CLEAR);
  ptr2 = ptr1;

  /* Create a strange pattern in the buffer */
  for ( i = 0; i < 128; i++ )
    {
      for ( j = 0; j < 128 ; j++ )
        {
          *ptr2++ = ((i & ~7) << 1) + (j >> 3);
        }
    }

  /* Render using increasingly wider and taller parameters */
  for ( i = 1; i <= 128; i++ )
    {
      HAME_8BitRender(HamePort, ptr1, 0, 0, i, i);
    }

  /* Pick up the final result */
  HAME_SetAPen(HamePort, 0);
  clip = HAME_GetClip(HamePort, 0, 0, 128, 128);
  if (!clip)
    {
      printf("No clip!\n");
      CloseStuff();
    }

  /* Copy it accross and down the sreen */
  for ( i = 0; i <= 3; i++ )
    {
      for ( j = 0; j < 2 ; j++ )
        {
          HAME_PutClip(HamePort, clip, (i << 7), (j << 7));
        }
    }

  /* Wait for mouse press */
  while( !finished )
    {
      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 INTUITICKS:
                for ( reg = 0; reg == 0; reg = rand() % 255 );
                HAME_SetRGB8(HamePort, reg, rand() % 255,
                                       rand() % 255, rand() % 255);
              break;

              case CLOSEWINDOW:
                finished = 1;
              break;

              default:
                printf("?");
            }
        }
     }

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

  CloseStuff();
}
