
/*
 *  SAVE.C
 */

#include "defs.h"

Prototype void SaveProject(char *);
Prototype void SaveRegion(FILE *, TplRegion *);
Prototype void SaveName(FILE *, char *);
Prototype void SaveLong(FILE *, uword, long);
Prototype void SaveLongNZ(FILE *, uword, long);
Prototype void SaveBox(FILE *, uword, Box *);
Prototype void SavePush(FILE *, uword);
Prototype void SavePop(FILE *);

void
SaveProject(name)
char *name;
{
    FILE *fo;
    TplRegion *rg;

    fo = fopen(name, "w");
    SavePush(fo, PT_PROJECT);

    SavePush(fo, PT_HEADER);
    fwrite(&Ph, sizeof(Ph), 1, fo);
    SavePop(fo);

    for (rg = GetHead(&RegList); rg; rg = GetSucc(&rg->rg_Node)) {
	SaveRegion(fo, rg);
    }

    SavePop(fo);
    fclose(fo);
}

void
SaveRegion(fo, rg)
FILE *fo;
TplRegion *rg;
{
    SavePush(fo, PT_REGION);

    SaveName(fo, rg->rg_Node.ln_Name);
    SaveBox(fo, PT_BOX,     &rg->rg_Box);
    SaveBox(fo, PT_MINMAX,  &rg->rg_MinMax);
    SaveLongNZ(fo, PT_MAXBUFLEN, rg->rg_MaxBufLen);
    SaveLongNZ(fo, PT_ID, rg->rg_Id);
    SaveLongNZ(fo, PT_REGLL,  RegionToId(rg->rg_LinkLeft));
    SaveLongNZ(fo, PT_REGLR,  RegionToId(rg->rg_LinkRight));
    SaveLongNZ(fo, PT_REGLU,  RegionToId(rg->rg_LinkUp));
    SaveLongNZ(fo, PT_REGLD,  RegionToId(rg->rg_LinkDown));
    SaveLongNZ(fo, PT_LOCKTO, RegionToId(rg->rg_LockedTo));
    SaveLongNZ(fo, PT_FLAGS,  rg->rg_Flags);
    SaveLong(fo, PT_TYPE,   rg->rg_Type);
    SaveLongNZ(fo, PT_EXCLID, rg->rg_ExclGroup);

    if (rg->rg_DataBase) {
	SavePush(fo, PT_DATABASE);
	SaveName(fo, rg->rg_DataBase);
	SavePop(fo);
    }
    if (rg->rg_ListRef) {
	SavePush(fo, PT_LISTREF);
	SaveName(fo, rg->rg_ListRef);
	SavePop(fo);
    }
    if (GetHead(&rg->rg_ListSet)) {
	MaxNode *node;

	SavePush(fo, PT_LISTSET);
	for (node = GetHead(&rg->rg_ListSet); node; node = GetSucc(node))
	    SaveName(fo, node->ln_Name);
	SavePop(fo);
    }
    if (rg->rg_DefText) {
	SavePush(fo, PT_DEFTEXT);
	SaveName(fo, rg->rg_DefText);
	SavePop(fo);
    }
    if (rg->rg_LabText) {
	SavePush(fo, PT_LABTEXT);
	SaveName(fo, rg->rg_LabText);
	SavePop(fo);
    }
    if (rg->rg_TextAttr.ta_Name) {
	SavePush(fo, PT_TEXTATTR);
	SaveName(fo, rg->rg_TextAttr.ta_Name);
	SaveLong(fo, PT_YSIZE, rg->rg_TextAttr.ta_YSize);
	SavePop(fo);
    }
    SavePop(fo);
}

void
SaveName(fo, name)
FILE *fo;
char *name;
{
    SavePush(fo, PT_NAME);
    fwrite(name, strlen(name) + 1, 1, fo);
    SavePop(fo);
}

void
SaveLong(fo, pt, val)
FILE *fo;
uword pt;
long val;
{
    SavePush(fo, pt);
    fwrite(&val, 4, 1, fo);
    SavePop(fo);
}

void
SaveLongNZ(fo, pt, val)
FILE *fo;
uword pt;
long val;
{
    if (val) {
	SavePush(fo, pt);
	fwrite(&val, 4, 1, fo);
	SavePop(fo);
    }
}


void
SaveBox(fo, pt, box)
FILE *fo;
uword pt;
Box *box;
{
    SavePush(fo, pt);
    fwrite(box, sizeof(Box), 1, fo);
    SavePop(fo);
}

void
SavePush(fo, pt)
FILE *fo;
uword pt;
{
    PPNode *pp = malloc(sizeof(PPNode));
    long z = 0;

    pp->pp_Pos = ftell(fo);
    AddTail(&PPList, (MaxNode *)pp);
    fwrite(&pt, sizeof(pt), 1, fo);
    fwrite(&z, 4, 1, fo);
}

void
SavePop(fo)
FILE *fo;
{
    PPNode *pp;
    long len;

    if (ftell(fo) & 1)
	putc(0, fo);
    if (pp = RemTail(&PPList)) {
	len = ftell(fo) - (pp->pp_Pos + sizeof(ProjEntry));
	fseek(fo, pp->pp_Pos + 2, 0);
	fwrite(&len, 4, 1, fo);
	fseek(fo, 0L, 2);
    } else {
	puts("Bad pop");
    }
}





