/* Charedit.c - Phase II of the Dungeon Master's familiar project

   Character Editing Module of Dungeon Master's Familiar

   James Gary
   2-25-88

   3-4-88  Fixed for use with combat module JeG
   3-11-88 Added Arps File Requestor JeG
   3-12-88 Added Open/Close gadgets (duh!) JeG
   3-14-88 Added AutoSelection of String Gadgets JeG
   7-1-88  Added Saving Throws
   7-1-88  Hit Dice now changes level gadget
   7-10-88 Fixed memory leak by calling MxCloseWindow()
   7-13-88 Added extra file list gadget for pasting from
           external files
*/

/* INCLUDES ********************************************************** */

#include <stdio.h>
#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>
#include "mxgadget.h"
#include "charedit.h"
#include "character.h"
#include <libraries/arpbase.h>	/* Standard ARP header file */
#include <proto/arpfunctions.h>	/* Predeclared functions */
#include <libraries/itools1l.h>

int ClericSave[7][5] = {
     {10,13,14,16,15},
     { 9,12,13,15,14},
     { 7,10,11,13,12},
     { 6, 9,10,12,11},
     { 5, 8, 9,11,10},
     { 4, 7, 8,10, 9},
     { 2, 5, 6, 8, 7}};

int FighterSave[10][5] = {
     {16,17,18,20,19},
     {14,15,16,17,17},
     {13,14,15,16,16},
     {11,12,13,13,14},
     {10,11,12,12,13},
     { 8, 9,10, 9,11},
     { 7, 8, 9, 8,10},
     { 5, 6, 7, 5, 8},
     { 4, 5, 6, 4, 7},
     { 3, 4, 5, 4, 6}};

MagicSave[5][5] = {
     {14,13,11,15,12},
     {13,11, 9,13,10},
     {11, 9, 7,11, 8},
     {10, 7, 5, 9, 6},
     { 8, 5, 3, 7, 4}};

ThiefSave[6][5] = {
     {13,12,14,16,15},
     {12,11,12,15,13},
     {11,10,10,14,11},
     {10, 9, 8,13, 9},
     { 9, 8, 8,13, 9},
     { 8, 7, 4,11, 5}};

struct CharListItem {   /* structure for list display */
     struct CharListItem *link;
     struct Character *character;
     short index;
     } CharList[MAXCHARS];
struct Character PatchChars[MAXCHARS]; /* Holds extra file data */
struct Character *PasteChar; /* Selected extra character for pasting */

static USHORT quit_flag; /*For PW event handler*/
static struct Window *wG; /*Main Combat window */
struct Character characters[MAXCHARS]; /*Character array*/
USHORT CurChar = 0; /*Holds postition in characters[]*/

/*Arp file requestor stuff*/

#define MAXPATH		( (FCHARS * 10) + DSIZE + 1)	/* Size of a pathname */

BYTE Filename[FCHARS + 1];
BYTE Directory[MAXPATH];

struct FileRequester FR = {
	"Select a character file",	/* Hailing text */
	Filename,			/* filename array */
	Directory,			/* directory array */
	NULL,		/* Window, NULL == workbench */
	NULL,		/* Flags, not used in this release */
	NULL,		/* Function pointers, not used in this release */
	NULL,		/*  "" */
};

/*Read a new character file from main combat window using ARP File req.*/
ReadCharFile()
{
    FILE *charfile;
    char *Selection;

    if ( Selection = FileRequest(&FR))
	if (*Selection) {
            if ((charfile = fopen(Filename,"r")) != NULL)
                 fread((char *)characters,sizeof(struct Character),MAXCHARS,charfile);
            else {
               printf("File not found\n");
               InitChars();
            }
       }
    fclose(charfile);
    PrintChars();
    return(0);
}

/*Write characters to file from main combat window using ARP File req.*/
WriteCharFile()
{
    FILE *charfile;
    char *Selection;

    if ( Selection = FileRequest(&FR))
        if (*Selection) {
            if ((charfile = fopen(Filename,"w")) != NULL)
                fwrite((char *)characters,sizeof(struct Character),MAXCHARS,charfile);
            else
                printf("Panic! Could not open output file\n");
        }
    fclose(charfile);
    return(0);
}

