/*****

      $Source: d:\gunther\source\grc/RCS/resfile.c,v $
      $Author: gunther $
      $Date: 1996/01/02 23:17:24 $
      $Revision: 1.1 $

	Changed by: Fred Kiefer (kiefer@isys.de) 1996/6/2

 *****/

#include "resfile.h"
#include "portio.h"
#include "resnt.h"
#include "rcutils.h"

int
writePadding(int padding, FILE *res)
{
	char pad[] ={0, 0, 0, 0};
 
	if(padding)
	{
		if(fwrite(&pad, 1, padding, res) != padding)
		{
			return FALSE;
		}
	}
	return TRUE;
}

int
writeResourceHeaderTail(ResourceTail *tail, FILE *f)
{
    register int retcode = 0;

    retcode += write_int32(&tail->DataVersion, f);
    retcode += write_int16(&tail->MemoryFlags, f);
    retcode += write_int16(&tail->LanguageId, f);
    retcode += write_int32(&tail->Version, f);
    retcode += write_int32(&tail->Characteristics, f);
    return retcode;         /* 16 */
}


int
readResourceHeaderTail(ResourceTail *tail, FILE *f)
{
    register int retcode = 0;

    retcode += read_int32(&tail->DataVersion, f);
    retcode += read_int16(&tail->MemoryFlags, f);
    retcode += read_int16(&tail->LanguageId, f);
    retcode += read_int32(&tail->Version, f);
    retcode += read_int32(&tail->Characteristics, f);
    return retcode;         /* 16 */
}


int
writeNameOrId(wchar_t *nameorid, FILE *f)
{
    int retcode = 0;

    if(nameorid[0] == INVAL_WCHAR)
    {
        /* write the integer value */
        retcode += write_int16(&nameorid[0], f);
        retcode += write_int16(&nameorid[1], f);
    }

    else
    {
        /* write the UNICODE string */
        register int i;

        for(i = 0; nameorid[i] != 0; i++)
            retcode += write_int16(&nameorid[i], f);

        /* write the trailing 0 */
        retcode += write_int16(&nameorid[i], f);
    }

    return retcode;         /* getIDlength(nameorid) */
}


int
readNameOrId(wchar_t *nameorid, FILE *f)
{
    int retcode = 0;

    retcode += read_int16(nameorid, f);

    if(nameorid[0] == INVAL_WCHAR)
        retcode += read_int16(&nameorid[1], f);

    else
    {
        register int i;

        for(i = 1;;i++)
        {
            retcode += read_int16(&nameorid[i], f);

            if(nameorid[i] == 0)
                break;
        }
    }

    return retcode;
}


int
writeResourceHeader(DWORD *DataSize, DWORD *HeaderSize, wchar_t *type, wchar_t *name, 
                    ResourceTail *tail, FILE *f)
{
	int padding = 0;
	int retcode = 0;
    
    *HeaderSize = 2 * sizeof(DWORD) + TAIL_SIZE + /* DataSize, HeaderSize, tail */
                  getIDlength(type) +
                  getIDlength(name);

	padding = PADDING(*HeaderSize, 4);
	*HeaderSize = ROUNDUP(*HeaderSize, 4);

    retcode += write_int32(DataSize, f);
    retcode += write_int32(HeaderSize, f);
    retcode += writeNameOrId(type, f);
    retcode += writeNameOrId(name, f);

	if (writePadding(padding, f))
		retcode += padding;

    retcode += writeResourceHeaderTail(tail, f);
    return retcode;    /* retcode == *HeaderSize: all is Ok */
}


int
readResourceHeader(DWORD *DataSize, DWORD *HeaderSize, wchar_t *type, wchar_t *name,
                    ResourceTail *tail, FILE *f)
{
    int retcode = 0;
    int padding;

    retcode += read_int32(DataSize, f);
    retcode += read_int32(HeaderSize, f);
    retcode += readNameOrId(type, f);
    retcode += readNameOrId(name, f);

    if ((padding = (ftell(f) % 4)))
    {
      padding = 4 - padding;
        retcode += padding;
        fseek(f, padding, SEEK_CUR);
    }

    retcode += readResourceHeaderTail(tail, f);

    return *HeaderSize;
}

int
writeICONDIRENTRY(ICONDIRENTRY *entry, FILE *f)
{
    int retcode = 0;

    retcode += write_int8(&entry->bWidth, f);
    retcode += write_int8(&entry->bHeight, f);
    retcode += write_int8(&entry->bColorCount, f);
    retcode += write_int8(&entry->bReserved, f);
    retcode += write_int16(&entry->wPlanes, f);
    retcode += write_int16(&entry->wBitCount, f);
    retcode += write_int32(&entry->dwBytesInRes, f);
    retcode += write_int32(&entry->dwImageOffset, f);

    return retcode;
}


