#include <stdio.h>
#include <ctype.h>
#include "room.h"
#include "stringops.h"
room_list *room_load (char *file)
{
room_list *rl = NULL;
room *tempr, *tempd;
FILE *f;
char input[256];
int src, dst;
#ifdef FUNCTIONS
puts ("**room_load");
#endif
rl = allocate (room_list);
rl->head = rl->tail = NULL;
rl->size = 0;
f = fopen (file, "r");
if (f == NULL)
return rl;
fgets (input, 255, f);
clipret (input);
while (!feof(f) && (strcmp (input, "---")))
{
room_add (rl, input);
fgets (input, 255, f);
clipret (input);
}
if (!feof(f))
{
fscanf (f, "%d %d ", &src, &dst);
fgets (input, 255, f);
clipret (input);
while (!feof(f))
{
tempr = room_find_num (rl, src);
tempd = room_find_num (rl, dst);
link_add (tempr->links, tempd, input);
fscanf (f, "%d %d ", &src, &dst);
fgets (input, 255, f);
clipret (input);
}
}
fclose (f);
return rl;
}
void room_save (room_list *rl, char *file)
{
FILE *f;
room *scan;
link *linkscan;
int num = 1;
f = fopen (file, "w");
if (f == NULL) return;
for (scan = rl->head; scan != NULL; scan = scan->next)
{
fputs (scan->name, f);
putc ('\n', f);
}
fputs ("---\n", f);
for (scan = rl->head; scan != NULL; scan = scan->next, num++)
{
for (linkscan = scan->links->head; linkscan != NULL;
linkscan = linkscan->next)
{
fprintf (f, "%d %d %s\n", num,
room_num (rl, linkscan->dest), linkscan->name);
}
}
fclose (f);
}
void room_add (room_list *rl, char *name)
{
room *new;
#ifdef FUNCTIONS
puts ("**room_add");
#endif
new = allocate (room);
copystring (new->name, name);
new->links = allocate (link_list);
new->links->head = new->links->tail = NULL;
new->links->size = 0;
new->next = NULL;
if (rl->tail != NULL)
rl->tail->next = new;
else
rl->head = new;
rl->tail = new;
(rl->size)++;
}
void room_delete (room_list *rl, room *dead)
{
room *scan;
link *link_scan;
#ifdef FUNCTIONS
puts ("**room_delete");
#endif
if ((rl == NULL) || (rl->head == NULL))
return;
for (scan = rl->head; scan != NULL; scan = scan->next)
{
if (scan != dead)
{
for (link_scan = scan->links->head; link_scan != NULL;
link_scan = link_scan->next)
{
if (link_scan->dest == dead)
link_delete (scan->links, link_scan);
}
}
}
if (rl->head == dead)
{
rl->head = dead->next;
if (rl->head == NULL)
{
rl->tail = NULL;
}
link_burn (dead->links);
free (dead->name);
free (dead);
(rl->size)--;
}
else
{
for (scan = rl->head;
(scan->next != NULL) && (scan->next != dead);
scan = scan->next);
if (scan->next != NULL)
{
if (scan->next == rl->tail) rl->tail = scan;
scan->next = scan->next->next;
link_burn (dead->links);
free (dead);
(rl->size)--;
}
}
}
room *room_find (room_list *rl, char *name)
{
room *scan;
#ifdef FUNCTIONS
puts ("**room_find");
#endif
if (isdigit (*name)) return (room_find_num (rl, atoi(name)));
for (scan = rl->head;
(scan != NULL) && (strcasecmp (name, scan->name));
scan = scan->next);
return scan;
}
room *room_find_num (room_list *rl, int n)
{
room *scan;
#ifdef FUNCTIONS
puts ("**room_find_num");
#endif
for (scan = rl->head;
(scan != NULL) && (n > 1);
scan = scan->next, n--);
return scan;
}
static void room_elements_burn (room *r)
{
#ifdef FUNCTIONS
puts ("<room_elements_burn>");
#endif
if (r != NULL)
{
room_elements_burn (r->next);
link_burn (r->links);
free (r->name);
free (r);
}
}
void room_burn (room_list *rl)
{
#ifdef FUNCTIONS
puts ("**room_burn");
#endif
if (rl != NULL)
{
room_elements_burn (rl->head);
free (rl);
}
}
void link_add (link_list *ll, room *dest, char *name)
{
link *new;
#ifdef FUNCTIONS
puts ("**link_add");
#endif
new = allocate (link);
copystring (new->name, name);
new->dest = dest;
new->next = NULL;
if (ll->tail != NULL) ll->tail->next = new;
else ll->head = new;
ll->tail = new;
(ll->size)++;
}
void link_delete (link_list *ll, link *dead)
{
#ifdef FUNCTIONS
puts ("**link_delete");
#endif
if ((ll == NULL) || (ll->head == NULL))
return;
if (ll->head == dead)
{
ll->head = dead->next;
free (dead->name);
free (dead);
(ll->size)--;
}
else
{
link *scan;
for (scan = ll->head;
(scan->next != NULL) && (scan->next != dead);
scan = scan->next);
if (scan->next != NULL)
{
if (scan->next == ll->tail) ll->tail = scan;
scan->next = scan->next->next;
free (dead->name);
free (dead);
(ll->size)--;
}
}
}
link *link_find (link_list *ll, char *name)
{
link *scan;
#ifdef FUNCTIONS
puts ("**link_find");
#endif
for (scan = ll->head;
(scan != NULL) && (strcasecmp (name, scan->name));
scan = scan->next);
return scan;
}
link *link_find_num (link_list *ll, int n)
{
link *scan;
#ifdef FUNCTIONS
puts ("**link_find");
#endif
for (scan = ll->head;
(scan != NULL) && (n > 1);
scan = scan->next, n--);
return scan;
}
static void link_elements_burn (link *l)
{
#ifdef FUNCTIONS
puts ("<link_elements_burn>");
#endif
if (l != NULL)
{
link_elements_burn (l->next);
free (l->name);
free (l);
}
}
void link_burn (link_list *ll)
{
#ifdef FUNCTIONS
puts ("**link_burn");
#endif
if (ll != NULL)
{
link_elements_burn (ll->head);
free (ll);
}
}
int room_num (room_list *rl, room *r)
{
room *scan;
int num = 1;
if ((rl == NULL) || (rl->head == NULL))
return 0;
for (scan = rl->head;
(scan != NULL) && (scan != r);
scan = scan->next, num++);
if (scan == NULL)
return 0;
return num;
}
int link_count (link_list *ll)
{
link *scan;
int n = 0;
for (scan = ll->head; scan != NULL; scan = scan->next, n++);
return n;
}