/*Read character file from edit window using ARP file req.
  and activate name gadget of current character for editing*/
ReadEditFile()
{
    FILE *charfile;
    char *Selection;

    if ( Selection = FileRequest(&FR))
	if (*Selection) {
            if ((charfile = fopen(Filename,"r")) != NULL)
                 fread((char *)characters,sizeof(struct Character),MAXCHARS,charfile);
            else {
               printf("File not found\n");
               InitChars();
            }
       }
    fclose(charfile);
    PrintChars();
    SetGads();
    ActivateGadget(&Name,wG,NULL);
    return(0);
}

/*Write current characters to file using ARP File req. Called from
  edit window.*/
WriteEditFile()
{
    FILE *charfile;
    char *Selection;

    if ( Selection = FileRequest(&FR))
        if (*Selection) {
            if ((charfile = fopen(Filename,"w")) != NULL)
                fwrite((char *)characters,sizeof(struct Character),MAXCHARS,charfile);
            else
                printf("Panic! Could not open output file\n");
        }
    fclose(charfile);
    return(0);
}

/* Initialize singly linked list for extra file display */
InitList()
{
     short i;

     for (i=0; i < MAXCHARS-1; i++) {
           CharList[i].link = &CharList[i+1];
           CharList[i].character = &PatchChars[i];
           CharList[i].index = i;
           }
     CharList[MAXCHARS-1].link = NULL;
     CharList[MAXCHARS-1].character = &PatchChars[MAXCHARS-1];
     CharList[MAXCHARS-1].index = MAXCHARS-1;
}

/* Hilight selected character from extra file display list */
void updatelistitem(rp,item,x,y,hi)
struct RastPort *rp;
struct CharListItem *item;
long x,y,hi;
{
   static struct IntuiText it = {0,0,JAM2,0,0,0,0,0};

   if (hi) {
      it.FrontPen = 0;
      it.BackPen = 1;
      }
   else {
      it.FrontPen = 1;
      it.BackPen = 0;
      }
   it.IText = PatchChars[item->index].Name;
   PrintIText(rp,&it,x,y);
}

static struct ListInfo windowlist = {
   445,122,123,50,8,
   50,51,52,53,
   1,0,
   0,0,0,
   0,
   0,0,0,0,
   updatelistitem,
   0,0,0,0,
};

/* Read in extra file and display in Inovatools1 list */
ReadPatchFile()
{
    FILE *charfile;
    char *Selection;

    if ( Selection = FileRequest(&FR))
	if (*Selection) 
            if ((charfile = fopen(Filename,"r")) != NULL)
                 fread((char *)PatchChars,sizeof(struct Character),MAXCHARS,charfile);
            else 
               printf("File not found\n");
    fclose(charfile);
    windowlist.TopItem = &CharList[0];
    windowlist.TopDisplayItem = &CharList[0];
    DrawList(&windowlist);
    return(0);
}

/* Copy extra file character to current character and redisplay gadgets */      
Paste(gad)
struct Gadget *gad;
{
     characters[CurChar] = *PasteChar;
     SetGads();
     ActivateGadget(&Name,wG,NULL);
}

/* NextChar() - advance to next character in edit list. Wrap around if
   at end of list. */
NextChar()
{
        if (CurChar < MAXCHARS-1)
                CurChar++;
	else
		CurChar = 0;
        SetGads(); /*Reset Gadgets to new character*/
	ActivateGadget(&Name,wG,NULL); /*Activate first string gadget*/
	return(0);
}

/* PrevChar() - move to previous character in edit list. Wrap around if
   at beginning of list. */
PrevChar()
{
        if (CurChar > 0)
                CurChar--;
	else
		CurChar = MAXCHARS-1;
        SetGads(); /*Reset gadgets to new character*/
	ActivateGadget(&Name,wG,NULL); /*Activate first string gadget*/
	return(0);
}

