// Compatibility layer with allegro

#include <SDL.h>
#include "raine.h"
#include <sys/stat.h>
#include "tilemod.h"
#include "compat2.h"
#include "cpuid.h"

SDL_Surface *sdl_screen;
SDL_PixelFormat *color_format;
SDL_Overlay *sdl_overlay;

void sdl_init() {
  /* Initialize the SDL library */
  if ( SDL_Init(SDL_INIT_AUDIO| SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
    exit(2);
  }
  atexit(SDL_Quit);
}

void sdl_done() {
  // This should also save the sdl specific params... Later !
  SDL_Quit();
}

BITMAP *surface_to_bmp(SDL_Surface *s) {
  int a;
  BITMAP *bmp;

  bmp = malloc( sizeof(BITMAP) + sizeof(char*) * s->h);
  bmp->extra = (void*)s;
  bmp->w = s->w; bmp->h = s->h;
  bmp->x_ofs = bmp->y_ofs = 0;
  for (a=0; a < s->h; a++)
    bmp->line[a] = (UINT8 *)s->pixels+a*s->pitch;
  bmp->dat = s->pixels;
  bmp->id = 0; // not a sub bitmap
  return bmp;
}

BITMAP *overlay_to_bmp(SDL_Overlay *s) {
  int a;
  BITMAP *bmp;
  // Works for packed yuv only

  bmp = malloc( sizeof(BITMAP) + sizeof(char*) * s->h);
  bmp->extra = (void*)s;
  bmp->w = s->w; bmp->h = s->h;
  bmp->x_ofs = bmp->y_ofs = 0;
  for (a=0; a < s->h; a++)
    bmp->line[a] = (UINT8 *)s->pixels[0]+a*s->pitches[0];
  bmp->dat = s->pixels[0];
  bmp->id = 2; // overlay
  return bmp;
}

BITMAP *sdl_create_bitmap_ex(int bpp, int w, int h) {
  // Init a fake bitmap to point to a newly created sdl_surface
  int r,g,b,a; // masks if necessary...
  SDL_Surface *s;

  if (bpp == 8) {
    r = g = b = a = 0; // Useless
  } else {
    const SDL_VideoInfo *inf = SDL_GetVideoInfo();
    SDL_PixelFormat *fmt = inf->vfmt;
    if (fmt->BitsPerPixel != bpp) {
      fprintf(stderr,"Something went wrong in bitmap creation\n");
      SDL_Quit();
    }
    r = fmt->Rmask;
    g = fmt->Gmask;
    b = fmt->Bmask;
    a = fmt->Amask;
  }

  s = SDL_CreateRGBSurface(SDL_SWSURFACE, // these bitmaps are ALWAYS in ram
			   w,h,bpp,r,g,b,a);
/*   if ( SDL_MUSTLOCK(screen) ) { */
/*     fprintf(stderr,"Locing problem !\n"); */
/*     SDL_Quit(-1); */
/*   } */

  return surface_to_bmp(s);
}

void sdl_create_overlay( int w, int h) {
  // Init a fake bitmap to point to a newly created sdl_surface
  SDL_PixelFormat *fmt = color_format;

  if (!(raine_cpu_capabilities & CPU_MMX)) {
    printf("no MMX support -> no overlay\n");
    return;
  }

  if (sdl_overlay)
    SDL_FreeYUVOverlay(sdl_overlay);
  sdl_overlay = SDL_CreateYUVOverlay( // these bitmaps are ALWAYS in ram
			   w,h,SDL_YUY2_OVERLAY, sdl_screen);
  if (!sdl_overlay->hw_overlay) {
    SDL_FreeYUVOverlay(sdl_overlay);
    sdl_overlay = NULL;
    printf("no hardware support for YUY2 overlay\n");
    return;
  }

  printf("w %d h %d bpp %d\n",w,h,color_format->BitsPerPixel);
  printf("masks r %x g %x b %x a %x\nshifts : %d,%d,%d,%d\n",
	 fmt->Rmask,fmt->Gmask,fmt->Bmask,fmt->Amask,
	 fmt->Rshift,fmt->Gshift,fmt->Bshift,fmt->Ashift);

  // force the right color format
  fmt->Rmask = 0x1f; fmt->Gmask = 0x7e0; fmt->Bmask = 0xf800;
  fmt->Rshift = 0;   fmt->Gshift= 5;     fmt->Bshift= 11;

/*   if ( SDL_MUSTLOCK(screen) ) { */
/*     fprintf(stderr,"Locing problem !\n"); */
/*     SDL_Quit(-1); */
/*   } */

  // return overlay_to_bmp(s);
}

void sdl_destroy_bitmap(BITMAP *bmp) {
  if (bmp) {
    if (bmp->extra) {
      if (bmp->id == 0) // real bitmap (not sub bitmap)
	SDL_FreeSurface((SDL_Surface*)bmp->extra);
      else if (bmp->id == 2) // sdl_overlay
	SDL_FreeYUVOverlay((SDL_Overlay*)bmp->extra);
    }
    free(bmp);
  }
}

// Strings...

void put_backslash(char *s) {
  int l = strlen(s)-1;
  s += l;
  if (*s != '/' && *s != '\\')
    strcat(s,SLASH);
}

UINT16 bytes_per_pixel(BITMAP *screen) {
  if (screen->extra)
    return ((screen->id&2) == 2 ? 2 : internal_bpp(((SDL_Surface*)screen->extra)->format->BitsPerPixel)/8);
  if (screen->vtable)
    return screen->vtable->color_depth/8;
  printf("no vtable and no extras for this bitmap !!!\n");
  exit(1);
  return 0;
}

struct BITMAP *sdl_create_sub_bitmap(struct BITMAP *src, int x, int y, int w, int h) {
  /* Apparently a sub bitmap is just a bitmap with x_ofs and y_ofs correctly */
  /* initialised... */

  BITMAP *bmp;
  int bpp;
  int n;

  if (src->id == 2) // SDL_Overlay
    bpp = 2;
  else
    bpp = bytes_per_pixel(src);

  bmp = malloc( sizeof(struct BITMAP) + sizeof(char*) * h);
  bmp->dat = src->dat;
  bmp->w = w; bmp->h = h;
  bmp->x_ofs = x;
  bmp->y_ofs = y;
  for (n=0; n<h; n++)
    bmp->line[n] = src->line[n+y] + bpp*x;
  bmp->extra = src->extra;
  bmp->id = src->id+1; // sub bitmap
  color_format = get_sdl_surface(GameBitmap)->format;
  if (bpp == 2) {
    sdl_create_overlay(w,h);
  }
  return bmp;
}