int
readICONDIRENTRY(ICONDIRENTRY *entry, FILE *f)
{
    int retcode = 0;

    retcode += read_int8(&entry->bWidth, f);
    retcode += read_int8(&entry->bHeight, f);
    retcode += read_int8(&entry->bColorCount, f);
    retcode += read_int8(&entry->bReserved, f);
    retcode += read_int16(&entry->wPlanes, f);
    retcode += read_int16(&entry->wBitCount, f);
    retcode += read_int32(&entry->dwBytesInRes, f);
    retcode += read_int32(&entry->dwImageOffset, f);

    return retcode;
}


int
writeIconHeader(IconHeader *hdr, FILE *f)
{
    int retcode = 0;

    retcode += write_int16(&hdr->wReserved, f);
    retcode += write_int16(&hdr->wType, f);
    retcode += write_int16(&hdr->wCount, f);

    return retcode;   /* 6 */
}


int
readIconHeader(IconHeader *hdr, FILE *f)
{
    int retcode = 0;

    retcode += read_int16(&hdr->wReserved, f);
    retcode += read_int16(&hdr->wType, f);
    retcode += read_int16(&hdr->wCount, f);

    return retcode;
}

int
writeResourceDirectory(IconResourceDirectory *rdir, FILE *f)
{
    register int retcode = 0;

    retcode += write_int8(&rdir->bWidth, f);
    retcode += write_int8(&rdir->bHeight, f);
    retcode += write_int8(&rdir->bColorCount, f);
    retcode += write_int8(&rdir->bReserved, f);
    retcode += write_int16(&rdir->wPlanes, f);
    retcode += write_int16(&rdir->wBitCount, f);
    retcode += write_int32(&rdir->lBytesInRes, f);
    retcode += write_int16(&rdir->wNameOrdinal, f);
    
    return retcode;
}


int
readResourceDirectory(IconResourceDirectory *rdir, FILE *f)
{
    register int retcode = 0;

    retcode += read_int8(&rdir->bWidth, f);
    retcode += read_int8(&rdir->bHeight, f);
    retcode += read_int8(&rdir->bColorCount, f);
    retcode += read_int8(&rdir->bReserved, f);
    retcode += read_int16(&rdir->wPlanes, f);
    retcode += read_int16(&rdir->wBitCount, f);
    retcode += read_int32(&rdir->lBytesInRes, f);
    retcode += read_int16(&rdir->wNameOrdinal, f);
    /* retcode += read_int16(&rdir->padding, f); */
    
    return retcode;
}


int
writeCURSORDIRENTRY(CURSORDIRENTRY *cdir, FILE *f)
{
    register int retcode = 0;

    retcode += write_int8(&cdir->bWidth, f);
    retcode += write_int8(&cdir->bHeight, f);
    retcode += write_int8(&cdir->bColorCount, f);   
    retcode += write_int8(&cdir->bReserved, f);
    retcode += write_int16(&cdir->wXHotspot, f);
    retcode += write_int16(&cdir->wYHotspot, f);
    retcode += write_int32(&cdir->lBytesInRes, f);
    retcode += write_int32(&cdir->dwImageOffset, f);

    return retcode;
}


int
readCURSORDIRENTRY(CURSORDIRENTRY *cdir, FILE *f)
{
    register int retcode = 0;

    retcode += read_int8(&cdir->bWidth, f);
    retcode += read_int8(&cdir->bHeight, f);
    retcode += read_int8(&cdir->bColorCount, f);   
    retcode += read_int8(&cdir->bReserved, f);
    retcode += read_int16(&cdir->wXHotspot, f);
    retcode += read_int16(&cdir->wYHotspot, f);
    retcode += read_int32(&cdir->lBytesInRes, f);
    retcode += read_int32(&cdir->dwImageOffset, f);

    return retcode;
}


int
writeCursorComponent(CursorComponent *hsp, FILE *f)
{
    register int retcode = 0;

    retcode += write_int16(&hsp->xHotspot, f);
    retcode += write_int16(&hsp->yHotspot, f);

    return retcode;
}


int
readCursorComponent(CursorComponent *hsp, FILE *f)
{
    register int retcode = 0;

    retcode += read_int16(&hsp->xHotspot, f);
    retcode += read_int16(&hsp->yHotspot, f);

    return retcode;
}


int
writeCursorResourceDirectory(CursorResourceDirectory *crd, FILE *f)
{
    register int retcode = 0;

    retcode += write_int16(&crd->wWidth, f);
    retcode += write_int16(&crd->wHeight, f);
    retcode += write_int16(&crd->wPlanes, f);
    retcode += write_int16(&crd->wBitCount, f);
    retcode += write_int32(&crd->lBytesInRes, f);
    retcode += write_int16(&crd->wNameOrdinal, f);

    return retcode; /* 12 */
}


