/****************************************************************/
/**                                                            **/
/**   Direct Communication Chat and Conferencing System        **/
/**   Created May 1993 out of complete boredom.                **/
/**   (c) 1993 Takoyaki Software Ltd.                          **/
/**                                                            **/
/**   Will only run in conjunction with Desqview/X.            **/
/**                                                            **/
/**   File:    CHATFILE.C                                      **/
/**   Purpose: Filing functions for writing/reading HOSTDATA   **/
/**   Usage:   Should be linked with chathost.                 **/
/**                                                            **/
/****************************************************************/


#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>

#include	"chatvars.h"



extern struct user *currentuser,*userlist;
extern struct emote *currentemote,*emotes;
extern struct staticuser *currentstatic,*staticlist;

extern struct item *additem(int);

extern struct items itemlist[];

extern struct flagdef *findflagdef(struct flagdef, char *);
extern int setrecord(struct item *, struct itemdef *, char *);
extern struct itemdef *findrecordtype(struct itemdef *,char *);
struct items *gettypedefbyname(char *);


char word[50];
char string[10240];


/*-------------------------------------------------------*/
/* get a word of text from a file                        */
/*-------------------------------------------------------*/

char *getword(FILE *fp)
	{
	char p,*s = word;

	do	{
		p = fgetc(fp);
		} while ((p == ' ' || p == '\n' || p == '\r' || p == '\t') && !feof(fp));

	do {
		*s++ = p;
		p = fgetc(fp);
		} while (p != ' ' && p != '\n' && p != '\r' && p != '\t' && (s-word) < sizeof(word) && !feof(fp));


	*s = '\0';

	return word;
	}

/*-------------------------------------------------------*/
/* get a string of text from a file                      */
/* the string is surrounded with STOPCHAR                */
/*-------------------------------------------------------*/

char *getstring(FILE *fp)
	{
	char p,*s = string;

	do	{
		p = fgetc(fp);
		} while ((p == ' ' || p == '\n' || p == '\r' || p == '\t' ) && p != STOPCHAR && !feof(fp));

	p = fgetc(fp);

	while (p != STOPCHAR && p != '\n' && p != '\r' && (s-string) < sizeof(string) && !feof(fp))
		{
		*s++ = p;
		p = fgetc(fp);
		};

	*s = '\0';

	while (p != STOPCHAR && p != '\n' && p != '\r' && !feof(fp))
		{
		p = fgetc(fp);
		}

	return string;
	}



        /****************************************************/
      /********************************************************/
    /************************************************************/
  /****************************************************************/
/********************************************************************/
/** New Loading and Saving data routines that are better automated **/
/********************************************************************/



/*-------------------------------------------------------*/
/* process the host's data file                          */
/*-------------------------------------------------------*/

processdata()
	{
	FILE *fp;
	char type[30],*s;
	struct itemdef *t;
	struct flagdef *fd;
	struct items *i;
	struct item *item;
	struct items *li = itemlist;


	while (li->name)
		{
		if (li->filename) if ((fp = fopen(li->filename,"rb")))
			{

			while (!feof(fp))
				{
				while (fgetc(fp) != '[' && !feof(fp))
					;
				if (feof(fp)) break;

				s = type;

				while ((*s++ = fgetc(fp)) != ']')
					;

				s[-1] = '\0';

				if (!(i = gettypedefbyname(type)))
					printf("Error: Unknown Record - \"%s\".\n",type);
				else
					{
					if (!(item = additem(i->type)))
						printf("Serious Error: Memory alloc failed, record type [%s] lost.\n",type);
					else
						{
						while (strcmpl((s = getword(fp)),"END") && !feof(fp))
							{
							if ((t = findrecordtype(i->itemdef,s)))
								{
								switch(t->datatype)
									{
									case T_STRING:
										setrecord(item,t,getstring(fp));
										break;
									case T_FLAGS:
										while (strcmpl((s = getword(fp)),"END"))
											setrecord(item,t,s);
										break;
									default:
										setrecord(item,t,getword(fp));
										break;
									}
								}
							else
								{
								printf("Unknown record [%s] in item type [%s]; skipping.\n",s,type);
								while (fgetc(fp) != '\n' && !feof(fp))
									;
								}
							}
						}
					}

				}
		

			fclose(fp);
			}
		li++;
		}

	}

/*----------------------------------------------------------*/
/* Save all data by going through the itemdef list          */
/*----------------------------------------------------------*/

savetype(char *name,struct itemdef *list, struct item *i,FILE *fp)
	{
	struct itemdef *t;
	struct flagdef *fd;

	while (i)
		{
		if (!(i->itemflags&I_INVALID))
			{
			fprintf(fp,"\r\n[%s]\r\n",name);

			t = list;
			while (t->name)
				{
				fprintf(fp,"%s ",t->name);

				switch(t->datatype)
					{
					case T_STRING:
						if (!geto_sptr(i,t->offset)) geto_sptr(i,t->offset) = strdup("");
						while (strchr(geto_sptr(i,t->offset),STOPCHAR))
							*strchr(geto_sptr(i,t->offset),STOPCHAR) = ' ';

						fprintf(fp,"%c%s%c",STOPCHAR,geto_sptr(i,t->offset),STOPCHAR);
						break;
					case T_FLAGS:
						if (fd = t->flagdefs)
							{
							while (fd->name)
								{
								if (geto_ulong(i,t->offset)&fd->mask)
									fprintf(fp,"%s ",fd->name);
								fd++;
								}
							}
						fprintf(fp,"END ");
						break;
					case T_INT:
						fprintf(fp,"%d",geto_int(i,t->offset));
						break;
					case T_UINT:
						fprintf(fp,"%u",geto_uint(i,t->offset));
						break;
					case T_LONG:
						fprintf(fp,"%ld",geto_long(i,t->offset));
						break;
					case T_ULONG:
						fprintf(fp,"%lu",geto_ulong(i,t->offset));
						break;
					case T_WORD:
						if (!geto_sptr(i,t->offset)) geto_sptr(i,t->offset) = strdup("");
						fprintf(fp,"%s",geto_sptr(i,t->offset));
						break;
					default:
						printf("Seriously Bad Error: Internal data tables corrupt.\n");
						break;
					}

				fprintf(fp,"\r\n");
				t++;
				}

			fprintf(fp,"END\r\n");
			}

		i = i->next;
		}



	}



saveall()
	{
	FILE *fp;
	struct items *i = itemlist;

/*	system("hostback");*/

	while (i->name)
		{
		if (!(i->flags&F_NOSAVE))
			{
			apiBeginC();
			if (fp = fopen(i->filename,"wb"))
				{
				savetype(i->name,i->itemdef,*i->header,fp);
				fclose(fp);
				}
			else printf("Rather Serious Error: Unable to save data file.\n");
			apiEndC();
			}
		i++;
		}


	}

