#define	LIBQSYS_CORE
#define	LIBQTOOLS_CORE
#include "../include/libqsys.h"
#include "../include/libqtools.h"

#ifndef	SWAPSHORT
short SwapShort(short l)
{
  unsigned char b1, b2;

  b1 = l & 255;
  b2 = (l >> 8) & 255;

  return (b1 << 8) + b2;
}
#endif

#ifndef	SWAPLONG
int SwapLong(int l)
{
  unsigned char b1, b2, b3, b4;

  b1 = l & 255;
  b2 = (l >> 8) & 255;
  b3 = (l >> 16) & 255;
  b4 = (l >> 24) & 255;

  return ((int)b1 << 24) + ((int)b2 << 16) + ((int)b3 << 8) + b4;
}

#endif

#ifndef	SWAPFLOAT
float SwapFloat(float l)
{
  union {
    unsigned char b[4];
    float f;
  } in, out;

  in.f = l;
  out.b[0] = in.b[3];
  out.b[1] = in.b[2];
  out.b[2] = in.b[1];
  out.b[3] = in.b[0];

  return out.f;
}
#endif

/* this is an offscreen-renderer */
#ifndef	OPENDISPLAY
struct DisplayDimension rootDim =
{0};								/* empty root at the beginning */

struct DisplayDimension *OpenDisplay(short int width, short int height, char depth, struct rgb *Palette)
{
  struct DisplayDimension *newDim;

  if ((newDim = (struct DisplayDimension *)tmalloc(sizeof(struct DisplayDimension)))) {
    newDim->changedOffset = TRUE;
    newDim->X = 0;
    newDim->Y = 0;
    newDim->changedSize = TRUE;
    newDim->Width = width;
    newDim->Height = height;
    newDim->changedDesktopOffset = TRUE;
    newDim->dtX = 0;
    newDim->dtY = 0;
    newDim->changedDesktopSize = TRUE;
    newDim->dtWidth = width;
    newDim->dtHeight = height;
    newDim->changedBuffer = TRUE;
    newDim->frameDepth = depth;
    newDim->frameSize = width * height;
    newDim->ID = rootDim.ID;
    newDim->nextDim = rootDim.nextDim;
    newDim->driverPrivate = 0;

    rootDim.nextDim = newDim;
    rootDim.ID++;

    if (depth <= 8)
      newDim->frameBPP = 1;					/* index based */
    else if (depth <= 16)
      newDim->frameBPP = 2;					/* 15/16 bit rgb */
    else if (depth <= 24)
      newDim->frameBPP = 3;					/* 24 bit rgb */
    else
      newDim->frameBPP = 4;					/* 32 bit argb */

    if (!(newDim->frameBuffer = (void *)tmalloc(width * height * newDim->frameBPP)))
      Error(failed_memoryunsize, "offscreen framebuffer");
#ifdef	USE_ZBUFFER
    if (!(newDim->zBuffer = (unsigned short int *)tmalloc(width * height * sizeof(unsigned short int))))
        Error(failed_memoryunsize, "offscreen zbuffer");

#endif
  }

  return newDim;
}
#endif

/* this swaps buffer if doublebuffer */
#ifndef	SWAPDISPLAY
void *SwapDisplay(void *oldBuffer)
{
  return oldBuffer;
}
#endif

#ifndef	UPDATEDISPLAY
void *UpdateDisplay(void *oldBuffer, short int x, short int y, short int width, short int height)
{
  return oldBuffer;
}
#endif

#ifndef	CHANGEDISPLAY
struct DisplayDimension *ChangeDisplay(short int width, short int height, char depth, struct rgb *Palette, char *Title)
{
  return 0;
}
#endif

/*
 * 
 */
#ifndef	CLOSEDISPLAY
void CloseDisplay(void)
{
}

#endif

/*
 * 
 */
#ifndef	OPENKEYS
void OpenKeys(void)
{
}

#endif

/*
 * the caller repeats through this untill it gets -1 or ESCAPE as a terminator
 * or return FALSE
 */
#ifndef	GETKEYS
bool GetKeys(struct keyEvent *eventBuffer)
{
  eventBuffer->pressed = RAWKEY_ESCAPE;
  return TRUE;
}
#endif

/*
 * 
 */
#ifndef	CLOSEKEYS
void CloseKeys(void)
{
}

#endif

/*
 * 
 */
#ifndef	OPENMOUSE
void OpenMouse(void)
{
}

#endif

/*
 * the caller repeats through this untill it gets -1
 */
#ifndef	GETMOUSE
void GetMouse(struct mouseEvent *eventBuffer)
{
  eventBuffer->pressed = RAWMOUSE_NOTHING;
  eventBuffer->mouseX = 0;
  eventBuffer->mouseY = 0;
}

#endif

/*
 * 
 */
#ifndef	CLOSEMOUSE
void CloseMouse(void)
{
}

#endif

/*
 * this is a generic match
 */
#ifndef	MATCH
unsigned char Match(register struct rgb *rawpix, register struct rgb *Palette)
{
  unsigned char palpix = 0;
  short int i;
  short int match = 0x7FFF;

  /* save conversion? has a palette only 6 valid bits? */
  short int rawpixR = (short int)(rawpix->r);
  short int rawpixG = (short int)(rawpix->g);
  short int rawpixB = (short int)(rawpix->b);

  /* find match */
  for (i = 0; i < 256; i++) {
    short int R, G, B, thismatch;

    if ((R = (short int)(Palette[i].r) - rawpixR) < 0)
      R = -R;
    if ((G = (short int)(Palette[i].g) - rawpixG) < 0)
      G = -G;
    if ((B = (short int)(Palette[i].b) - rawpixB) < 0)
      B = -B;
    if ((thismatch = R + G + B) != 0) {
      if (thismatch < match) {
	match = thismatch;
	palpix = (unsigned char)i;
      }
    }
    else
      return (unsigned char)i;
  }
  return palpix;
}
#endif

struct DisplayDimension localDim;

void SetDisplay(struct DisplayDimension *dim)
{
  localDim = *dim;
}