/* Initialize character array*/
InitChars()
{
        USHORT i;

        for (i=0;i<MAXCHARS;i++) {
                sprintf(characters[i].Name,"Character %d",i);
                characters[i].AC = 10;
                characters[i].Level = 1;
                characters[i].Size = SMALL;
                characters[i].Job = FIGHTER;
                characters[i].LgHitPlus = 0;
                characters[i].SmHitPlus = 0;
                characters[i].LgDamPlus = 0;
                characters[i].SmDamPlus = 0;
                characters[i].LgTypeDie = 6;
                characters[i].LgNumDie = 1;
                characters[i].SmTypeDie = 6;
                characters[i].SmNumDie = 1;
                SetSave(i);
        }
	return(0);
}

/* Set up an integer gadget. For Intuition
   to recognize changes, gadget must first be removed from list. */
SetIntGad(gad,setting)
struct Gadget *gad; /* Which gadget to set up*/
long int setting; /* Value to place into gadget*/
{
        USHORT i;
        struct StringInfo *sinfo;

        i = RemoveGadget(wG,gad);
        if (i >= 0) {
                sinfo = (struct StringInfo *)gad->SpecialInfo;
                sinfo->LongInt = setting; /* Integer value*/
                sprintf(sinfo->Buffer,"%d",sinfo->LongInt); /* Put text version*/
                AddGadget(wG,gad,i); /*Back in windows gadget list*/
        }
        else
                printf("Panic -- gadget not in list!!\n");
	return(0);
}

/* Set up a boolean gadget. For Intuition to recognize changes, gadget
   must first be removed from list.*/
SetBoolGad(gad,setting,constant)
struct Gadget *gad; /* Which gadget to set up*/
int setting,constant; /* Since the gadgets are mutually exclusive need
                      variable setting and setting of gadget. If gadget
                      corresponds to the variable, then select the gadget.*/
{
        USHORT i;

        i = RemoveGadget(wG,gad);
        if (i >= 0) {
                if (setting == constant)
                /*      gad->Flags |= SELECTED;*/
                        SelectGadget(gad,wG,NULL);
                else
                /*      gad->Flags &= ~SELECTED;*/
                        UnSelectGadget(gad,wG,NULL);
                AddGadget(wG,gad,i);
        }
	return(0);
}

/* Set up gadgets for current character */
SetGads()
{
        USHORT i;

        i = RemoveGadget(wG,&Name);
        if (i >= 0) {
                strcpy(NameSIBuff,characters[CurChar].Name);
                AddGadget(wG,&Name,i);
        }
        SetIntGad(&ArmorClass,characters[CurChar].AC);
        SetBoolGad(&Fighter,characters[CurChar].Job,FIGHTER);
        SetBoolGad(&Cleric,characters[CurChar].Job,CLERIC);
        SetBoolGad(&Thief,characters[CurChar].Job,THIEF);
        SetBoolGad(&MagicUser,characters[CurChar].Job,MAGICUSER);
        SetBoolGad(&Monster,characters[CurChar].Job,MONSTER);
        SetBoolGad(&Small,characters[CurChar].Size,SMALL);
        SetBoolGad(&Large,characters[CurChar].Size,LARGE);
        SetIntGad(&Level,characters[CurChar].Level);
        SetIntGad(&SmHitPlus,characters[CurChar].SmHitPlus);
        SetIntGad(&SmNumDie,characters[CurChar].SmNumDie);
        SetIntGad(&SmDamPlus,characters[CurChar].SmDamPlus);
        SetIntGad(&SmSizeDie,characters[CurChar].SmTypeDie);
        SetIntGad(&LgHitPlus,characters[CurChar].LgHitPlus);
        SetIntGad(&LgDamPlus,characters[CurChar].LgDamPlus);
        SetIntGad(&LgNumDie,characters[CurChar].LgNumDie);
        SetIntGad(&LgSizeDie,characters[CurChar].LgTypeDie);
        SetBoolGad(&ML1,characters[CurChar].Level,ML1.GadgetID);
        SetBoolGad(&ML2,characters[CurChar].Level,ML2.GadgetID);
        SetBoolGad(&ML3,characters[CurChar].Level,ML3.GadgetID);
        SetBoolGad(&ML4,characters[CurChar].Level,ML4.GadgetID);
        SetBoolGad(&ML5,characters[CurChar].Level,ML5.GadgetID);
        SetBoolGad(&ML6,characters[CurChar].Level,ML6.GadgetID);
        SetBoolGad(&ML7,characters[CurChar].Level,ML7.GadgetID);
        SetBoolGad(&ML8,characters[CurChar].Level,ML8.GadgetID);
        SetBoolGad(&ML9,characters[CurChar].Level,ML9.GadgetID);
        SetBoolGad(&ML10,characters[CurChar].Level,ML10.GadgetID);
        SetBoolGad(&ML11,characters[CurChar].Level,ML11.GadgetID);
        SetBoolGad(&ML12,characters[CurChar].Level,ML12.GadgetID);
        SetIntGad(&ParSave,characters[CurChar].Saves[PAR]);
        SetIntGad(&PetSave,characters[CurChar].Saves[PET]);
        SetIntGad(&RodSave,characters[CurChar].Saves[ROD]);
        SetIntGad(&BreathSave,characters[CurChar].Saves[BREATH]);
        SetIntGad(&SpellSave,characters[CurChar].Saves[SPELL]);
        RefreshGadgets(&Name,wG,NULL); /* Redraw them!*/
	return(0);
}

