/* dumb-pic.c
 * $Id: dumb-pic.c,v 1.1.1.1 2002/03/26 22:38:34 feedle Exp $
 *
 * Copyright 1997,1998 Alcibiades Petrofsky
 * <alcibiades@petrofsky.berkeley.ca.us>.
 * Any use permitted provided this notice stays intact.
 */
#include "dumb_frotz.h"

f_setup_t f_setup;

#define PIC_FILE_HEADER_FLAGS 1
#define PIC_FILE_HEADER_NUM_IMAGES 4
#define PIC_FILE_HEADER_ENTRY_SIZE 8
#define PIC_FILE_HEADER_VERSION 14

#define PIC_HEADER_NUMBER 0
#define PIC_HEADER_WIDTH 2
#define PIC_HEADER_HEIGHT 4

static struct {
  int z_num;
  int width;
  int height;
  int orig_width;
  int orig_height;
} *pict_info;
static int num_pictures = 0;

static unsigned char lookupb(unsigned char *p, int n) {return p[n];}
static unsigned short lookupw(unsigned char *p, int n)
{
  return (p[n + 1] << 8) | p[n];
}

void dumb_init_pictures (char *filename)
{
  FILE *file = NULL;
  int success = FALSE;
  unsigned char gheader[16];
  unsigned char *raw_info = NULL;
  int i, entry_size, flags;
  float x_scaler, y_scaler;

  do {
    if ((h_version != V6)
	|| !filename
	|| ((file = fopen (filename, "rb")) == NULL)
	|| (fread(&gheader, sizeof (gheader), 1, file) != 1))
      break;

    num_pictures = lookupw(gheader, PIC_FILE_HEADER_NUM_IMAGES);
    entry_size = lookupb(gheader, PIC_FILE_HEADER_ENTRY_SIZE);
    flags = lookupb(gheader, PIC_FILE_HEADER_FLAGS);

    raw_info = malloc(num_pictures * entry_size);

    if (fread(raw_info, num_pictures * entry_size, 1, file) != 1)
      break;

    pict_info = malloc((num_pictures + 1) * sizeof(*pict_info));
    pict_info[0].z_num = 0;
    pict_info[0].height = num_pictures;
    pict_info[0].width = lookupw(gheader, PIC_FILE_HEADER_VERSION);

    y_scaler = h_screen_rows / 200.0;
    x_scaler = h_screen_cols / ((flags & 0x08) ? 640.0 : 320.0);

    /* Copy and scale.  */
    for (i = 1; i <= num_pictures; i++) {
      unsigned char *p = raw_info + entry_size * (i - 1);
      pict_info[i].z_num = lookupw(p, PIC_HEADER_NUMBER);
      pict_info[i].orig_height = lookupw(p, PIC_HEADER_HEIGHT);
      pict_info[i].orig_width = lookupw(p, PIC_HEADER_WIDTH);
      pict_info[i].height = pict_info[i].orig_height * y_scaler + .5;
      pict_info[i].width = pict_info[i].orig_width * x_scaler + .5;
    }
    success = TRUE;
  } while (0);
  if (file)
    fclose(file);
  if (raw_info)
    free(raw_info);
  if (success)
    h_config |= CONFIG_PICTURES;
  else
    {
      h_flags &= ~GRAPHICS_FLAG;
      if (filename)
	fprintf(stderr, "Warning: could not read graphics file %s\n", filename);
    }
}

/* Convert a Z picture number to an index into pict_info.  */
static int z_num_to_index(int n)
{
  int i;
  for (i = 0; i <= num_pictures; i++)
    if (pict_info[i].z_num == n)
      return i;
  return -1;
}

bool os_picture_data(int num, int *height, int *width)
{
  int index;

  *height = 0;
  *width = 0;

  if (!pict_info)
    return FALSE;

  if ((index = z_num_to_index(num)) == -1)
    return FALSE;

  *height = pict_info[index].height;
  *width = pict_info[index].width;

  return TRUE;
}

void os_draw_picture (int num, int row, int col)
{
  int width, height, r, c;
  if (!os_picture_data(num, &height, &width) || !width || !height)
    return;
  col--, row--;
  /* Draw corners */
  dumb_set_picture_cell(row, col, '+');
  dumb_set_picture_cell(row, col + width - 1, '+');
  dumb_set_picture_cell(row + height - 1, col, '+');
  dumb_set_picture_cell(row + height - 1, col + width - 1, '+');
  /* sides */
  for (c = col + 1; c < col + width - 1; c++) {
    dumb_set_picture_cell(row, c, '-');
    dumb_set_picture_cell(row + height - 1, c, '-');
  }
  for (r = row + 1; r < row + height - 1; r++) {
    dumb_set_picture_cell(r, col, '|');
    dumb_set_picture_cell(r, col + width - 1, '|');
  }
  /* body, but for last line */
  for (r = row + 1; r < row + height - 2; r++)
    for (c = col + 1; c < col + width - 1; c++)
      dumb_set_picture_cell(r, c, ':');
  /* Last line of body, including picture number.  */
  if (height >= 3)
    for (c = col + width - 2; c > col; c--, (num /= 10))
      dumb_set_picture_cell(row + height - 2, c, num ? (num % 10 + '0') : ':');
}

int os_peek_colour (void) {return BLACK_COLOUR; }
