/*
 * Read a .res file and create a resource-tree
 *
 * Copyright 1998 Bertho A. Stultiens
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include <config.h>
#include "wrc.h"
#include "readres.h"
#include "newstruc.h"
#include "utils.h"
#include "genres.h"

struct resheader32 {
	DWORD	ressize;	/* 0 */
	DWORD	hdrsize;	/* 0x20 */
	WORD	restype1;	/* 0xffff */
	WORD	restype2;	/* 0 */
	WORD	resname1;	/* 0xffff */
	WORD	resname2;	/* 0 */
	DWORD	dversion;	/* 0 */
	WORD	memopt;		/* 0 */
	WORD	language;	/* 0 */
	DWORD	version;	/* 0 */
	DWORD	characts;	/* 0 */
} emptyheader = {0, 0x20, 0xffff, 0, 0xffff, 0, 0, 0, 0, 0, 0};

/*
 *****************************************************************************
 * Function	:
 * Syntax	:
 * Input	:
 * Output	:
 * Description	:
 * Remarks	:
 *****************************************************************************
*/
/*
 *****************************************************************************
 * Function	:
 * Syntax	:
 * Input	:
 * Output	:
 * Description	:
 * Remarks	:
 *****************************************************************************
*/
/*
 *****************************************************************************
 * Function	:
 * Syntax	:
 * Input	:
 * Output	:
 * Description	:
 * Remarks	:
 *****************************************************************************
*/
int read_data(FILE *fp, size_t size, void *buf)
{
	int r;
	int pos = ftell(fp);
	r = fread(buf, 1, size, fp);
	if(r == size)
		return 0;
	if(r == 0 && ftell(fp) - pos > 0)
		return 1;
	else
		return -1;
}

/*
 *****************************************************************************
 * Function	:
 * Syntax	:
 * Input	:
 * Output	:
 * Description	:
 * Remarks	:
 *****************************************************************************
*/
enum res_e res_type_from_id(name_id_t *nid)
{
	if(nid->type == name_str)
		return res_usr;

	if(nid->type != name_ord)
		internal_error(__FILE__, __LINE__, "Invalid name_id descriptor %d", nid->type);

	switch(nid->name.i_name)
	{
	case WRC_RT_CURSOR:		return res_cur;
	case WRC_RT_BITMAP:		return res_bmp;
	case WRC_RT_ICON:		return res_ico;
	case WRC_RT_MENU:		return res_men;
	case WRC_RT_DIALOG:		return res_dlg;
	case WRC_RT_STRING:		return res_stt;
	case WRC_RT_FONTDIR:		return res_fntdir;
	case WRC_RT_FONT:		return res_fnt;
	case WRC_RT_ACCELERATOR:	return res_acc;
	case WRC_RT_RCDATA:		return res_rdt;
	case WRC_RT_MESSAGETABLE:	return res_msg;
	case WRC_RT_GROUP_CURSOR:	return res_curg;
	case WRC_RT_GROUP_ICON:		return res_icog;
	case WRC_RT_VERSION:		return res_ver;
	case WRC_RT_TOOLBAR:		return res_toolbar;

	default:
	case WRC_RT_DLGINCLUDE:
	case WRC_RT_PLUGPLAY:
	case WRC_RT_VXD:
	case WRC_RT_ANICURSOR:
	case WRC_RT_ANIICON:
		warning("Cannot be sure of resource type, using usertype settings");
		return res_usr;
	}
}

/*
 *****************************************************************************
 * Function	:
 * Syntax	:
 * Input	:
 * Output	:
 * Description	:
 * Remarks	:
 *****************************************************************************
*/
#define get_word(idx)	(*((WORD *)(&res->data[idx])))
#define get_dword(idx)	(*((DWORD *)(&res->data[idx])))