/* For PW event handler */
static quit(object)
APTR object;
{
        quit_flag = TRUE;
	return(0);
}


struct Window *OpenWindow();

/* User selected Paralyzation save, so update character array*/
Par(gad)
struct Gadget *gad;
{
     struct StringInfo *sinfo;
     
     sinfo = (struct StringInfo *)gad->SpecialInfo;
     characters[CurChar].Saves[PAR] = sinfo->LongInt;
     ActivateGadget(&PetSave,wG,NULL); /*Advance to next string gadget*/
     return(0);
}    

/* User selected Petrification save, so update character array*/
Pet(gad)
struct Gadget *gad;
{
     struct StringInfo *sinfo;

     sinfo = (struct StringInfo *)gad->SpecialInfo;
     characters[CurChar].Saves[PET] = sinfo->LongInt;
     ActivateGadget(&RodSave,wG,NULL); /*Advance to next string gadget*/
     return(0);
}

/* User selected Rod save, so update character array*/
Rod(gad)
struct Gadget *gad;
{
     struct StringInfo *sinfo;

     sinfo = (struct StringInfo *)gad->SpecialInfo;
     characters[CurChar].Saves[ROD] = sinfo->LongInt;
     ActivateGadget(&BreathSave,wG,NULL); /*Advance to next string gadget*/
     return(0);
}

/* User selected Breath save, so update character array*/
Breath(gad)
struct Gadget *gad;
{
     struct StringInfo *sinfo;
 
     sinfo = (struct StringInfo *)gad->SpecialInfo;
     characters[CurChar].Saves[BREATH] = sinfo->LongInt;
     ActivateGadget(&SpellSave,wG,NULL); /*Advance to next string gadget*/
     return(0);
}

/* User selected Spell save, so update character array*/
Spell(gad)
struct Gadget *gad;
{
     struct StringInfo *sinfo;
   
     sinfo = (struct StringInfo *)gad->SpecialInfo;
     characters[CurChar].Saves[SPELL] = sinfo->LongInt;
     NextChar(); /*Last gadget, advance to next charcter*/
     return(0);
}

/* User selected name gadget, so update character array*/
AddName(gad)
struct Gadget  *gad;
{
        struct StringInfo *sinfo;

        sinfo = (struct StringInfo *)gad->SpecialInfo;
        strcpy(characters[CurChar].Name,sinfo->Buffer);
	ActivateGadget(&Level,wG,NULL); /*Advance to next string gadget*/
	return(0);
}

/* User selected AC gadget, so update character array*/
AddAC(gad)
struct Gadget  *gad;
{
        struct StringInfo *sinfo;

        sinfo = (struct StringInfo *)gad->SpecialInfo;
        characters[CurChar].AC = sinfo->LongInt;
	ActivateGadget(&SmHitPlus,wG,NULL); /* Advance to next string gadget*/	
	return(0);
}

