/* NetHack 5.0  ppmwrite.c	$NHDT-Date: 1596498336 2020/08/03 23:45:36 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ */
/* this produces a raw ppm file, with a 15-character header of
 * "P6 3-digit-width 3-digit-height 255\n"
 */

#include "config.h"
#include "tile.h"

#ifndef MONITOR_HEAP
extern long *alloc(unsigned int);
#endif

FILE *ppm_file;

struct ppmscreen {
    int Width;
    int Height;
} PpmScreen;

static int tiles_across, tiles_down, curr_tiles_across;
static pixel **image;

static void write_header(void);
static void WriteTileStrip(void);

static void
write_header(void)
{
    (void) fprintf(ppm_file, "P6 %03d %03d 255\n", PpmScreen.Width,
                   PpmScreen.Height);
}

static void
WriteTileStrip(void)
{
    int i, j;

    for (j = 0; j < TILE_Y; j++) {
        for (i = 0; i < PpmScreen.Width; i++) {
            (void) fputc((char) image[j][i].r, ppm_file);
            (void) fputc((char) image[j][i].g, ppm_file);
            (void) fputc((char) image[j][i].b, ppm_file);
        }
    }
}

boolean
fopen_ppm_file(const char *filename, const char *type)
{
    int i;

    if (strcmp(type, WRBMODE)) {
        Fprintf(stderr, "using writing routine for non-writing?\n");
        return FALSE;
    }
    ppm_file = fopen(filename, type);
    if (ppm_file == (FILE *) 0) {
        Fprintf(stderr, "cannot open ppm file %s\n", filename);
        return FALSE;
    }

    if (!colorsinmainmap) {
        Fprintf(stderr, "no colormap set yet\n");
        return FALSE;
    }

    tiles_across = 20;
    curr_tiles_across = 0;
    PpmScreen.Width = 20 * TILE_X;

    tiles_down = 0;
    PpmScreen.Height = 0; /* will be rewritten later */

    write_header();

    image = (pixel **) alloc(TILE_Y * sizeof(pixel *));
    for (i = 0; i < TILE_Y; i++) {
        image[i] = (pixel *) alloc(PpmScreen.Width * sizeof(pixel));
    }

    return TRUE;
}

boolean
write_ppm_tile(pixel (*pixels)[TILE_X]) 
{
    int i, j;

    for (j = 0; j < TILE_Y; j++) {
        for (i = 0; i < TILE_X; i++) {
            image[j][curr_tiles_across * TILE_X + i] = pixels[j][i];
        }
    }
    curr_tiles_across++;
    if (curr_tiles_across == tiles_across) {
        WriteTileStrip();
        curr_tiles_across = 0;
        tiles_down++;
    }
    return TRUE;
}

int
fclose_ppm_file(void)
{
    int i, j;

    if (curr_tiles_across) { /* partial row */
        /* fill with checkerboard, for lack of a better idea */
        for (j = 0; j < TILE_Y; j++) {
            for (i = curr_tiles_across * TILE_X; i < PpmScreen.Width;
                 i += 2) {
                image[j][i].r = MainColorMap[CM_RED][0];
                image[j][i].g = MainColorMap[CM_GREEN][0];
                image[j][i].b = MainColorMap[CM_BLUE][0];
                image[j][i + 1].r = MainColorMap[CM_RED][1];
                image[j][i + 1].g = MainColorMap[CM_GREEN][1];
                image[j][i + 1].b = MainColorMap[CM_BLUE][1];
            }
        }
        WriteTileStrip();
        curr_tiles_across = 0;
        tiles_down++;
    }

    for (i = 0; i < TILE_Y; i++) {
        free((genericptr_t) image[i]);
    }
    free((genericptr_t) image);

    PpmScreen.Height = tiles_down * TILE_Y;
    rewind(ppm_file);
    write_header(); /* update size */

    return (fclose(ppm_file));
}

int
main(int argc, char *argv[])
{
    pixel pixels[TILE_Y][TILE_X];

    if (argc != 3) {
        Fprintf(stderr, "usage: txt2ppm txtfile ppmfile\n");
        exit(EXIT_FAILURE);
    }

    if (!fopen_text_file(argv[1], RDTMODE))
        exit(EXIT_FAILURE);

    init_colormap();

    if (!fopen_ppm_file(argv[2], WRBMODE)) {
        (void) fclose_text_file();
        exit(EXIT_FAILURE);
    }

    while (read_text_tile(pixels))
        (void) write_ppm_tile(pixels);

    (void) fclose_text_file();
    (void) fclose_ppm_file();
    exit(EXIT_SUCCESS);
    /*NOTREACHED*/
    return 0;
}