int
readCursorResourceDirectory(CursorResourceDirectory *crd, FILE *f)
{
    register int retcode = 0;

    retcode += read_int16(&crd->wWidth, f);
    retcode += read_int16(&crd->wHeight, f);
    retcode += read_int16(&crd->wPlanes, f);
    retcode += read_int16(&crd->wBitCount, f);
    retcode += read_int32(&crd->lBytesInRes, f);
    retcode += read_int16(&crd->wNameOrdinal, f);

    return retcode;
}


int
writeDLGITEMTEMPLATE(DLGITEMTEMPLATE *ctl, FILE *f)
{
    register int retcode = 0;

    retcode += write_int32(&ctl->style, f);
    retcode += write_int32(&ctl->dwExtendedStyle, f);
    retcode += write_int16(&ctl->x, f);
    retcode += write_int16(&ctl->y, f);
    retcode += write_int16(&ctl->cx, f);
    retcode += write_int16(&ctl->cy, f);
    retcode += write_int16(&ctl->id, f);

    return retcode;
}


int
writeDLGTEMPLATE(DLGTEMPLATE *dlg, FILE *f)
{
    register int retcode = 0;
    
    retcode += write_int32(&dlg->style, f);
    retcode += write_int32(&dlg->dwExtendedStyle, f);
    retcode += write_int16(&dlg->cdit, f);
    retcode += write_int16(&dlg->x, f);
    retcode += write_int16(&dlg->y, f);
    retcode += write_int16(&dlg->cx, f);
    retcode += write_int16(&dlg->cy, f);

    return retcode;
}


int
readDLGTEMPLATE(DLGTEMPLATE *dlg, FILE *f)
{
    register int retcode = 0;
    
    retcode += read_int32(&dlg->style, f);
    retcode += read_int32(&dlg->dwExtendedStyle, f);
    retcode += read_int16(&dlg->cdit, f);
    retcode += read_int16(&dlg->x, f);
    retcode += read_int16(&dlg->y, f);
    retcode += read_int16(&dlg->cx, f);
    retcode += read_int16(&dlg->cy, f);

    return retcode;
}


int
writeDLGFONT(DLGFONT *fnt, FILE *f)
{
    register int retcode = 0;

    retcode += write_int16(&fnt->PointSize, f);
    retcode += writeNameOrId(fnt->TypefaceName, f);

    return retcode;
}


int
readDLGFONT(DLGFONT *fnt, FILE *f)
{
    register int retcode = 0;

    retcode += read_int16(&fnt->PointSize, f);
    retcode += readNameOrId(fnt->TypefaceName, f);

    return retcode;
}


int
writeMenuHeader(MenuHeader *mh, FILE *f)
{
    register int retcode = 0;

    retcode += write_int16(&mh->wVersion, f);
    retcode += write_int16(&mh->cbHeaderSize, f);

    return retcode;
}


int
readMenuHeader(MenuHeader *mh, FILE *f)
{
    register int retcode = 0;

    retcode += read_int16(&mh->wVersion, f);
    retcode += read_int16(&mh->cbHeaderSize, f);

    return retcode;
}


int
writeaccel_entry(ACCELTABLEENTRY*ae, FILE *f)
{
    register int retcode = 0;
    
    retcode += write_int16(&ae->fFlags, f);
    retcode += write_int16(&ae->wAscii, f);
    retcode += write_int16(&ae->wId, f);
    retcode += write_int16(&ae->padding, f);

    return retcode;
}


int
readaccel_entry(ACCELTABLEENTRY*ae, FILE *f)
{
    register int retcode = 0;
    
    retcode += read_int16(&ae->fFlags, f);
    retcode += read_int16(&ae->wAscii, f);
    retcode += read_int16(&ae->wId, f);
    retcode += read_int16(&ae->padding, f);

    return retcode;
}

int
writeVersionEntry(version_entry *vs, FILE *f)
{
	register int retcode = 0;
	int padding;
	int size;

	retcode += write_int16(&vs->wLength, f);
	retcode += write_int16(&vs->wValueLength, f);
	retcode += write_int16(&vs->wType, f);
	if (vs->szKey)
		    retcode += writeNameOrId(vs->szKey, f);

	if (vs->lpValue){
		padding = PADDING(retcode, 4);
		if (writePadding(padding, f))
			retcode += padding;

		size = vs->wValueLength * (vs->wType ? sizeof(wchar_t) : 1);
		retcode += fwrite(vs->lpValue, 1, size, f);
	}

	return retcode;
}