/* User changed class of character, so update character array*/
SelectJob(gad)
struct Gadget  *gad;
{
        characters[CurChar].Job = gad->GadgetID;
	SetSave(CurChar); /* Job affects saving throws */
        SetSaveGads(CurChar);
        return(0);
}

/* User changed size of character, so update character array*/
ReSize(gad)
struct Gadget  *gad;
{
        characters[CurChar].Size = gad->GadgetID;
	return(0);
}

/* User changed level of character, so update character array*/
ChangeLevel(gad)
struct Gadget  *gad;
{
        struct StringInfo *sinfo;

        sinfo = (struct StringInfo *)gad->SpecialInfo;
        characters[CurChar].Level = sinfo->LongInt;
	ActivateGadget(&ArmorClass,wG,NULL); /*Advance to next string gadget*/
	SetSave(CurChar); /* Job affects saving throws*/
        SetSaveGads(CurChar);
        return(0);
}

/* User changed to hit small, update character array*/
SmHit(gad)
struct Gadget  *gad;
{
        struct StringInfo *sinfo;

        sinfo = (struct StringInfo *)gad->SpecialInfo;
        characters[CurChar].SmHitPlus = sinfo->LongInt;
	ActivateGadget(&SmNumDie,wG,NULL); /*Advance to next string gadget*/
	return(0);
}

/* User changed hit dice, update character array*/
HitDice(gad)
struct Gadget *gad;
{
        struct StringInfo *sinfo;
 
        sinfo = (struct StringInfo *)gad->SpecialInfo;
        characters[CurChar].Level = gad->GadgetID; /*Change level gadget*/
        SetIntGad(&Level,characters[CurChar].Level);
        SetSave(CurChar); /*Hit dice affects save*/
        SetSaveGads(CurChar);
           
	return(0);
}

/* User changed number of dice vs. small, update character array*/
SmNum(gad)
struct Gadget  *gad;
{
        struct StringInfo *sinfo;

        sinfo = (struct StringInfo *)gad->SpecialInfo;
        characters[CurChar].SmNumDie = sinfo->LongInt;
	ActivateGadget(&SmDamPlus,wG,NULL);/*Advance to next string gadget*/
	return(0);
}

/* User changed damage plus vs. small, update character array*/
SmDam(gad)
struct Gadget  *gad;
{
        struct StringInfo *sinfo;

        sinfo = (struct StringInfo *)gad->SpecialInfo;
        characters[CurChar].SmDamPlus = sinfo->LongInt;
	ActivateGadget(&SmSizeDie,wG,NULL);/*Advance to next string gadget*/
	return(0);
}

/* User changed type of die vs. small, update character array*/
SmSize(gad)
struct Gadget  *gad;
{
        struct StringInfo *sinfo;

        sinfo = (struct StringInfo *)gad->SpecialInfo;
        characters[CurChar].SmTypeDie = sinfo->LongInt;
	ActivateGadget(&LgHitPlus,wG,NULL);/*Advance to next string gadget*/
	return(0);
}

/* User changed hit bonus vs. large, update character array*/
LgHit(gad)
struct Gadget  *gad;
{
        struct StringInfo *sinfo;

        sinfo = (struct StringInfo *)gad->SpecialInfo;
        characters[CurChar].LgHitPlus = sinfo->LongInt;
	ActivateGadget(&LgNumDie,wG,NULL);/*Advance to next string gadget*/
	return(0);
}

/* User changed damage bonus vs. large, update character array*/
LgDam(gad)
struct Gadget  *gad;
{
        struct StringInfo *sinfo;

        sinfo = (struct StringInfo *)gad->SpecialInfo;
        characters[CurChar].LgDamPlus = sinfo->LongInt;
	ActivateGadget(&LgSizeDie,wG,NULL);/*Advance to next string gadget*/
	return(0);
}

/* User changed num. of dice vs. large, update character array*/
LgNum(gad)
struct Gadget  *gad;
{
        struct StringInfo *sinfo;

        sinfo = (struct StringInfo *)gad->SpecialInfo;
        characters[CurChar].LgNumDie = sinfo->LongInt;
	ActivateGadget(&LgDamPlus,wG,NULL);/*Advance to next string gadget*/
	return(0);
}

