/***   [backg.c]
*
*	背景画 関連		(C)ささがわ
*
*	For GNU C Compiler (GCC)   Version 1.39
*
***/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "graph.h"
#include "optparse.h"
#include "others.h"
#include "icn.h"

extern int	PAL_Black;
static unsigned char	bgp[153600];

static void	beta(int);
static long	readN(FILE *, int);
static int	Tiff(char *);
static int	Tile(char *, int);
static void	transfill(void);

void BACKG_init(void) {
	int		no;
	char	path[90];
	
	ICN_mos(1);
	switch (OPT_BackG(path, &no)) {
		case 0:
			if (Tiff(path)) {
				WIND_error(3, path);
				beta(PAL_Black);
			}
			break;
		case 1:
			if (Tile(path, no)) {
				WIND_error(3, path);
				beta(PAL_Black);
			}
			break;
		default:
			if (1 <= no && no <= 15)
				beta(no);
			else
				beta(PAL_Black);
			break;
	}
	ICN_mos(0);
}

static void beta(int c) {
	memset(bgp, (c << 4) + c, 153600);
}

void BACKG_draw(int x, int y) {
	EGB_put(3, bgp, x, y, x + 639, y + 479);
}

static int Tiff(char *path) {
	int		i, ifdn, xx = 0, yy = 0, bp = 0;
	long	ifdoff, dataoff = 0;
	FILE	*fp;
	
	if ((fp = fopen(path, "rb")) == NULL)
		return -1;
	
	clearerr(fp);
	if (fgetc(fp) != 0x49 || fgetc(fp) != 0x49 || fgetc(fp) != 0x2a || fgetc(fp) != 0x00) {
		fclose(fp);
		return -1;
	}
	
	if ((ifdoff = readN(fp, 4)) < 0) {
		fclose(fp);
		return -1;
	}
	
	fseek(fp, ifdoff, SEEK_SET);
	if ((ifdn = readN(fp, 2)) < 0) {
		fclose(fp);
		return -1;
	}
	
	for (i = 0; i < ifdn; i++) {
		int		tag, a;
		
		tag = readN(fp, 2);
		fseek(fp, 6l, SEEK_CUR);
		a = readN(fp, 4);
		switch (tag) {
			case 0x0100:	xx = a;	break;
			case 0x0101:	yy = a;	break;
			case 0x0102:	bp = a;	break;
			case 0x0111:	dataoff = a;	break;
		}
	}
	if (xx < 1 || 640 < xx || yy < 1 || bp != 4 || dataoff < 0) {
		fclose(fp);
		return -1;
	}
	
	fseek(fp, dataoff, SEEK_SET);
	memset(bgp, 0, 153600);
	if (yy > 480)
		yy = 480;
	for (i = 0; i < yy; i++) {
		fread(bgp + i * 320, 1, (xx + 1) / 2, fp);
		if (ferror(fp) || feof(fp)) {
			fclose(fp);
			return -1;
		}
	}
	fclose(fp);
	transfill();
	
	return 0;
}

static int Tile(char *path, int n) {
	int		x, y;
	FILE	*fp;
	
	if ((fp = fopen(path, "rb")) == NULL)
		return -1;
	
	clearerr(fp);
	fseek(fp, n * 512, SEEK_SET);
	for (y = 0; y < 32; y++) {
		fread(bgp + y * 320, 1, 16, fp);
		if (ferror(fp) || feof(fp)) {
			fclose(fp);
			return -1;
		}
	}
	fclose(fp);
	
	for (y = 0; y < 15; y++) {
		for (x = 0; x < 20; x++) {
			int		i;
			
			if (x == 0 && y == 0)
				continue;
			
			for (i = 0; i < 32; i++)
				memcpy(bgp + y * 10240 + i * 320 + x * 16, bgp + i * 320, 16);
		}
	}
	transfill();
	
	return 0;
}

static long readN(FILE *fp, int n) {
	int		i, ret;
	
	for (ret = 0, i = 0; i < n; i++) {
		ret += fgetc(fp) << i * 8;
		if (ferror(fp) || feof(fp)) {
			ret = -1;
			break;
		}
	}
	
	return ret;
}

static void transfill(void) {
	int		i;
	
	for (i = 0; i < 153600; i++) {
		if ((bgp[i] & 0xf0) == 0)
			bgp[i] = (bgp[i] & 0x0f) + (PAL_Black << 4);
		if ((bgp[i] & 0x0f) == 0)
			bgp[i] = (bgp[i] & 0xf0) + PAL_Black;
	}
}