resource_t *read_res32(FILE *fp)
{
	static char wrong_format[] = "Wrong resfile format (32bit)";
	DWORD ressize;
	DWORD hdrsize;
	DWORD totsize;
	WORD memopt;
	WORD language;
	int err;
	res_t *res;
	resource_t *rsc;
	resource_t *tail = NULL;
	resource_t *list = NULL;
	name_id_t *type = NULL;
	name_id_t *name = NULL;
	int idx;
	enum res_e res_type;
	user_t *usrres;

	while(1)
	{
		/* Get headersize and resource size */
		err = read_data(fp, sizeof(ressize), &ressize);
		if(err < 0)
			break;
		else if(err > 0)
			error(wrong_format);
		err = read_data(fp, sizeof(hdrsize), &hdrsize);
		if(err)
			error(wrong_format);

		/* Align sizes and compute total size */
		totsize = hdrsize;
		if(hdrsize & 3)
		{
			warning("Hu? .res header needed alignment (anything can happen now)");
			totsize += 4 - (hdrsize & 3);
		}
		totsize += ressize;
		if(ressize & 3)
			totsize += 4 - (ressize & 3);

		/* Read in entire data-block */
		fseek(fp, -8, SEEK_CUR);
		res = new_res();
		if(res->allocsize < totsize)
			grow_res(res, totsize - res->allocsize + 8);
		err = read_data(fp, totsize, res->data);
		if(err)
			error(wrong_format);

		res->dataidx = hdrsize;
		res->size = hdrsize + ressize;

		/* Analyse the content of the header */
		idx = 8;
		/* Get restype */
		if(get_word(idx) == 0xffff)
		{
			idx += sizeof(WORD);
			type = new_name_id();
			type->type = name_ord;
			type->name.i_name = get_word(idx);
			idx += sizeof(WORD);
		}
		else if(get_word(idx) == 0)
		{
			error("ResType name has zero length (32 bit)");
		}
		else
		{
			int tag = idx;
			string_t *str;
			while(1)
			{
				idx += sizeof(WORD);
				if(!get_word(idx))
					break;
			}
			idx += sizeof(WORD);
			str = new_string();
			str->type = str_unicode;
			str->size = (idx - tag) / 2;
			str->str.wstr = (short *)xmalloc(idx-tag+2);
			memcpy(str->str.wstr, &res->data[tag], idx-tag);
			str->str.wstr[str->size] = 0;
			type = new_name_id();
			type->type = name_str;
			type->name.s_name = str;
		}
		/* Get resname */
		if(get_word(idx) == 0xffff)
		{
			idx += sizeof(WORD);
			name = new_name_id();
			name->type = name_ord;
			name->name.i_name = get_word(idx);
			idx += sizeof(WORD);
		}
		else if(get_word(idx) == 0)
		{
			error("ResName name has zero length (32 bit)");
		}
		else
		{
			int tag = idx;
			string_t *str;
			while(1)
			{
				idx += sizeof(WORD);
				if(!get_word(idx))
					break;
			}
			idx += sizeof(WORD);
			str = new_string();
			str->type = str_unicode;
			str->size = (idx - tag) / 2;
			str->str.wstr = (short *)xmalloc(idx-tag+2);
			memcpy(str->str.wstr, &res->data[tag], idx-tag);
			str->str.wstr[str->size] = 0;
			name = new_name_id();
			name->type = name_str;
			name->name.s_name = str;
		}

		/* align */
		if(idx & 0x3)
			idx += 4 - (idx & 3);

		idx += sizeof(DWORD);	/* Skip DataVersion */
		memopt = get_word(idx);
		idx += sizeof(WORD);
		language = get_word(idx);

		/* Build a resource_t list */
		res_type = res_type_from_id(type);
		if(res_type == res_usr)
		{
			/* User-type has custom ResType for .[s|h] generation */
			usrres = new_user(type, NULL, new_int(memopt));
		}
		else
			usrres = NULL;
		rsc = new_resource(res_type,
				   usrres,
				   memopt,
				   new_language(PRIMARYLANGID(language),
						SUBLANGID(language)));
		rsc->binres = res;
		rsc->name = name;
		rsc->c_name = make_c_name(get_c_typename(res_type), name, rsc->lan);
		if(!list)
		{
			list = rsc;
			tail = rsc;
		}
		else
		{
			rsc->prev = tail;
			tail->next = rsc;
			tail = rsc;
		}
	}
	return list;
}

/*
 *****************************************************************************
 * Function	:
 * Syntax	:
 * Input	:
 * Output	:
 * Description	:
 * Remarks	:
 *****************************************************************************
*/
resource_t *read_res16(FILE *fp)
{
	internal_error(__FILE__, __LINE__, "Can't yet read 16 bit .res files");
	return NULL;
}

/*
 *****************************************************************************
 * Function	: read_resfile
 * Syntax	: resource_t *read_resfile(char *inname)
 * Input	:
 * Output	:
 * Description	:
 * Remarks	:
 *****************************************************************************
*/
resource_t *read_resfile(char *inname)
{
	FILE *fp;
	struct resheader32 rh;
	int is32bit;
	resource_t *top;

	fp = fopen(inname, "rb");
	if(!fp)
		error("Could not open inputfile %s", inname);

	/* Determine 16 or 32 bit .res file */
	if(fread(&rh, 1, sizeof(rh), fp) != sizeof(rh))
		is32bit = 0;
	else
	{
		if(!memcmp(&emptyheader, &rh, sizeof(rh)))
			is32bit = 1;
		else
			is32bit = 0;
	}

	if(is32bit && !win32)
		error("Cannot convert 32-bit .res-file into 16-bit resources (and will, hopefully never, implement it)");

	if(!is32bit && win32)
		error("Cannot (yet) convert 16-bit .res-file into 32-bit resources");

	if(!is32bit)
	{
		fseek(fp, 0, SEEK_SET);
		top = read_res16(fp);
	}
	else
	{
		top = read_res32(fp);
	}

	fclose(fp);

	return top;
}