/* User changed size of die vs. large, update character array*/
LgSize(gad)
struct Gadget  *gad;
{
        struct StringInfo *sinfo;

        sinfo = (struct StringInfo *)gad->SpecialInfo;
        characters[CurChar].LgTypeDie = sinfo->LongInt;
	ActivateGadget(&ParSave,wG,NULL); /*Advance to next string gadget*/
	return(0);
}

/* End editing session */
QuitEdit(gad)
struct Gadget  *gad;
{
	PrintChars(); /* Print characters on combat window*/
        quit(gad);
	return(0);
}

/* Determine row of save table for fighter */
FighterSaveRow(level)
int level;
{
     int row;
   
     if (level <1 )
         row = 0;
     else if (level > 16)
         row = 9;
     else
         row = ((level+1)/2);
     return(row);
}

/* Determine row of save table for cleric */
ClericSaveRow(level)
int level;
{
     int row;
 
     if (level > 18)
          row = 6;
     else if (level < 1)
          row = 0;
     else
          row = ((level-1)/3);
     return(row);
}

/* Determine row of save table for Magic users */
MagicSaveRow(level)
int level;
{
     int row;

     if (level < 1)
          row = 0;
     else if (level > 20)
          row = 4;
     else
          row = ((level-1)/5);
     return(row);
}

/*Determine row of save table for thief */
ThiefSaveRow(level)
int level;
{
     int row;
    
     if (level < 1)
          row = 0;
     else if (level > 20)
          row = 5;
     else
          row = ((level-1)/4);
     return(row);
}

/* Determine row of save table for monster */
/* Note that this is an approximation. See Dungeon Master's 
Guide to make neccesary adjustments */
MonsterSaveRow(level)
int level;
{
     int row;

     if (level < 2)
          row = 0;
     else if (level < 5)
          row = 1;
     else if (level > 12)
          row = 9;
     else 
          row = (level-3);
     return(row);
}

              

/* User selected new level/hd or job, so modify saves */
SetSave(Char)
int Char;
{
     int save,row,level;

     level = characters[Char].Level;
     switch(characters[Char].Job) {
          case FIGHTER : { 
                           row = FighterSaveRow(level);
                           save = FighterSave[row][PAR];
                           characters[Char].Saves[PAR] = save;
                           save = FighterSave[row][PET];
                           characters[Char].Saves[PET] = save;
                           save = FighterSave[row][ROD];
                           characters[Char].Saves[ROD] = save;
                           save = FighterSave[row][BREATH];
                           characters[Char].Saves[BREATH] = save;
                           save = FighterSave[row][SPELL];
                           characters[Char].Saves[SPELL] = save;
                           break;
                         }
          case CLERIC :  { 
                           row = ClericSaveRow(level);
                           save = ClericSave[row][PAR];
                           characters[Char].Saves[PAR] = save;
                           save = ClericSave[row][PET];
                           characters[Char].Saves[PET] = save;
                           save = ClericSave[row][ROD];
                           characters[Char].Saves[ROD] = save;
                           save = ClericSave[row][BREATH];
                           characters[Char].Saves[BREATH] = save;
                           save = ClericSave[row][SPELL];
                           characters[Char].Saves[SPELL] = save;
                           break;
                         }
          case MAGICUSER :{
                           row = MagicSaveRow(level);
                           save = MagicSave[row][PAR];
                           characters[Char].Saves[PAR] = save;
                           save = MagicSave[row][PET];
                           characters[Char].Saves[PET] = save;
                           save = MagicSave[row][ROD];
                           characters[Char].Saves[ROD] = save;
                           save = MagicSave[row][BREATH];
                           characters[Char].Saves[BREATH] = save;
                           save = MagicSave[row][SPELL];
                           characters[Char].Saves[SPELL] = save;
                           break;
                         }
          case THIEF :   { 
                           row = ThiefSaveRow(level);
                           save = ThiefSave[row][PAR];
                           characters[Char].Saves[PAR] = save;
                           save = ThiefSave[row][PET];
                           characters[Char].Saves[PET] = save;
                           save = ThiefSave[row][ROD];
                           characters[Char].Saves[ROD] = save;
                           save = ThiefSave[row][BREATH];
                           characters[Char].Saves[BREATH] = save;
                           save = ThiefSave[row][SPELL];
                           characters[Char].Saves[SPELL] = save;
                           break;
                         }
          case MONSTER : { 
                           row = MonsterSaveRow(level);
                           save = FighterSave[row][PAR];
                           characters[Char].Saves[PAR] = save;
                           save = FighterSave[row][PET];
                           characters[Char].Saves[PET] = save;
                           save = FighterSave[row][ROD];
                           characters[Char].Saves[ROD] = save;
                           save = FighterSave[row][BREATH];
                           characters[Char].Saves[BREATH] = save;
                           save = FighterSave[row][SPELL];
                           characters[Char].Saves[SPELL] = save;
                           break;
                         }
     }
     return(0);
}

