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

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.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;
}
