
/*
 * SAVE.C
 */

#include "defs.h"
#include <workbench/workbench.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 *);
Prototype struct WBStartup *_WBMsg;
Prototype void *IconBase;

/* IE ICON GENERATION */
/* Iff2Src conversion: DeluxePaintIII:Brush/tpledit.br3 */

const USHORT Image1Data[] = {
  0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x2000,
  0x0000, 0x0002, 0x2000, 0x03FF, 0xCFFE, 0x2000,
  0x0000, 0x0804, 0x2000, 0x0000, 0x0806, 0x2000,
  0x0000, 0x0802, 0x2000, 0x0000, 0x08F2, 0x2000,
  0x0000, 0x0882, 0x2000, 0x0000, 0x0882, 0x2000,
  0x0000, 0x0882, 0x2000, 0x0000, 0x0882, 0x2000,
  0x0000, 0x0882, 0x2000, 0x0000, 0x0882, 0x2000,
  0x0000, 0x0886, 0x2000, 0x0000, 0x08BC, 0x2000,
  0x0000, 0x0880, 0x2000, 0x0000, 0x0888, 0x0800,
  0x0000, 0x0888, 0x0800, 0x00FF, 0xF8BB, 0x3800,
  0x0080, 0x0080, 0x2000, 0x0080, 0x0088, 0x2000,
  0x0080, 0x0088, 0x2000, 0x0002, 0x3C88, 0x2000,
  0x0002, 0x2088, 0x2000, 0x00FE, 0x2088, 0x2000,
  0x0080, 0x2088, 0x2000, 0x0080, 0x2088, 0x2000,
  0x0080, 0x2088, 0x2000, 0x0602, 0x0888, 0x2000,
  0x0303, 0x8888, 0x2000, 0x01FE, 0xFBB8, 0xE000,
  0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400,
  0x0620, 0x0000, 0x7E00, 0x0FBC, 0xC673, 0x1800,
  0x1CA9, 0x7CD6, 0x9000, 0x2952, 0x24E4, 0x2000,
  0x1B9F, 0x67CC, 0xE400, 0x2619, 0xCC67, 0x3000,
  0x6000, 0x1800, 0x0000, 0xC000, 0x2800, 0x0000,
  0x8000, 0x5000, 0x0000, 0x0000, 0x6000, 0x0000,
  /* Plane 1 */
  0x07FF, 0xFFFF, 0xE000, 0x0400, 0x0001, 0x0000,
  0x0400, 0x0001, 0x0000, 0x0400, 0x0001, 0x0000,
  0x0000, 0x47FD, 0x0000, 0x0000, 0x4407, 0x0000,
  0x0000, 0x4401, 0x0000, 0x0000, 0x4401, 0x0000,
  0x0000, 0x4411, 0x0000, 0x0000, 0x4411, 0x0000,
  0x0000, 0x4411, 0x0000, 0x0000, 0x4411, 0x0000,
  0x0000, 0x4471, 0x0000, 0x0000, 0x4441, 0x0000,
  0x0000, 0x4441, 0x0000, 0x0000, 0x4441, 0x0000,
  0x01FF, 0xC47F, 0x1800, 0x0300, 0x0444, 0x0000,
  0x0600, 0x0444, 0x0000, 0x0400, 0x0444, 0x0000,
  0x0400, 0xFC79, 0x0000, 0x0401, 0x8041, 0x0000,
  0x047F, 0x0041, 0x0000, 0x0401, 0x0041, 0x0000,
  0x0401, 0x0441, 0x0000, 0x0401, 0x0441, 0x0000,
  0x0401, 0x0441, 0x0000, 0x0401, 0x0441, 0x0000,
  0x047F, 0x1C41, 0x0000, 0x0601, 0x0441, 0x0000,
  0x0301, 0x8441, 0x0000, 0x0100, 0x8441, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400,
  0x0620, 0x0000, 0x7E00, 0x0FBC, 0xC673, 0x1800,
  0x1CA9, 0x7CD6, 0x9000, 0x2952, 0x24E4, 0x2000,
  0x1B9F, 0x67CC, 0xE400, 0x2619, 0xCC67, 0x3000,
  0x6000, 0x1800, 0x0000, 0xC000, 0x2800, 0x0000,
  0x8000, 0x5000, 0x0000, 0x0000, 0x6000, 0x0000
};


const struct Image Image1 = {
  0,0,39,44,
  2,
  &Image1Data[0],
  0xff,
  0,
  NULL
};

const struct DiskObject Icon = {
  WB_DISKMAGIC,
  WB_DISKVERSION,
  /*  struct Gadget */
  NULL,
  0,0,39,44,
  GADGIMAGE | GADGHCOMP,
  RELVERIFY | GADGIMMEDIATE,
  BOOLGADGET,
  (APTR) &Image1,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  /*  do_Type */
  WBPROJECT,
  "TplEdit",
  NULL,
  NO_ICON_POSITION,
  NO_ICON_POSITION,
  NULL,
  NULL,
  8192
};

void *IconBase;

/***********************  SaveProject(name) **************************/
void
SaveProject(name)
  char  *name;
{
  if (_WBMsg)
  {
    if (IconBase = OpenLibrary("icon.library", 33))
    {
      struct DiskObject *d;

      if ((d = (struct Diskobject *)GetDiskObject(name)) != NULL)
        FreeDiskObject(d);
      else
        PutDiskObject(name, &Icon);

      Delay(10);

      CloseLibrary(IconBase);
    }
  }

  FILE  *fo;
  TplRegion *rg;

  if (fo = fopen(name, "r"))
  {
    fclose(fo);
    if (!(do_request( "Project \"%s\" already exists !",
                      "Replace it|Cancel", name)))
      return;
  }
  if ((fo = fopen(name, "w")) == NULL)
    return;


  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);
}

/***********************  SaveRegion(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_BufSpace);
  SaveLongNZ(fo, PT_ID,        rg->rg_Id);
  SaveLongNZ(fo, PT_REGLL,     (rg->rg_LinkLeft)  ? rg->rg_LinkLeft->rg_Id  : 0);
  SaveLongNZ(fo, PT_REGLR,     (rg->rg_LinkRight) ? rg->rg_LinkRight->rg_Id : 0);
  SaveLongNZ(fo, PT_REGLU,     (rg->rg_LinkUp)    ? rg->rg_LinkUp->rg_Id    : 0);
  SaveLongNZ(fo, PT_REGLD,     (rg->rg_LinkDown)  ? rg->rg_LinkDown->rg_Id  : 0);
  SaveLongNZ(fo, PT_LOCKTO,    (rg->rg_LockedTo)  ? rg->rg_LockedTo->rg_Id  : 0);
  SaveLongNZ(fo, PT_FLAGS,     rg->rg_Flags);
  SaveLong(fo,   PT_TYPE,      rg->rg_Type);
  SaveLongNZ(fo, PT_EXCLID,    rg->rg_ExclGroup);
  SaveLong(fo,   PT_SPECFLAGS, rg->rg_SpecFlags);
  SaveLongNZ(fo, PT_MAXVAL,    rg->rg_MaxVal);
  SaveLongNZ(fo, PT_DEFVAL,    rg->rg_DefVal);

  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);
}

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

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

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


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

/***********************  SavePush(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);
}

/***********************  SavePop(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");
}