SetSaveGads(Char)
int Char;
{
     SetIntGad(&ParSave,characters[Char].Saves[PAR]);
     SetIntGad(&PetSave,characters[Char].Saves[PET]);
     SetIntGad(&RodSave,characters[Char].Saves[ROD]);
     SetIntGad(&BreathSave,characters[Char].Saves[BREATH]);
     SetIntGad(&SpellSave,characters[Char].Saves[SPELL]);
     RefreshGadgets(&Name,wG,NULL);
     return(0);
}
 
/* Main editing event handling and set up routine
   Note: this routine is adapted from the PW example program
   and contains unused remnants thereof. Sorry, but I am lazy.  */
Edit()
{
        UWORD code;
        ULONG class;
        struct Gadget *object;
	extern long IntuitionBase;
	extern long  GfxBase;
        struct CharListItem *litem;
        struct RastPort *rpG;
        struct IntuiMessage *message;   /* the message the IDCMP sends us */
        if (IntuitionBase == NULL)
            IntuitionBase = OpenLibrary("intuition.library", 0);
        if (IntuitionBase == NULL)
        {
                printf("intuition is not here.  where are we?\n");
                goto cleanup1;
        }
        if (GfxBase == NULL)
            GfxBase = OpenLibrary("graphics.library", 0);

        quit_flag = FALSE;
        wG = (struct Window *) MxOpenWindow(&NewWindowStructure1);
        if ( wG == NULL )
        {
                printf ("open window failed\n");
                goto cleanup1;
        }
        InitList();
        windowlist.Window = wG;
        InitListInfo(&windowlist);
	SetGads(); /* Set up initial display */
        rpG = wG->RPort;        /* get a rastport pointer for the window */

	DrawBorder(rpG,&BorderList1,0,0);
        PrintIText(rpG,&IntuiTextList1,0,0);   
	ActivateWindow(wG);
        do
        {
                WaitPort(wG->UserPort);
                        while( (message = (struct IntuiMessage *)
                                GetMsg(wG->UserPort) ) != NULL)
                        {
                                code = message->Code;  /* MENUNUM */
                                object = (struct Gadget *)message->IAddress;  /* Gadget */
                                class = message->Class;
                                ReplyMsg(message);
				if ( class == ACTIVEWINDOW) 
					ActivateGadget(&Name,wG,NULL);
                                if ( class == CLOSEWINDOW ) 
                                        QuitEdit(object);
                                if ( class == GADGETDOWN ){
                                   if (object->GadgetID == 51) { 
                                           litem = (struct CharListItem *)GetListItem(&windowlist);
                                           PasteChar = litem->character;
                                   }
                                   else if ((object->GadgetID == 52)||(object->GadgetID == 53)) 
                                           ClickList(&windowlist,object->GadgetID);
                                   }
                                if (class == GADGETUP) {
                                   if (object->GadgetID == 50)
                                      ScrollList(&windowlist);
                                else {
                                   HandleEditEvent(object);
                                   SelectGadget(object,wG,NULL);
                                }
                            }
                        }
        } while (quit_flag == FALSE);

cleanup3:

cleanup2:
        RemoveListInfo(&windowlist);
        MxCloseWindow(wG);

cleanup1:
        return(0);
}
